From: ebotcazou Date: Tue, 10 Nov 2009 20:45:25 +0000 (+0000) Subject: PR target/10127 X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=d1b9226497e79115b89c6dc54ea8d5bb6cb077c8;p=pf3gnuchains%2Fgcc-fork.git PR target/10127 PR ada/20548 * expr.h (anti_adjust_stack_and_probe): Declare. * explow.c (anti_adjust_stack_and_probe): Make global, add ADJUST_BACK parameter and rewrite head comment. (allocate_dynamic_stack_space): Adjust call to above function. * function.c (expand_function_end): Handle STACK_CHECK_MOVING_SP. * tree.h (dwarf2out_args_size): Delete. * dwarf2out.c (dwarf2out_args_size): Make static and move around. (dwarf2out_args_size_adjust): Delete prototype and move around. (dwarf2out_frame_debug_expr): Do not record arg size adjustments for ACCUMULATE_OUTGOING_ARGS targets. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154079 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8902ee98d5..e22b3f90206 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ 2009-11-10 Eric Botcazou + PR target/10127 + PR ada/20548 + * expr.h (anti_adjust_stack_and_probe): Declare. + * explow.c (anti_adjust_stack_and_probe): Make global, add ADJUST_BACK + parameter and rewrite head comment. + (allocate_dynamic_stack_space): Adjust call to above function. + * function.c (expand_function_end): Handle STACK_CHECK_MOVING_SP. + + * tree.h (dwarf2out_args_size): Delete. + * dwarf2out.c (dwarf2out_args_size): Make static and move around. + (dwarf2out_args_size_adjust): Delete prototype and move around. + (dwarf2out_frame_debug_expr): Do not record arg size adjustments for + ACCUMULATE_OUTGOING_ARGS targets. + +2009-11-10 Eric Botcazou + * config/sparc/sparc.c (print_operand) <')'>: Test for a non-null DECL_SIZE of DECL_RESULT before evaluating it. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index e5648090f9c..e3a641206d8 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -470,8 +470,6 @@ static void output_cfi (dw_cfi_ref, dw_fde_ref, int); static void output_cfi_directive (dw_cfi_ref); static void output_call_frame_info (int); static void dwarf2out_note_section_used (void); -static void dwarf2out_stack_adjust (rtx, bool); -static void dwarf2out_args_size_adjust (HOST_WIDE_INT, const char *); static void flush_queued_reg_saves (void); static bool clobbers_queued_reg_save (const_rtx); static void dwarf2out_frame_debug_expr (rtx, const char *); @@ -1157,25 +1155,6 @@ dwarf2out_window_save (const char *label) add_fde_cfi (label, cfi); } -/* Add a CFI to update the running total of the size of arguments - pushed onto the stack. */ - -void -dwarf2out_args_size (const char *label, HOST_WIDE_INT size) -{ - dw_cfi_ref cfi; - - if (size == old_args_size) - return; - - old_args_size = size; - - cfi = new_cfi (); - cfi->dw_cfi_opc = DW_CFA_GNU_args_size; - cfi->dw_cfi_oprnd1.dw_cfi_offset = size; - add_fde_cfi (label, cfi); -} - /* Entry point for saving a register to the stack. REG is the GCC register number. LABEL and OFFSET are passed to reg_save. */ @@ -1526,6 +1505,48 @@ compute_barrier_args_size (void) VEC_free (rtx, heap, next); } +/* Add a CFI to update the running total of the size of arguments + pushed onto the stack. */ + +static void +dwarf2out_args_size (const char *label, HOST_WIDE_INT size) +{ + dw_cfi_ref cfi; + + if (size == old_args_size) + return; + + old_args_size = size; + + cfi = new_cfi (); + cfi->dw_cfi_opc = DW_CFA_GNU_args_size; + cfi->dw_cfi_oprnd1.dw_cfi_offset = size; + add_fde_cfi (label, cfi); +} + +/* Adjust args_size based on stack adjustment OFFSET. */ + +static void +dwarf2out_args_size_adjust (HOST_WIDE_INT offset, const char *label) +{ + if (cfa.reg == STACK_POINTER_REGNUM) + cfa.offset += offset; + + if (cfa_store.reg == STACK_POINTER_REGNUM) + cfa_store.offset += offset; + +#ifndef STACK_GROWS_DOWNWARD + offset = -offset; +#endif + + args_size += offset; + if (args_size < 0) + args_size = 0; + + def_cfa_1 (label, &cfa); + if (flag_asynchronous_unwind_tables) + dwarf2out_args_size (label, args_size); +} /* Check INSN to see if it looks like a push or a stack adjustment, and make a note of it if it does. EH uses this information to find out how @@ -1619,30 +1640,6 @@ dwarf2out_stack_adjust (rtx insn, bool after_p) dwarf2out_args_size_adjust (offset, label); } -/* Adjust args_size based on stack adjustment OFFSET. */ - -static void -dwarf2out_args_size_adjust (HOST_WIDE_INT offset, const char *label) -{ - if (cfa.reg == STACK_POINTER_REGNUM) - cfa.offset += offset; - - if (cfa_store.reg == STACK_POINTER_REGNUM) - cfa_store.offset += offset; - -#ifndef STACK_GROWS_DOWNWARD - offset = -offset; -#endif - - args_size += offset; - if (args_size < 0) - args_size = 0; - - def_cfa_1 (label, &cfa); - if (flag_asynchronous_unwind_tables) - dwarf2out_args_size (label, args_size); -} - #endif /* We delay emitting a register save until either (a) we reach the end @@ -2209,7 +2206,8 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) && (!MEM_P (SET_DEST (elem)) || GET_CODE (expr) == SEQUENCE) && (RTX_FRAME_RELATED_P (elem) || par_index == 0)) dwarf2out_frame_debug_expr (elem, label); - else if (GET_CODE (elem) == SET + else if (!ACCUMULATE_OUTGOING_ARGS + && GET_CODE (elem) == SET && par_index != 0 && !RTX_FRAME_RELATED_P (elem)) { diff --git a/gcc/explow.c b/gcc/explow.c index a887849816b..4d1d24e501d 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -43,7 +43,6 @@ along with GCC; see the file COPYING3. If not see static rtx break_out_memory_refs (rtx); static void emit_stack_probe (rtx); -static void anti_adjust_stack_and_probe (rtx); /* Truncate and perhaps sign-extend C as appropriate for MODE. */ @@ -1308,7 +1307,7 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align) } if (flag_stack_check && STACK_CHECK_MOVING_SP) - anti_adjust_stack_and_probe (size); + anti_adjust_stack_and_probe (size, false); else anti_adjust_stack (size); @@ -1545,13 +1544,17 @@ probe_stack_range (HOST_WIDE_INT first, rtx size) } } -/* Adjust the stack by SIZE bytes while probing it. Note that we skip the - probe for the first interval + a small dope of 4 words and instead probe - that many bytes past the specified size to maintain a protection area. */ +/* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes) + while probing it. This pushes when SIZE is positive. SIZE need not + be constant. If ADJUST_BACK is true, adjust back the stack pointer + by plus SIZE at the end. */ -static void -anti_adjust_stack_and_probe (rtx size) +void +anti_adjust_stack_and_probe (rtx size, bool adjust_back) { + /* We skip the probe for the first interval + a small dope of 4 words and + probe that many bytes past the specified size to maintain a protection + area at the botton of the stack. */ const int dope = 4 * UNITS_PER_WORD; /* First ensure SIZE is Pmode. */ @@ -1660,8 +1663,11 @@ anti_adjust_stack_and_probe (rtx size) } } - /* Adjust back to account for the additional first interval. */ - adjust_stack (GEN_INT (PROBE_INTERVAL + dope)); + /* Adjust back and account for the additional first interval. */ + if (adjust_back) + adjust_stack (plus_constant (size, PROBE_INTERVAL + dope)); + else + adjust_stack (GEN_INT (PROBE_INTERVAL + dope)); } /* Return an rtx representing the register or memory location diff --git a/gcc/expr.h b/gcc/expr.h index e84779639b5..88d72daad4f 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -767,6 +767,9 @@ extern void adjust_stack (rtx); /* Add some bytes to the stack. An rtx says how many. */ extern void anti_adjust_stack (rtx); +/* Add some bytes to the stack while probing it. An rtx says how many. */ +extern void anti_adjust_stack_and_probe (rtx, bool); + /* This enum is used for the following two functions. */ enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL}; diff --git a/gcc/function.c b/gcc/function.c index d5963430c73..ca578892869 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4642,9 +4642,12 @@ expand_function_end (void) for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if (CALL_P (insn)) { + rtx max_frame_size = GEN_INT (STACK_CHECK_MAX_FRAME_SIZE); start_sequence (); - probe_stack_range (STACK_OLD_CHECK_PROTECT, - GEN_INT (STACK_CHECK_MAX_FRAME_SIZE)); + if (STACK_CHECK_MOVING_SP) + anti_adjust_stack_and_probe (max_frame_size, true); + else + probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size); seq = get_insns (); end_sequence (); emit_insn_before (seq, stack_check_probe_note); diff --git a/gcc/tree.h b/gcc/tree.h index 36deb0d51e5..f4d1e275520 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5161,11 +5161,6 @@ extern void dwarf2out_def_cfa (const char *, unsigned, HOST_WIDE_INT); extern void dwarf2out_window_save (const char *); -/* Add a CFI to update the running total of the size of arguments pushed - onto the stack. */ - -extern void dwarf2out_args_size (const char *, HOST_WIDE_INT); - /* Entry point for saving a register to the stack. */ extern void dwarf2out_reg_save (const char *, unsigned, HOST_WIDE_INT);