aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-10-09 12:47:18 -0700
committerRichard Henderson <rth@gcc.gnu.org>1999-10-09 12:47:18 -0700
commitd3a923ee2e12552204257a77c59fad127beec6e4 (patch)
tree979c66605d3637bf2f02aa8e816c05810e05aa54 /gcc/combine.c
parent1640ef3802ce93dd63448f315b5923eb1e495665 (diff)
downloadgcc-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.c114
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));