]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
stmt.c (expand_nl_goto_receiver): Remove almost-copy of expand_builtin_setjmp_receiver.
authorHans-Peter Nilsson <hp@bitrange.com>
Mon, 22 Oct 2012 09:22:11 +0000 (09:22 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Mon, 22 Oct 2012 09:22:11 +0000 (09:22 +0000)
* stmt.c (expand_nl_goto_receiver): Remove almost-copy of
expand_builtin_setjmp_receiver.
(expand_label): Adjust, call expand_builtin_setjmp_receiver
with NULL for the label parameter.
* builtins.c (expand_builtin_setjmp_receiver): Don't clobber
the frame-pointer.  Adjust comments.
[HAVE_builtin_setjmp_receiver]: Emit builtin_setjmp_receiver
only if LABEL is non-NULL.

From-SVN: r192676

gcc/ChangeLog
gcc/builtins.c
gcc/stmt.c

index f7e2572ee1b39869c8431b6bffdfba9657938f54..128837f8e4c0bfe68158c8694f4217fb5126f60b 100644 (file)
@@ -1,3 +1,14 @@
+2012-10-22  Hans-Peter Nilsson  <hp@bitrange.com>
+
+       * stmt.c (expand_nl_goto_receiver): Remove almost-copy of
+       expand_builtin_setjmp_receiver.
+       (expand_label): Adjust, call expand_builtin_setjmp_receiver
+       with NULL for the label parameter.
+       * builtins.c (expand_builtin_setjmp_receiver): Don't clobber
+       the frame-pointer.  Adjust comments.
+       [HAVE_builtin_setjmp_receiver]: Emit builtin_setjmp_receiver
+       only if LABEL is non-NULL.
+
 2012-10-21  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386-protos.h (memory_address_length): Add new bool
index c309566919ecf19e160d239ca69a84198c17820b..6d501c47ad89df870bd4f71b16d1e4aa267515ae 100644 (file)
@@ -885,14 +885,15 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
 }
 
 /* Construct the trailing part of a __builtin_setjmp call.  This is
-   also called directly by the SJLJ exception handling code.  */
+   also called directly by the SJLJ exception handling code.
+   If RECEIVER_LABEL is NULL, instead contruct a nonlocal goto handler.  */
 
 void
 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
 {
   rtx chain;
 
-  /* Clobber the FP when we get here, so we have to make sure it's
+  /* Mark the FP as used when we get here, so we have to make sure it's
      marked as used by this function.  */
   emit_use (hard_frame_pointer_rtx);
 
@@ -907,17 +908,28 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
 #ifdef HAVE_nonlocal_goto
   if (! HAVE_nonlocal_goto)
 #endif
-    {
-      emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
-      /* This might change the hard frame pointer in ways that aren't
-        apparent to early optimization passes, so force a clobber.  */
-      emit_clobber (hard_frame_pointer_rtx);
-    }
+    /* First adjust our frame pointer to its actual value.  It was
+       previously set to the start of the virtual area corresponding to
+       the stacked variables when we branched here and now needs to be
+       adjusted to the actual hardware fp value.
+
+       Assignments to virtual registers are converted by
+       instantiate_virtual_regs into the corresponding assignment
+       to the underlying register (fp in this case) that makes
+       the original assignment true.
+       So the following insn will actually be decrementing fp by
+       STARTING_FRAME_OFFSET.  */
+    emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
 
 #if !HARD_FRAME_POINTER_IS_ARG_POINTER
   if (fixed_regs[ARG_POINTER_REGNUM])
     {
 #ifdef ELIMINABLE_REGS
+      /* If the argument pointer can be eliminated in favor of the
+        frame pointer, we don't need to restore it.  We assume here
+        that if such an elimination is present, it can always be used.
+        This is the case on all known machines; if we don't make this
+        assumption, we do unnecessary saving on many machines.  */
       size_t i;
       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
 
@@ -938,7 +950,7 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
 #endif
 
 #ifdef HAVE_builtin_setjmp_receiver
-  if (HAVE_builtin_setjmp_receiver)
+  if (receiver_label != NULL && HAVE_builtin_setjmp_receiver)
     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
   else
 #endif
index 14a28abcc58a2246881d373803b18245d47596a8..07e7cc74159541fbdaff55b5eab208491cec7cc8 100644 (file)
@@ -106,7 +106,6 @@ extern basic_block label_to_block_fn (struct function *, tree);
 \f
 static int n_occurrences (int, const char *);
 static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *);
-static void expand_nl_goto_receiver (void);
 static bool check_operand_nalternatives (tree, tree);
 static bool check_unique_operand_names (tree, tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree, tree);
@@ -200,7 +199,7 @@ expand_label (tree label)
 
   if (DECL_NONLOCAL (label))
     {
-      expand_nl_goto_receiver ();
+      expand_builtin_setjmp_receiver (NULL);
       nonlocal_goto_handler_labels
        = gen_rtx_EXPR_LIST (VOIDmode, label_r,
                             nonlocal_goto_handler_labels);
@@ -1556,77 +1555,6 @@ expand_return (tree retval)
     }
 }
 \f
