diff options
author | Richard Henderson <rth@cygnus.com> | 1999-10-09 12:47:18 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1999-10-09 12:47:18 -0700 |
commit | d3a923ee2e12552204257a77c59fad127beec6e4 (patch) | |
tree | 979c66605d3637bf2f02aa8e816c05810e05aa54 /gcc/combine.c | |
parent | 1640ef3802ce93dd63448f315b5923eb1e495665 (diff) | |
download | gcc-d3a923ee2e12552204257a77c59fad127beec6e4.zip gcc-d3a923ee2e12552204257a77c59fad127beec6e4.tar.gz gcc-d3a923ee2e12552204257a77c59fad127beec6e4.tar.bz2 |
Makefile.in (flow.o): Depend on TREE_H.
* Makefile.in (flow.o): Depend on TREE_H.
* basic-block.h (REG_SET_EQUAL_P): New.
(XOR_REG_SET): New.
(n_edges): Declare.
(free_regset_vector): Remove declaration.
(flow_delete_insn_chain): Declare.
(enum update_life_extent): New.
(update_life_info, count_or_remove_death_notes): Declare.
* combine.c (distribute_notes) [REG_DEAD]: Stop search at bb->head.
Verify register live at bb->global_live_at_start before adding USE.
* flow.c (HAVE_epilogue, HAVE_prologue): Provide default.
(CLEAN_ALLOCA): New.
(n_edges): New.
(PROP_*): New flags.
(find_basic_blocks_1): Use alloc_EXPR_LIST.
(clear_edges): Zero n_edges.
(make_edge): Increment n_edges.
(split_edge): Don't allocate bb->local_set. Increment n_edges.
(flow_delete_insn_chain): Export.
(delete_block): Decrement n_edges.
(merge_blocks_nomove): Likewise.
(life_analysis): Give life_analysis_1 PROP flags.
(verify_wide_reg_1, verify_wide_reg): New.
(verify_local_live_at_start): New.
(update_life_info): Rewrite to call into propogate_block.
(mark_reg): New.
(mark_regs_live_at_end): After reload, if epilogue as rtl,
always mark stack pointer. Conditionally mark PIC register.
After reload, mark call-saved registers, return regsiters.
(life_analysis_1): Accept PROP flags not remove_dead_code.
Call mark_regs_live_at_end before zeroing regs_ever_live.
Use calculate_global_regs_live. Copy global_live_at_end before
calling final propagate_block. Zero reg_next_use on exit.
(calculate_global_regs_live): New.
(allocate_bb_life_data): Don't allocate bb->local_set.
(init_regset_vector, free_regset_vector): Remove.
(propagate_block): Accept FLAGS not FINAL or REMOVE_DEAD_CODE.
Test flags before every operation. Warn if prologue/epilogue insn
would have been deleted.
(mark_set_regs, mark_set_1): Accept and use FLAGS.
Use alloc_EXPR_LIST.
(mark_used_regs): Accept and use FLAGS, not FINAL.
Remove special handling for RETURN.
(try_pre_increment): Use alloc_EXPR_LIST.
(dump_flow_info): Dump n_edges.
(unlink_insn_chain, split_hard_reg_notes): Remove.
(maybe_add_dead_note, maybe_add_dead_note_use): Remove.
(find_insn_with_note, new_insn_dead_notes): Remove.
(update_n_sets, sets_reg_or_subreg_1, sets_reg_or_subreg): Remove.
(maybe_remove_dead_notes, prepend_reg_notes): Remove.
(replace_insns): Remove.
(count_or_remove_death_notes): New.
(verify_flow_info): Abort on error after all checks.
(remove_edge): Decrement n_edges.
(remove_fake_edges): Tweek format.
* haifa-sched.c (schedule_insns): Use split_all_insns.
* output.h (update_life_info): Remove declaration.
* recog.c (split_all_insns): From the corpse of split_block_insns,
do the whole function block by block. Use update_life_info.
(recog_last_allowed_insn): New.
(recog_next_insn): Mind it.
(peephole2_optimize): Set it. Walk backwards through blocks.
Use update_life_info.
* rtl.h (update_flow_info, replace_insns): Remove declarations.
(split_all_insns): Declare.
* toplev.c (rest_of_compilation): Thread prologue before flow2.
Use split_all_insns.
* i386.md (or -1 peep2s): Disable.
From-SVN: r29877
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 114 |
1 files changed, 68 insertions, 46 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 813f8fa..0e634ae 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -11721,11 +11721,17 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) if (place == 0) { - for (tem = prev_nonnote_insn (i3); - place == 0 && tem - && (GET_CODE (tem) == INSN || GET_CODE (tem) == CALL_INSN); - tem = prev_nonnote_insn (tem)) + basic_block bb = BASIC_BLOCK (this_basic_block); + + for (tem = PREV_INSN (i3); place == 0; tem = PREV_INSN (tem)) { + if (GET_RTX_CLASS (GET_CODE (tem)) != 'i') + { + if (tem == bb->head) + break; + continue; + } + /* If the register is being set at TEM, see if that is all TEM is doing. If so, delete TEM. Otherwise, make this into a REG_UNUSED note instead. */ @@ -11740,8 +11746,8 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) if (set != 0) for (inner_dest = SET_DEST (set); GET_CODE (inner_dest) == STRICT_LOW_PART - || GET_CODE (inner_dest) == SUBREG - || GET_CODE (inner_dest) == ZERO_EXTRACT; + || GET_CODE (inner_dest) == SUBREG + || GET_CODE (inner_dest) == ZERO_EXTRACT; inner_dest = XEXP (inner_dest, 0)) ; @@ -11789,7 +11795,8 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) distribute_links (LOG_LINKS (cc0_setter)); PUT_CODE (cc0_setter, NOTE); - NOTE_LINE_NUMBER (cc0_setter) = NOTE_INSN_DELETED; + NOTE_LINE_NUMBER (cc0_setter) + = NOTE_INSN_DELETED; NOTE_SOURCE_FILE (cc0_setter) = 0; } #endif @@ -11818,48 +11825,64 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) REGNO (XEXP (note, 0)))) place = tem; break; - } - } - else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem)) - || (GET_CODE (tem) == CALL_INSN - && find_reg_fusage (tem, USE, XEXP (note, 0)))) - { - place = tem; - - /* If we are doing a 3->2 combination, and we have a - register which formerly died in i3 and was not used - by i2, which now no longer dies in i3 and is used in - i2 but does not die in i2, and place is between i2 - and i3, then we may need to move a link from place to - i2. */ - if (i2 && INSN_UID (place) <= max_uid_cuid - && INSN_CUID (place) > INSN_CUID (i2) - && from_insn && INSN_CUID (from_insn) > INSN_CUID (i2) - && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) - { - rtx links = LOG_LINKS (place); - LOG_LINKS (place) = 0; - distribute_links (links); - } + } + } + else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem)) + || (GET_CODE (tem) == CALL_INSN + && find_reg_fusage (tem, USE, XEXP (note, 0)))) + { + place = tem; + + /* If we are doing a 3->2 combination, and we have a + register which formerly died in i3 and was not used + by i2, which now no longer dies in i3 and is used in + i2 but does not die in i2, and place is between i2 + and i3, then we may need to move a link from place to + i2. */ + if (i2 && INSN_UID (place) <= max_uid_cuid + && INSN_CUID (place) > INSN_CUID (i2) + && from_insn && INSN_CUID (from_insn) > INSN_CUID (i2) + && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) + { + rtx links = LOG_LINKS (place); + LOG_LINKS (place) = 0; + distribute_links (links); + } + break; + } + + if (tem == bb->head) break; - } } - /* If we haven't found an insn for the death note and it - is still a REG_DEAD note, but we have hit a CODE_LABEL, - insert a USE insn for the register at that label and - put the death node there. This prevents problems with - call-state tracking in caller-save.c. */ - if (REG_NOTE_KIND (note) == REG_DEAD && place == 0 && tem != 0) + /* We haven't found an insn for the death note and it + is still a REG_DEAD note, but we have hit the beginning + of the block. If the existing life info says the reg + was dead, there's nothing left to do. + + ??? If the register was live, we ought to mark for later + global life update. Cop out like the previous code and + just add a hook for the death note to live on. */ + if (REG_NOTE_KIND (note) == REG_DEAD && place == 0) { - place - = emit_insn_after (gen_rtx_USE (VOIDmode, XEXP (note, 0)), - tem); - - /* If this insn was emitted between blocks, then update - BLOCK_HEAD of the current block to include it. */ - if (BLOCK_END (this_basic_block - 1) == tem) - BLOCK_HEAD (this_basic_block) = place; + int regno = REGNO (XEXP (note, 0)); + + if (REGNO_REG_SET_P (bb->global_live_at_start, regno)) + { + rtx die = gen_rtx_USE (VOIDmode, XEXP (note, 0)); + + place = bb->head; + if (GET_CODE (place) != CODE_LABEL + && GET_CODE (place) != NOTE) + { + place = emit_insn_before (die, place); + bb->head = place; + } + else + { + place = emit_insn_after (die, place); + } + } } } @@ -11869,7 +11892,6 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) which is what `dead_or_set_p' checks, so also check for it being set partially. */ - if (place && REG_NOTE_KIND (note) == REG_DEAD) { int regno = REGNO (XEXP (note, 0)); |