function.h (struct stack_usage): Remove dynamic_alloc_count field.

* 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
This commit is contained in:
Eric Botcazou 2011-06-02 10:48:11 +00:00 committed by Eric Botcazou
parent 66bd20e7b6
commit bc6d3f91a3
11 changed files with 144 additions and 197 deletions

View 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

View 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);
}

View 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 *);

View 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

View file

@ -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. */

View 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)
@ -6444,136 +6443,100 @@
"jmp\t%a0%#"
[(set_attr "type" "uncond_branch")])
(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 "" "")]
(define_expand "save_stack_nonlocal"
[(set (match_operand 0 "memory_operand" "")
(match_operand 1 "register_operand" ""))
(set (match_dup 2) (match_dup 3))]
""
{
rtx lab = operands[1];
rtx stack = operands[2];
rtx fp = operands[3];
rtx labreg;
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 */
})
/* Trap instruction to flush all the register windows. */
(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 0 "general_operand" "")
(match_operand 1 "general_operand" "")
(match_operand 2 "memory_operand" "")
(match_operand 3 "memory_operand" "")]
""
{
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));
/* 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);
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
/* 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);
/* 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)]
;; Special insn to flush register windows.
(define_insn "flush_register_windows"
[(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
""
{
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.
(define_expand "setjmp"
[(const_int 0)]
""
{
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.

View file

@ -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. */

View 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.

View 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;
}

View 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 \

View 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)