diff options
author | Richard Henderson <rth@redhat.com> | 2011-08-02 22:18:35 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 2011-08-02 22:18:35 +0000 |
commit | bf09bd0346534d9083b254f767a68118d7fa965e (patch) | |
tree | 3dd838d8e7cbbe356e3db0a0c2bcb80fcfbb4daf /gcc/recog.c | |
parent | 1757200903af5644c86dedeb3de94b9b6274b8f8 (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.c | 32 |
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)) |