From 7280c2a4f0ece9a4b2876d52a683e0b92af1b10d Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Thu, 11 Aug 1994 13:13:20 -0400 Subject: [PATCH] (find_auto_inc): Ensure that all proposed changes to insns are valid before commiting to the auto-inc. From-SVN: r7889 --- gcc/flow.c | 98 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/gcc/flow.c b/gcc/flow.c index db4f37f64e3..56c5ca737e1 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) { - /* Record that this insn has an implicit side effect. */ - REG_NOTES (insn) - = gen_rtx (EXPR_LIST, REG_INC, addr, REG_NOTES (insn)); + PUT_CODE (incr, NOTE); + NOTE_LINE_NUMBER (incr) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (incr) = 0; + } - /* 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 (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; - /* 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 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]++; } } }