-/* Emit code to restore vital registers at the beginning of a nonlocal goto
-   handler.  */
-static void
-expand_nl_goto_receiver (void)
-{
-  rtx chain;
-
-  /* Clobber the FP when we get here, so we have to make sure it's
-     marked as used by this function.  */
-  emit_use (hard_frame_pointer_rtx);
-
-  /* Mark the static chain as clobbered here so life information
-     doesn't get messed up for it.  */
-  chain = targetm.calls.static_chain (current_function_decl, true);
-  if (chain && REG_P (chain))
-    emit_clobber (chain);
-
-#ifdef HAVE_nonlocal_goto
-  if (! HAVE_nonlocal_goto)
-#endif
-    /* First adjust our frame pointer to its actual value.  It was
-       previously set to the start of the virtual area corresponding to
-       the stacked variables when we branched here and now needs to be
-       adjusted to the actual hardware fp value.
-
-       Assignments are to virtual registers are converted by
-       instantiate_virtual_regs into the corresponding assignment
-       to the underlying register (fp in this case) that makes
-       the original assignment true.
-       So the following insn will actually be
-       decrementing fp by STARTING_FRAME_OFFSET.  */
-    emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
-
-#if !HARD_FRAME_POINTER_IS_ARG_POINTER
-  if (fixed_regs[ARG_POINTER_REGNUM])
-    {
-#ifdef ELIMINABLE_REGS
-      /* If the argument pointer can be eliminated in favor of the
-        frame pointer, we don't need to restore it.  We assume here
-        that if such an elimination is present, it can always be used.
-        This is the case on all known machines; if we don't make this
-        assumption, we do unnecessary saving on many machines.  */
-      static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
-      size_t i;
-
-      for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
-       if (elim_regs[i].from == ARG_POINTER_REGNUM
-           && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
-         break;
-
-      if (i == ARRAY_SIZE (elim_regs))
-#endif
-       {
-         /* Now restore our arg pointer from the address at which it
-            was saved in our stack frame.  */
-         emit_move_insn (crtl->args.internal_arg_pointer,
-                         copy_to_reg (get_arg_pointer_save_area ()));
-       }
-    }
-#endif
-
-#ifdef HAVE_nonlocal_goto_receiver
-  if (HAVE_nonlocal_goto_receiver)
-    emit_insn (gen_nonlocal_goto_receiver ());
-#endif
-
-  /* We must not allow the code we just generated to be reordered by
-     scheduling.  Specifically, the update of the frame pointer must
-     happen immediately, not later.  */
-  emit_insn (gen_blockage ());
-}
 \f
 /* Emit code to save the current value of stack.  */
 rtx