aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-08-02 22:18:35 +0000
committerRichard Henderson <rth@redhat.com>2011-08-02 22:18:35 +0000
commitbf09bd0346534d9083b254f767a68118d7fa965e (patch)
tree3dd838d8e7cbbe356e3db0a0c2bcb80fcfbb4daf /gcc/recog.c
parent1757200903af5644c86dedeb3de94b9b6274b8f8 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@177218 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index 933168149a8..22a5402f00f 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3146,16 +3146,17 @@ static rtx
peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
{
int i;
- rtx last, note, before_try, x;
+ rtx last, eh_note, as_note, before_try, x;
rtx old_insn, new_insn;
bool was_call = false;
- /* If we are splittind an RTX_FRAME_RELATED_P insn, do not allow it to
+ /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
match more than one insn, or to be split into more than one insn. */
old_insn = peep2_insn_data[peep2_current].insn;
if (RTX_FRAME_RELATED_P (old_insn))
{
bool any_note = false;
+ rtx note;
if (match_len != 0)
return NULL;
@@ -3236,6 +3237,7 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
for (i = 0; i <= match_len; ++i)
{
int j;
+ rtx note;
j = peep2_buf_position (peep2_current + i);
old_insn = peep2_insn_data[j].insn;
@@ -3281,9 +3283,21 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
break;
}
- i = peep2_buf_position (peep2_current + match_len);
+ /* If we matched any instruction that had a REG_ARGS_SIZE, then
+ move those notes over to the new sequence. */
+ as_note = NULL;
+ for (i = match_len; i >= 0; --i)
+ {
+ int j = peep2_buf_position (peep2_current + i);
+ old_insn = peep2_insn_data[j].insn;
+
+ as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
+ if (as_note)
+ break;
+ }
- note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
+ i = peep2_buf_position (peep2_current + match_len);
+ eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
/* Replace the old sequence with the new. */
last = emit_insn_after_setloc (attempt,
@@ -3293,7 +3307,7 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
delete_insn_chain (insn, peep2_insn_data[i].insn, false);
/* Re-insert the EH_REGION notes. */
- if (note || (was_call && nonlocal_goto_handler_labels))
+ if (eh_note || (was_call && nonlocal_goto_handler_labels))
{
edge eh_edge;
edge_iterator ei;
@@ -3302,8 +3316,8 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
break;
- if (note)
- copy_reg_eh_region_note_backward (note, last, before_try);
+ if (eh_note)
+ copy_reg_eh_region_note_backward (eh_note, last, before_try);
if (eh_edge)
for (x = last; x != before_try; x = PREV_INSN (x))
@@ -3336,6 +3350,10 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
peep2_do_cleanup_cfg |= purge_dead_edges (bb);
}
+ /* Re-insert the ARGS_SIZE notes. */
+ if (as_note)
+ fixup_args_size_notes (before_try, last, INTVAL (XEXP (as_note, 0)));
+
/* If we generated a jump instruction, it won't have
JUMP_LABEL set. Recompute after we're done. */
for (x = last; x != before_try; x = PREV_INSN (x))