function.h (struct stack_usage): Remove dynamic_alloc_count field.
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 2 Jun 2011 10:48:11 +0000 (10:48 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 2 Jun 2011 10:48:11 +0000 (10:48 +0000)
* function.h (struct stack_usage): Remove dynamic_alloc_count field.
(current_function_dynamic_alloc_count): Delete.
* builtins.c (expand_builtin_setjmp_setup): Do not set calls_setjmp.
(expand_builtin_nonlocal_goto): Remove obsolete comment.
(expand_builtin_update_setjmp_buf): Remove dead code.
* cse.c (cse_find_path): Do not follow a single abnormal incoming edge.
* explow.c (allocate_dynamic_stack_space): Remove SETJMP_VIA_SAVE_AREA
support.
* function.c (instantiate_virtual_regs): Likewise.
* postreload-gcse.c (bb_has_well_behaved_predecessors): Return false
for a block with a single abnormal incoming edge.
* config/sparc/sparc.h (STACK_SAVEAREA_MODE): Define.
* config/sparc/sparc-protos.h (load_got_register): Declare.
* config/sparc/sparc.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Define.
(load_got_register): Make global.
(sparc_frame_pointer_required): Add 'static'.
(sparc_can_eliminate): Likewise.  Call sparc_frame_pointer_required.
(sparc_builtin_setjmp_frame_value): New function.
* config/sparc/sparc.md (UNSPECV_SETJMP): Remove.
(save_stack_nonlocal): New expander.
(restore_stack_nonlocal): Likewise.
(nonlocal_goto): Remove modes, adjust predicates and reimplement.
(nonlocal_goto_internal): New insn.
(goto_handler_and_restore): Delete.
(builtin_setjmp_setup): Likewise.
(do_builtin_setjmp_setup): Likewise.
(setjmp): Likewise.
(builtin_setjmp_receiver): New expander.

From-SVN: r174564

gcc/ChangeLog
gcc/builtins.c
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md
gcc/cse.c
gcc/explow.c
gcc/function.c
gcc/function.h
gcc/postreload-gcse.c

index 8f706afd724dc846c35714130d30af4261a39e33..cddb5243b51bcd65c4567c198fb3b35713c77cbf 100644 (file)
@@ -1,3 +1,34 @@
+2011-06-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * function.h (struct stack_usage): Remove dynamic_alloc_count field.
+       (current_function_dynamic_alloc_count): Delete.
+       * builtins.c (expand_builtin_setjmp_setup): Do not set calls_setjmp.
+       (expand_builtin_nonlocal_goto): Remove obsolete comment.
+       (expand_builtin_update_setjmp_buf): Remove dead code.
+       * cse.c (cse_find_path): Do not follow a single abnormal incoming edge.
+       * explow.c (allocate_dynamic_stack_space): Remove SETJMP_VIA_SAVE_AREA
+       support.
+       * function.c (instantiate_virtual_regs): Likewise.
+       * postreload-gcse.c (bb_has_well_behaved_predecessors): Return false
+       for a block with a single abnormal incoming edge.
+       * config/sparc/sparc.h (STACK_SAVEAREA_MODE): Define.
+       * config/sparc/sparc-protos.h (load_got_register): Declare.
+       * config/sparc/sparc.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Define.
+       (load_got_register): Make global.
+       (sparc_frame_pointer_required): Add 'static'.
+       (sparc_can_eliminate): Likewise.  Call sparc_frame_pointer_required.
+       (sparc_builtin_setjmp_frame_value): New function.
+       * config/sparc/sparc.md (UNSPECV_SETJMP): Remove.
+       (save_stack_nonlocal): New expander.
+       (restore_stack_nonlocal): Likewise.
+       (nonlocal_goto): Remove modes, adjust predicates and reimplement.
+       (nonlocal_goto_internal): New insn.
+       (goto_handler_and_restore): Delete.
+       (builtin_setjmp_setup): Likewise.
+       (do_builtin_setjmp_setup): Likewise.
+       (setjmp): Likewise.
+       (builtin_setjmp_receiver): New expander.
+
 2011-06-01  David Li  <davidxl@google.com>
 
        PR middle-end/49261
index a23237dd94ad30b4516437c65e4deef28483e1bf..d37558c15260c166db559588fb06b2ef70cf0d9b 100644 (file)
@@ -806,10 +806,6 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
     emit_insn (gen_builtin_setjmp_setup (buf_addr));
 #endif
 
-  /* Tell optimize_save_area_alloca that extra work is going to
-     need to go on during alloca.  */
-  cfun->calls_setjmp = 1;
-
   /* We have a nonlocal label.   */
   cfun->has_nonlocal_label = 1;
 }
