aboutsummaryrefslogtreecommitdiff
path: root/gcc/flow.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-08-11 13:13:20 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-08-11 13:13:20 -0400
commit7280c2a4f0ece9a4b2876d52a683e0b92af1b10d (patch)
treedaa93e7b258d3f391cc33d99d21c8b2066fd6f10 /gcc/flow.c
parent70a76f06adf9437d513e97acc4a169a4a140b4bb (diff)
downloadgcc-7280c2a4f0ece9a4b2876d52a683e0b92af1b10d.zip
gcc-7280c2a4f0ece9a4b2876d52a683e0b92af1b10d.tar.gz
gcc-7280c2a4f0ece9a4b2876d52a683e0b92af1b10d.tar.bz2
(find_auto_inc): Ensure that all proposed changes to insns are valid
before commiting to the auto-inc. From-SVN: r7889
Diffstat (limited to 'gcc/flow.c')
-rw-r--r--gcc/flow.c100
1 files changed, 56 insertions, 44 deletions
diff --git a/gcc/flow.c b/gcc/flow.c
index db4f37f..56c5ca7 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -2090,11 +2090,21 @@ find_auto_inc (needed, x, insn)
&& (use = find_use_as_address (PATTERN (insn), addr, offset),
use != 0 && use != (rtx) 1))
{
- int win = 0;
rtx q = SET_DEST (set);
+ enum rtx_code inc_code = (INTVAL (XEXP (y, 1)) == size
+ ? (offset ? PRE_INC : POST_INC)
+ : (offset ? PRE_DEC : POST_DEC));
if (dead_or_set_p (incr, addr))
- win = 1;
+ {
+ /* This is the simple case. Try to make the auto-inc. If
+ we can't, we are done. Otherwise, we will do any
+ needed updates below. */
+ if (! validate_change (insn, &XEXP (x, 0),
+ gen_rtx (inc_code, Pmode, addr),
+ 0))
+ return;
+ }
else if (GET_CODE (q) == REG
/* PREV_INSN used here to check the semi-open interval
[insn,incr). */
@@ -2122,14 +2132,25 @@ find_auto_inc (needed, x, insn)
BLOCK_NUM (temp) = BLOCK_NUM (insn);
}
+ /* If we can't make the auto-inc, or can't make the
+ replacement into Y, exit. There's no point in making
+ the change below if we can't do the auto-inc and doing
+ so is not correct in the pre-inc case. */
+
+ validate_change (insn, &XEXP (x, 0),
+ gen_rtx (inc_code, Pmode, q),
+ 1);
+ validate_change (incr, &XEXP (y, 0), q, 1);
+ if (! apply_change_group ())
+ return;
+
+ /* We now know we'll be doing this change, so emit the
+ new insn(s) and do the updates. */
emit_insns_before (insns, insn);
if (basic_block_head[BLOCK_NUM (insn)] == insn)
basic_block_head[BLOCK_NUM (insn)] = insns;
- XEXP (x, 0) = q;
- XEXP (y, 0) = q;
-
/* INCR will become a NOTE and INSN won't contain a
use of ADDR. If a use of ADDR was just placed in
the insn before INSN, make that the next use.
@@ -2143,7 +2164,6 @@ find_auto_inc (needed, x, insn)
addr = q;
regno = REGNO (q);
- win = 1;
/* REGNO is now used in INCR which is below INSN, but
it previously wasn't live here. If we don't mark
@@ -2159,46 +2179,38 @@ find_auto_inc (needed, x, insn)
reg_n_calls_crossed[regno]++;
}
- if (win
- /* If we have found a suitable auto-increment, do
- POST_INC around the register here, and patch out the
- increment instruction that follows. */
- && validate_change (insn, &XEXP (x, 0),
- gen_rtx ((INTVAL (XEXP (y, 1)) == size
- ? (offset ? PRE_INC : POST_INC)
- : (offset ? PRE_DEC : POST_DEC)),
- Pmode, addr), 0))
+ /* If we haven't returned, it means we were able to make the
+ auto-inc, so update the status. First, record that this insn
+ has an implicit side effect. */
+
+ REG_NOTES (insn)
+ = gen_rtx (EXPR_LIST, REG_INC, addr, REG_NOTES (insn));
+
+ /* Modify the old increment-insn to simply copy
+ the already-incremented value of our register. */
+ if (! validate_change (incr, &SET_SRC (set), addr, 0))
+ abort ();
+
+ /* If that makes it a no-op (copying the register into itself) delete
+ it so it won't appear to be a "use" and a "set" of this
+ register. */
+ if (SET_DEST (set) == addr)
+ {
+ PUT_CODE (incr, NOTE);
+ NOTE_LINE_NUMBER (incr) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (incr) = 0;
+ }
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
{
- /* Record that this insn has an implicit side effect. */
- REG_NOTES (insn)
- = gen_rtx (EXPR_LIST, REG_INC, addr, REG_NOTES (insn));
-
- /* Modify the old increment-insn to simply copy
- the already-incremented value of our register. */
- SET_SRC (set) = addr;
- /* Indicate insn must be re-recognized. */
- INSN_CODE (incr) = -1;
-
- /* If that makes it a no-op (copying the register into itself)
- then delete it so it won't appear to be a "use" and a "set"
- of this register. */
- if (SET_DEST (set) == addr)
- {
- PUT_CODE (incr, NOTE);
- NOTE_LINE_NUMBER (incr) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (incr) = 0;
- }
+ /* Count an extra reference to the reg. When a reg is
+ incremented, spilling it is worse, so we want to make
+ that less likely. */
+ reg_n_refs[regno] += loop_depth;
- if (regno >= FIRST_PSEUDO_REGISTER)
- {
- /* Count an extra reference to the reg. When a reg is
- incremented, spilling it is worse, so we want to make
- that less likely. */
- reg_n_refs[regno] += loop_depth;
- /* Count the increment as a setting of the register,
- even though it isn't a SET in rtl. */
- reg_n_sets[regno]++;
- }
+ /* Count the increment as a setting of the register,
+ even though it isn't a SET in rtl. */
+ reg_n_sets[regno]++;
}
}
}