summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2011-06-02 10:48:11 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2011-06-02 10:48:11 +0000
commitd1ff492eeef4a497050ca49beff7fa18c867a344 (patch)
tree5f109a1d3dfcb88bc0c15d333cf680895b7292b4
parent7d2c0823a665fbad341841785a0219e4f0ddfbf7 (diff)
downloadgcc-d1ff492eeef4a497050ca49beff7fa18c867a344.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@174564 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog31
-rw-r--r--gcc/builtins.c34
-rw-r--r--gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc/config/sparc/sparc.c23
-rw-r--r--gcc/config/sparc/sparc.h10
-rw-r--r--gcc/config/sparc/sparc.md171
-rw-r--r--gcc/cse.c8
-rw-r--r--gcc/explow.c36
-rw-r--r--gcc/function.c11
-rw-r--r--gcc/function.h6
-rw-r--r--gcc/postreload-gcse.c6
11 files changed, 142 insertions, 195 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8f706afd724..cddb5243b51 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index a23237dd94a..d37558c1526 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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);
}
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index c1bbab7e5b6..ccf16573cb4 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -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 *);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index d65ced03d2d..d5d043def0f 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -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
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index ad354e89eca..67189ecfe8d 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1384,11 +1384,19 @@ do { \
#define EPILOGUE_USES(REGNO) ((REGNO) == 31 \
|| (crtl->calls_eh_return && (REGNO) == 1))
+/* 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
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 5e16179a62b..e6342eca5e9 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -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)
@@ -6444,136 +6443,100 @@
"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.
diff --git a/gcc/cse.c b/gcc/cse.c
index d83b38a60b8..5e2b4d83dc5 100644
--- 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. */
diff --git a/gcc/explow.c b/gcc/explow.c
index fe507877c90..7387dad98df 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -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.
diff --git a/gcc/function.c b/gcc/function.c
index c0350be5b17..30cc9ff2b4f 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
}
diff --git a/gcc/function.h b/gcc/function.h
index 0e8bc74aaa5..3b572cc16a7 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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 \
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index 8e26419f39c..0ee50d81229 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -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)