@@ -992,8 +988,8 @@ expand_builtin_nonlocal_goto (tree exp)
   r_label = convert_memory_address (Pmode, r_label);
   r_save_area = expand_normal (t_save_area);
   r_save_area = convert_memory_address (Pmode, r_save_area);
-  /* Copy the address of the save location to a register just in case it was based
-    on the frame pointer.   */
+  /* Copy the address of the save location to a register just in case it was
+     based on the frame pointer.   */
   r_save_area = copy_to_reg (r_save_area);
   r_fp = gen_rtx_MEM (Pmode, r_save_area);
   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
@@ -1013,11 +1009,7 @@ expand_builtin_nonlocal_goto (tree exp)
       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
 
-      /* Restore frame pointer for containing function.
-        This sets the actual hard register used for the frame pointer
-        to the location of the function's incoming static chain info.
-        The non-local goto handler will then adjust it to contain the
-        proper value and reload the argument pointer, if needed.  */
+      /* Restore frame pointer for containing function.  */
       emit_move_insn (hard_frame_pointer_rtx, r_fp);
       emit_stack_restore (SAVE_NONLOCAL, r_sp);
 
@@ -1066,29 +1058,13 @@ expand_builtin_nonlocal_goto (tree exp)
 static void
 expand_builtin_update_setjmp_buf (rtx buf_addr)
 {
-  enum machine_mode sa_mode = Pmode;
-  rtx stack_save;
-
-
-#ifdef HAVE_save_stack_nonlocal
-  if (HAVE_save_stack_nonlocal)
-    sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
-#endif
-#ifdef STACK_SAVEAREA_MODE
-  sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
-#endif
-
-  stack_save
+  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
+  rtx stack_save
     = gen_rtx_MEM (sa_mode,
                   memory_address
                   (sa_mode,
                    plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
 
-#ifdef HAVE_setjmp
-  if (HAVE_setjmp)
-    emit_insn (gen_setjmp ());
-#endif
-
   emit_stack_save (SAVE_NONLOCAL, &stack_save);
 }
 
index c1bbab7e5b6623bc537ded41f6e8c96b0b9c0c4f..ccf16573cb496fbcda8b47570199d89b06e8b97e 100644 (file)
@@ -60,6 +60,7 @@ extern bool constant_address_p (rtx);
 extern bool legitimate_pic_operand_p (rtx);
 extern rtx sparc_legitimize_reload_address (rtx, enum machine_mode, int, int,
                                            int, int *win);
+extern void load_got_register (void);
 extern void sparc_emit_call_insn (rtx, rtx);
 extern void sparc_defer_case_vector (rtx, rtx, int);
 extern bool sparc_expand_move (enum machine_mode, rtx *);
index d65ced03d2d177eb5cbdabe9677d760b1362b1d7..d5d043def0f3127fdf5808710118f6eef5587ed3 100644 (file)
@@ -387,7 +387,6 @@ static rtx sparc_builtin_saveregs (void);
 static int epilogue_renumber (rtx *, int);
 static bool sparc_assemble_integer (rtx, unsigned int, int);
 static int set_extends (rtx);
-static void load_got_register (void);
 static int save_or_restore_regs (int, int, rtx, int, int);
 static void emit_save_or_restore_regs (int);
 static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT);
@@ -464,6 +463,7 @@ static void sparc_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
 static void sparc_file_end (void);
 static bool sparc_frame_pointer_required (void);
 static bool sparc_can_eliminate (const int, const int);
+static rtx sparc_builtin_setjmp_frame_value (void);
 static void sparc_conditional_register_usage (void);
 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
 static const char *sparc_mangle_type (const_tree);
@@ -650,8 +650,12 @@ static const struct default_options sparc_option_optimization_table[] =
 #undef TARGET_FRAME_POINTER_REQUIRED
 #define TARGET_FRAME_POINTER_REQUIRED sparc_frame_pointer_required
 
+#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
+#define TARGET_BUILTIN_SETJMP_FRAME_VALUE sparc_builtin_setjmp_frame_value
+
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE sparc_can_eliminate
+
 #undef  TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS sparc_preferred_reload_class
 
@@ -3770,7 +3774,7 @@ gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2, rtx op3)
 
 /* Emit code to load the GOT register.  */
 
