diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-17 15:38:48 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-17 15:38:48 +0000 |
commit | c69c2a1026c8837ea5ebe131118f2bcf0f274139 (patch) | |
tree | 0ed5f441b7efcebdfd2d9a9ed091d473b2b0eba9 /gcc/loop-invariant.c | |
parent | 34d1dd5de6bbc3ebcc5ed5ca36a968750e7b4839 (diff) | |
download | gcc-c69c2a1026c8837ea5ebe131118f2bcf0f274139.tar.gz |
PR rtl-optimization/26449
* loop-invariant.c (move_invariant_reg): Do not use force_operand.
(seq_insns_valid_p): Removed.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128549 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop-invariant.c')
-rw-r--r-- | gcc/loop-invariant.c | 77 |
1 files changed, 18 insertions, 59 deletions
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 91c5d05c6f5..ba1f2888b00 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -1154,20 +1154,6 @@ find_invariants_to_move (void) } } -/* Returns true if all insns in SEQ are valid. */ - -static bool -seq_insns_valid_p (rtx seq) -{ - rtx x; - - for (x = seq; x; x = NEXT_INSN (x)) - if (insn_invalid_p (x)) - return false; - - return true; -} - /* Move invariant INVNO out of the LOOP. Returns true if this succeeds, false otherwise. */ @@ -1178,7 +1164,7 @@ move_invariant_reg (struct loop *loop, unsigned invno) struct invariant *repr = VEC_index (invariant_p, invariants, inv->eqto); unsigned i; basic_block preheader = loop_preheader_edge (loop)->src; - rtx reg, set, dest, seq, op; + rtx reg, set, dest, note; struct use *use; bitmap_iterator bi; @@ -1209,50 +1195,23 @@ move_invariant_reg (struct loop *loop, unsigned invno) dest = SET_DEST (set); reg = gen_reg_rtx (GET_MODE (dest)); - /* If the SET_DEST of the invariant insn is a pseudo, we can just move - the insn out of the loop. Otherwise, we have to use gen_move_insn - to let emit_move_insn produce a valid instruction stream. */ - if (REG_P (dest) && !HARD_REGISTER_P (dest)) - { - rtx note; - - emit_insn_after (gen_move_insn (dest, reg), inv->insn); - SET_DEST (set) = reg; - df_insn_rescan (inv->insn); - reorder_insns (inv->insn, inv->insn, BB_END (preheader)); - - /* If there is a REG_EQUAL note on the insn we just moved, and - insn is in a basic block that is not always executed, the note - may no longer be valid after we move the insn. - Note that uses in REG_EQUAL notes are taken into account in - the computation of invariants. Hence it is safe to retain the - note even if the note contains register references. */ - if (! inv->always_executed - && (note = find_reg_note (inv->insn, REG_EQUAL, NULL_RTX))) - remove_note (inv->insn, note); - } - else - { - start_sequence (); - op = force_operand (SET_SRC (set), reg); - if (!op) - { - end_sequence (); - goto fail; - } - if (op != reg) - emit_move_insn (reg, op); - seq = get_insns (); - unshare_all_rtl_in_chain (seq); - end_sequence (); - - if (!seq_insns_valid_p (seq)) - goto fail; - emit_insn_after (seq, BB_END (preheader)); - - emit_insn_after (gen_move_insn (dest, reg), inv->insn); - delete_insn (inv->insn); - } + /* Try replacing the destination by a new pseudoregister. */ + if (!validate_change (inv->insn, &SET_DEST (set), reg, false)) + goto fail; + df_insn_rescan (inv->insn); + + emit_insn_after (gen_move_insn (dest, reg), inv->insn); + reorder_insns (inv->insn, inv->insn, BB_END (preheader)); + + /* If there is a REG_EQUAL note on the insn we just moved, and + insn is in a basic block that is not always executed, the note + may no longer be valid after we move the insn. + Note that uses in REG_EQUAL notes are taken into account in + the computation of invariants. Hence it is safe to retain the + note even if the note contains register references. */ + if (! inv->always_executed + && (note = find_reg_note (inv->insn, REG_EQUAL, NULL_RTX))) + remove_note (inv->insn, note); } else { |