Commit 7280c2a4 by Richard Kenner

(find_auto_inc): Ensure that all proposed changes to insns are valid

before commiting to the auto-inc.

From-SVN: r7889
parent 70a76f06
...@@ -2090,11 +2090,21 @@ find_auto_inc (needed, x, insn) ...@@ -2090,11 +2090,21 @@ find_auto_inc (needed, x, insn)
&& (use = find_use_as_address (PATTERN (insn), addr, offset), && (use = find_use_as_address (PATTERN (insn), addr, offset),
use != 0 && use != (rtx) 1)) use != 0 && use != (rtx) 1))
{ {
int win = 0;
rtx q = SET_DEST (set); 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)) 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 else if (GET_CODE (q) == REG
/* PREV_INSN used here to check the semi-open interval /* PREV_INSN used here to check the semi-open interval
[insn,incr). */ [insn,incr). */
...@@ -2122,14 +2132,25 @@ find_auto_inc (needed, x, insn) ...@@ -2122,14 +2132,25 @@ find_auto_inc (needed, x, insn)
BLOCK_NUM (temp) = BLOCK_NUM (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); emit_insns_before (insns, insn);
if (basic_block_head[BLOCK_NUM (insn)] == insn) if (basic_block_head[BLOCK_NUM (insn)] == insn)
basic_block_head[BLOCK_NUM (insn)] = insns; 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 /* INCR will become a NOTE and INSN won't contain a
use of ADDR. If a use of ADDR was just placed in use of ADDR. If a use of ADDR was just placed in
the insn before INSN, make that the next use. the insn before INSN, make that the next use.
...@@ -2143,7 +2164,6 @@ find_auto_inc (needed, x, insn) ...@@ -2143,7 +2164,6 @@ find_auto_inc (needed, x, insn)
addr = q; addr = q;
regno = REGNO (q); regno = REGNO (q);
win = 1;
/* REGNO is now used in INCR which is below INSN, but /* REGNO is now used in INCR which is below INSN, but
it previously wasn't live here. If we don't mark it previously wasn't live here. If we don't mark
...@@ -2159,46 +2179,38 @@ find_auto_inc (needed, x, insn) ...@@ -2159,46 +2179,38 @@ find_auto_inc (needed, x, insn)
reg_n_calls_crossed[regno]++; reg_n_calls_crossed[regno]++;
} }
if (win /* If we haven't returned, it means we were able to make the
/* If we have found a suitable auto-increment, do auto-inc, so update the status. First, record that this insn
POST_INC around the register here, and patch out the has an implicit side effect. */
increment instruction that follows. */
&& validate_change (insn, &XEXP (x, 0), REG_NOTES (insn)
gen_rtx ((INTVAL (XEXP (y, 1)) == size = gen_rtx (EXPR_LIST, REG_INC, addr, REG_NOTES (insn));
? (offset ? PRE_INC : POST_INC)
: (offset ? PRE_DEC : POST_DEC)), /* Modify the old increment-insn to simply copy
Pmode, addr), 0)) 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. */ /* Count an extra reference to the reg. When a reg is
REG_NOTES (insn) incremented, spilling it is worse, so we want to make
= gen_rtx (EXPR_LIST, REG_INC, addr, REG_NOTES (insn)); that less likely. */
reg_n_refs[regno] += loop_depth;
/* 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;
}
if (regno >= FIRST_PSEUDO_REGISTER) /* Count the increment as a setting of the register,
{ even though it isn't a SET in rtl. */
/* Count an extra reference to the reg. When a reg is reg_n_sets[regno]++;
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]++;
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment