aboutsummaryrefslogtreecommitdiff
path: root/gcc/explow.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-08-02 15:18:35 -0700
committerRichard Henderson <rth@gcc.gnu.org>2011-08-02 15:18:35 -0700
commit9a08d23082fbeb95013dc74dd3611b6b2331e3cb (patch)
tree3dd838d8e7cbbe356e3db0a0c2bcb80fcfbb4daf /gcc/explow.c
parentcde7b553dbabe7d7341998f54979af2190539cd7 (diff)
downloadgcc-9a08d23082fbeb95013dc74dd3611b6b2331e3cb.zip
gcc-9a08d23082fbeb95013dc74dd3611b6b2331e3cb.tar.gz
gcc-9a08d23082fbeb95013dc74dd3611b6b2331e3cb.tar.bz2
re PR debug/49864 (ICE: in maybe_record_trace_start, at dwarf2cfi.c:2439)
PR target/49864 * reg-notes.def (REG_ARGS_SIZE): New. * calls.c (emit_call_1): Emit REG_ARGS_SIZE for call_pop. (expand_call): Add REG_ARGS_SIZE to emit_stack_restore. * cfgcleanup.c (old_insns_match_p): Don't allow cross-jumping to different stack levels. * combine-stack-adj.c (adjust_frame_related_expr): Remove. (maybe_move_args_size_note): New. (combine_stack_adjustments_for_block): Use it. * combine.c (distribute_notes): Place REG_ARGS_SIZE. * dwarf2cfi.c (dw_cfi_row_struct): Remove args_size member. (dw_trace_info): Add beg_true_args_size, end_true_args_size, beg_delay_args_size, end_delay_args_size, eh_head, args_size_undefined. (cur_cfa): New. (queued_args_size): Remove. (add_cfi_args_size): Assert size is non-negative. (stack_adjust_offset, dwarf2out_args_size): Remove. (dwarf2out_stack_adjust, dwarf2out_notice_stack_adjust): Remove. (notice_args_size, notice_eh_throw): New. (dwarf2out_frame_debug_def_cfa): Use cur_cfa. (dwarf2out_frame_debug_adjust_cfa): Likewise. (dwarf2out_frame_debug_cfa_offset): Likewise. (dwarf2out_frame_debug_expr): Likewise. Don't stack_adjust_offset. (dwarf2out_frame_debug): Don't handle non-frame-related-p insns. (change_cfi_row): Don't emit args_size. (maybe_record_trace_start_abnormal): Split out from ... (maybe_record_trace_start): Here. Set args_size_undefined. (create_trace_edges): Update to match. (scan_trace): Handle REG_ARGS_SIZE. (connect_traces): Connect args_size between EH insns. * emit-rtl.c (try_split): Handle REG_ARGS_SIZE. * explow.c (suppress_reg_args_size): New. (adjust_stack_1): Split out from ... (adjust_stack): ... here. (anti_adjust_stack): Use it. (allocate_dynamic_stack_space): Suppress REG_ARGS_SIZE. * expr.c (mem_autoinc_base): New. (fixup_args_size_notes): New. (emit_single_push_insn_1): Rename from emit_single_push_insn. (emit_single_push_insn): New. Generate REG_ARGS_SIZE. * recog.c (peep2_attempt): Handle REG_ARGS_SIZE. * reload1.c (reload_as_needed): Likewise. * rtl.h (fixup_args_size_notes): Declare. From-SVN: r177218
Diffstat (limited to 'gcc/explow.c')
-rw-r--r--gcc/explow.c65
1 files changed, 39 insertions, 26 deletions
diff --git a/gcc/explow.c b/gcc/explow.c
index 3c692f40..f8262db 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -873,14 +873,45 @@ promote_decl_mode (const_tree decl, int *punsignedp)
}
+/* Controls the behaviour of {anti_,}adjust_stack. */
+static bool suppress_reg_args_size;
+
+/* A helper for adjust_stack and anti_adjust_stack. */
+
+static void
+adjust_stack_1 (rtx adjust, bool anti_p)
+{
+ rtx temp, insn;
+
+#ifndef STACK_GROWS_DOWNWARD
+ /* Hereafter anti_p means subtract_p. */
+ anti_p = !anti_p;
+#endif
+
+ temp = expand_binop (Pmode,
+ anti_p ? sub_optab : add_optab,
+ stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
+ OPTAB_LIB_WIDEN);
+
+ if (temp != stack_pointer_rtx)
+ insn = emit_move_insn (stack_pointer_rtx, temp);
+ else
+ {
+ insn = get_last_insn ();
+ temp = single_set (insn);
+ gcc_assert (temp != NULL && SET_DEST (temp) == stack_pointer_rtx);
+ }
+
+ if (!suppress_reg_args_size)
+ add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+}
+
/* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
This pops when ADJUST is positive. ADJUST need not be constant. */
void
adjust_stack (rtx adjust)
{
- rtx temp;
-
if (adjust == const0_rtx)
return;
@@ -889,17 +920,7 @@ adjust_stack (rtx adjust)
if (CONST_INT_P (adjust))
stack_pointer_delta -= INTVAL (adjust);
- temp = expand_binop (Pmode,
-#ifdef STACK_GROWS_DOWNWARD
- add_optab,
-#else
- sub_optab,
-#endif
- stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
- OPTAB_LIB_WIDEN);
-
- if (temp != stack_pointer_rtx)
- emit_move_insn (stack_pointer_rtx, temp);
+ adjust_stack_1 (adjust, false);
}
/* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes).
@@ -908,8 +929,6 @@ adjust_stack (rtx adjust)
void
anti_adjust_stack (rtx adjust)
{
- rtx temp;
-
if (adjust == const0_rtx)
return;
@@ -918,17 +937,7 @@ anti_adjust_stack (rtx adjust)
if (CONST_INT_P (adjust))
stack_pointer_delta += INTVAL (adjust);
- temp = expand_binop (Pmode,
-#ifdef STACK_GROWS_DOWNWARD
- sub_optab,
-#else
- add_optab,
-#endif
- stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
- OPTAB_LIB_WIDEN);
-
- if (temp != stack_pointer_rtx)
- emit_move_insn (stack_pointer_rtx, temp);
+ adjust_stack_1 (adjust, true);
}
/* Round the size of a block to be pushed up to the boundary required
@@ -1416,14 +1425,18 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
}
saved_stack_pointer_delta = stack_pointer_delta;
+ suppress_reg_args_size = true;
+
if (flag_stack_check && STACK_CHECK_MOVING_SP)
anti_adjust_stack_and_probe (size, false);
else
anti_adjust_stack (size);
+
/* Even if size is constant, don't modify stack_pointer_delta.
The constant size alloca should preserve
crtl->preferred_stack_boundary alignment. */
stack_pointer_delta = saved_stack_pointer_delta;
+ suppress_reg_args_size = false;
#ifdef STACK_GROWS_DOWNWARD
emit_move_insn (target, virtual_stack_dynamic_rtx);