-static void
+void
 load_got_register (void)
 {
   /* In PIC mode, this will retrieve pic_offset_table_rtx.  */
@@ -9801,7 +9805,7 @@ sparc_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
 
 /* Implement TARGET_FRAME_POINTER_REQUIRED.  */
 
-bool
+static bool
 sparc_frame_pointer_required (void)
 {
   return !(current_function_is_leaf && only_leaf_regs_used ());
@@ -9812,11 +9816,18 @@ sparc_frame_pointer_required (void)
    in that case.  But the test in update_eliminables doesn't know we are
    assuming below that we only do the former elimination.  */
 
-bool
+static bool
 sparc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
 {
-  return (to == HARD_FRAME_POINTER_REGNUM
-          || !targetm.frame_pointer_required ());
+  return to == HARD_FRAME_POINTER_REGNUM || !sparc_frame_pointer_required ();
+}
+
+/* Return the hard frame pointer directly to bypass the stack bias.  */
+
+static rtx
+sparc_builtin_setjmp_frame_value (void)
+{
+  return hard_frame_pointer_rtx;
 }
 
 /* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that
index ad354e89ecaa2296297a9901ef344e36040dd5e5..67189ecfe8d4104ba9405c05b60a56c20041e114 100644 (file)
@@ -1384,11 +1384,19 @@ do {                                                                    \
 #define EPILOGUE_USES(REGNO) ((REGNO) == 31 \
   || (crtl->calls_eh_return && (REGNO) == 1))
 \f
+/* We need 2 words, so we can save the stack pointer and the return register
+   of the function containing a non-local goto target.  */
+
+#define STACK_SAVEAREA_MODE(LEVEL) \
+  ((LEVEL) == SAVE_NONLOCAL ? (TARGET_ARCH64 ? TImode : DImode) : Pmode)
+
 /* Length in units of the trampoline for entering a nested function.  */
 
 #define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16)
 
-#define TRAMPOLINE_ALIGNMENT 128 /* 16 bytes */
+/* Alignment required for trampolines, in bits.  */
+
+#define TRAMPOLINE_ALIGNMENT 128
 \f
 /* Generate RTL to flush the register windows so as to make arbitrary frames
    available.  */
index 5e16179a62b288150ec14a69bcfc9889540aa95e..e6342eca5e91826e4ae92e0e2bcb789ddf939457 100644 (file)
@@ -1,7 +1,7 @@
 ;; Machine description for SPARC chip for GCC
 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;;  Free Software Foundation, Inc.
+;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+;;  2011 Free Software Foundation, Inc.
 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
 ;;  at Cygnus Support.
@@ -70,7 +70,6 @@
    (UNSPECV_FLUSHW             1)
    (UNSPECV_GOTO               2)
    (UNSPECV_FLUSH              4)
-   (UNSPECV_SETJMP             5)
    (UNSPECV_SAVEW              6)
    (UNSPECV_CAS                        8)
    (UNSPECV_SWAP               9)
   "jmp\t%a0%#"
   [(set_attr "type" "uncond_branch")])
 
+(define_expand "save_stack_nonlocal"
+  [(set (match_operand 0 "memory_operand" "")
+       (match_operand 1 "register_operand" ""))
+   (set (match_dup 2) (match_dup 3))]
+  ""
+{
+  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
+  operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
+  operands[3] = gen_rtx_REG (Pmode, 31); /* %i7 */
+})
+
+(define_expand "restore_stack_nonlocal"
+  [(set (match_operand 0 "register_operand" "")
+       (match_operand 1 "memory_operand" ""))]
+  ""
+{
+  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
+})
+
 (define_expand "nonlocal_goto"
-  [(match_operand:SI 0 "general_operand" "")
-   (match_operand:SI 1 "general_operand" "")
-   (match_operand:SI 2 "general_operand" "")
-   (match_operand:SI 3 "" "")]
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")
+   (match_operand 2 "memory_operand" "")
+   (match_operand 3 "memory_operand" "")]
   ""
 {
-  rtx lab = operands[1];
-  rtx stack = operands[2];
-  rtx fp = operands[3];
-  rtx labreg;
+  rtx r_label = copy_to_reg (operands[1]);
+  rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
+  rtx r_fp = operands[3];
+  rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
 
-  /* Trap instruction to flush all the register windows.  */
+  /* We need to flush all the register windows so that their contents will
+     be re-synchronized by the restore insn of the target function.  */
   emit_insn (gen_flush_register_windows ());
 
-  /* Load the fp value for the containing fn into %fp.  This is needed
-     because STACK refers to %fp.  Note that virtual register instantiation
-     fails if the virtual %fp isn't set from a register.  */
-  if (GET_CODE (fp) != REG)
-    fp = force_reg (Pmode, fp);
-  emit_move_insn (virtual_stack_vars_rtx, fp);
-
-  /* Find the containing function's current nonlocal goto handler,
-     which will do any cleanups and then jump to the label.  */
-  labreg = gen_rtx_REG (Pmode, 8);
-  emit_move_insn (labreg, lab);
+  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
+  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
 
-  /* Restore %fp from stack pointer value for containing function.
-     The restore insn that follows will move this to %sp,
-     and reload the appropriate value into %fp.  */
-  emit_move_insn (hard_frame_pointer_rtx, stack);
+  /* Restore frame pointer for containing function.  */
+  emit_move_insn (hard_frame_pointer_rtx, r_fp);
+  emit_stack_restore (SAVE_NONLOCAL, r_sp);
 
+  /* USE of hard_frame_pointer_rtx added for consistency;
+     not clear if really needed.  */
+  emit_use (hard_frame_pointer_rtx);
   emit_use (stack_pointer_rtx);
 
-  /* ??? The V9-specific version was disabled in rev 1.65.  */
-  emit_jump_insn (gen_goto_handler_and_restore (labreg));
+  /* We need to smuggle the load of %i7 as it is a fixed register.  */
+  emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
   emit_barrier ();
   DONE;
 })
 
