aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
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 9331681..22a5402 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))