-;; Special trap insn to flush register windows.
-(define_insn "flush_register_windows"
-  [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
-  ""
-  { return TARGET_V9 ? "flushw" : "ta\t3"; }
-  [(set_attr "type" "flushw")])
-
-(define_insn "goto_handler_and_restore"
-  [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
-  "GET_MODE (operands[0]) == Pmode"
+(define_insn "nonlocal_goto_internal"
+  [(unspec_volatile [(match_operand 0 "register_operand" "r")
+                     (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
+  "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
 {
   if (flag_delayed_branch)
-    return "jmp\t%0\n\t restore";
+    {
+      if (TARGET_ARCH64)
+       return "jmp\t%0\n\t ldx\t%1, %%i7";
+      else
+       return "jmp\t%0\n\t ld\t%1, %%i7";
+    }
   else
-    return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
+    {
+      if (TARGET_ARCH64)
+       return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
+      else
+       return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
+    }
 }
   [(set (attr "type") (const_string "multi"))
    (set (attr "length")
        (if_then_else (eq_attr "delayed_branch" "true")
                      (const_int 2)
-                     (const_int 4)))])
+                     (const_int 3)))])
 
-;; For __builtin_setjmp we need to flush register windows iff the function
-;; calls alloca as well, because otherwise the current register window might
-;; be saved after the %sp adjustment and thus setjmp would crash.
-(define_expand "builtin_setjmp_setup"
-  [(match_operand 0 "register_operand" "r")]
-  ""
+(define_expand "builtin_setjmp_receiver"
+  [(label_ref (match_operand 0 "" ""))]
+  "flag_pic"
 {
-  emit_insn (gen_do_builtin_setjmp_setup ());
+  load_got_register ();
   DONE;
 })
 
-(define_insn "do_builtin_setjmp_setup"
-  [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
-  ""
-{
-  if (!cfun->calls_alloca)
-    return "";
-  if (!TARGET_V9)
-    return "ta\t3";
-  fputs ("\tflushw\n", asm_out_file);
-  if (flag_pic)
-    fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
-            TARGET_ARCH64 ? 'x' : 'w',
-            SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
-  fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
-          TARGET_ARCH64 ? 'x' : 'w',
-          SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
-  fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
-          TARGET_ARCH64 ? 'x' : 'w',
-          SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
-  return "";
-}
-  [(set_attr "type" "multi")
-   (set (attr "length")
-        (cond [(eq_attr "calls_alloca" "false")
-                 (const_int 0)
-               (eq_attr "isa" "!v9")
-                 (const_int 1)
-               (eq_attr "pic" "true")
-                 (const_int 4)] (const_int 3)))])
-
-;; Pattern for use after a setjmp to store registers into the save area.
+;; Special insn to flush register windows.
 
-(define_expand "setjmp"
-  [(const_int 0)]
+(define_insn "flush_register_windows"
+  [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
   ""
-{
-  rtx mem;
-
-  if (flag_pic)
-    {
-      mem = gen_rtx_MEM (Pmode,
-                        plus_constant (stack_pointer_rtx,
-                                       SPARC_STACK_BIAS + 7 * UNITS_PER_WORD));
-      emit_insn (gen_rtx_SET (VOIDmode, mem, pic_offset_table_rtx));
-    }
-
-  mem = gen_rtx_MEM (Pmode,
-                    plus_constant (stack_pointer_rtx,
-                                   SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
-  emit_insn (gen_rtx_SET (VOIDmode, mem, hard_frame_pointer_rtx));
-
-  mem = gen_rtx_MEM (Pmode,
-                    plus_constant (stack_pointer_rtx,
-                                   SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
-  emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
-  DONE;
-})
+  { return TARGET_V9 ? "flushw" : "ta\t3"; }
+  [(set_attr "type" "flushw")])
 
 ;; Special pattern for the FLUSH instruction.
 
index d83b38a60b80d097e8c22ecbaa3b91c6f7cb64a1..5e2b4d83dc5f8c53ab7e75d6a72a173d757c1b22 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1,7 +1,7 @@
 /* Common subexpression elimination for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -6192,7 +6192,9 @@ cse_find_path (basic_block first_bb, struct cse_basic_block_data *data,
          else
            e = NULL;
 
-         if (e && e->dest != EXIT_BLOCK_PTR
+         if (e
+             && (e->flags & EDGE_ABNORMAL) == 0
+             && e->dest != EXIT_BLOCK_PTR
              && single_pred_p (e->dest)
              /* Avoid visiting basic blocks twice.  The large comment
                 above explains why this can happen.  */
index fe507877c900c694cd116645b0cc7f3e9bd2d2a1..7387dad98df234ec27a13c4ffcfd019dbfd654cc 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines for manipulating rtx's in semantically interesting ways.
-   Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1249,38 +1249,6 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
        size_align = extra_align;
     }
 
-#ifdef SETJMP_VIA_SAVE_AREA
-  /* If setjmp restores regs from a save area in the stack frame,
-     avoid clobbering the reg save area.  Note that the offset of
-     virtual_incoming_args_rtx includes the preallocated stack args space.
-     It would be no problem to clobber that, but it's on the wrong side
-     of the old save area.
-
-     What used to happen is that, since we did not know for sure
-     whether setjmp() was invoked until after RTL generation, we
-     would use reg notes to store the "optimized" size and fix things
-     up later.  These days we know this information before we ever
-     start building RTL so the reg notes are unnecessary.  */
-  if (cfun->calls_setjmp)
-    {
-      rtx dynamic_offset
-       = expand_binop (Pmode, sub_optab, virtual_stack_dynamic_rtx,
-                       stack_pointer_rtx, NULL_RTX, 1, OPTAB_LIB_WIDEN);
-
-      size = expand_binop (Pmode, add_optab, size, dynamic_offset,
-                          NULL_RTX, 1, OPTAB_LIB_WIDEN);
-
-      /* The above dynamic offset cannot be computed statically at this
-        point, but it will be possible to do so after RTL expansion is
-        done.  Record how many times we will need to add it.  */
-      if (flag_stack_usage_info)
-       current_function_dynamic_alloc_count++;
-
-      /* ??? Can we infer a minimum of STACK_BOUNDARY here?  */
-      size_align = BITS_PER_UNIT;
-    }
-#endif /* SETJMP_VIA_SAVE_AREA */
-
   /* Round the size to a multiple of the required stack alignment.
      Since the stack if presumed to be rounded before this allocation,
      this will maintain the required alignment.
index c0350be5b177dc1db9dc693b1901da1a6f7cc8ff..30cc9ff2b4f9bb137743fb27d4644657f1dfa428 100644 (file)
@@ -1937,17 +1937,6 @@ instantiate_virtual_regs (void)
      frame_pointer_rtx.  */
   virtuals_instantiated = 1;
 
-  /* See allocate_dynamic_stack_space for the rationale.  */
-#ifdef SETJMP_VIA_SAVE_AREA
-  if (flag_stack_usage_info && cfun->calls_setjmp)
-    {
-      int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
-      dynamic_offset = (dynamic_offset + align - 1) / align * align;
-      current_function_dynamic_stack_size
-       += current_function_dynamic_alloc_count * dynamic_offset;
-    }
-#endif
-
   return 0;
 }
 
index 0e8bc74aaa59d6d8ec5df24cd6a1a3b41e638aae..3b572cc16a78fc6d5b1d79029382dffd7bfa50c8 100644 (file)
@@ -1,6 +1,6 @@
 /* Structure for saving state for a nested function.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -476,9 +476,6 @@ struct GTY(()) stack_usage
      !ACCUMULATE_OUTGOING_ARGS, it contains the outgoing arguments.  */
   int pushed_stack_size;
 
-  /* # of dynamic allocations in the function.  */
-  unsigned int dynamic_alloc_count : 31;
-
   /* Nonzero if the amount of stack space allocated dynamically cannot
      be bounded at compile-time.  */
   unsigned int has_unbounded_dynamic_stack_size : 1;
@@ -487,7 +484,6 @@ struct GTY(()) stack_usage
 #define current_function_static_stack_size (cfun->su->static_stack_size)
 #define current_function_dynamic_stack_size (cfun->su->dynamic_stack_size)
 #define current_function_pushed_stack_size (cfun->su->pushed_stack_size)
-#define current_function_dynamic_alloc_count (cfun->su->dynamic_alloc_count)
 #define current_function_has_unbounded_dynamic_stack_size \
   (cfun->su->has_unbounded_dynamic_stack_size)
 #define current_function_allocates_dynamic_stack_space    \
index 8e26419f39c94a386b8a1083e8d5636623a2122e..0ee50d8122986b61d10560882c3e10b18a661aa9 100644 (file)
@@ -1,5 +1,5 @@
 /* Post reload partially redundant load elimination
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -912,10 +912,12 @@ get_avail_load_store_reg (rtx insn)
 static bool
 bb_has_well_behaved_predecessors (basic_block bb)
 {
+  unsigned int edge_count = EDGE_COUNT (bb->preds);
   edge pred;
   edge_iterator ei;
 
-  if (EDGE_COUNT (bb->preds) == 0)
+  if (edge_count == 0
+      || (edge_count == 1 && (single_pred_edge (bb)->flags & EDGE_ABNORMAL)))
     return false;
 
   FOR_EACH_EDGE (pred, ei, bb->preds)