diff options
author | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-25 20:56:46 +0000 |
---|---|---|
committer | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-25 20:56:46 +0000 |
commit | cc6757ec825d05ba36419234bdcfea6bf03079d1 (patch) | |
tree | f43a6eb2bfabc2b51c7f153a8a2a49f931ad9e74 /gcc/reload1.c | |
parent | 46cdddaa43b816c9fef2072dbab9d0dbc214e918 (diff) | |
download | gcc-cc6757ec825d05ba36419234bdcfea6bf03079d1.tar.gz |
* reload.c (find_reloads_address_1): Handle PLUS expressions resulting
from register elimination as PRE_MODIFY / POST_MODIFY increments.
Do not attempt to handle MEM inside auto-inc expressions.
* reload1.c (eliminate_regs_1): Do not attempt to handle elimination
of a register modified by an auto-inc expression. However, do handle
elimination of a register used as PRE_MODIFY / POST_MODIFY increment.
(elimination_effects): Prohibit elimination of a register modified
by an auto-inc expression. Disable register elimination rules whose
target register is modified by an auto-inc expression with variable
increment.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122318 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index c86b2bd429f..c469fb07618 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -2548,6 +2548,30 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn, case POST_INC: case PRE_DEC: case POST_DEC: + /* We do not support elimination of a register that is modified. + elimination_effects has already make sure that this does not + happen. */ + return x; + + case PRE_MODIFY: + case POST_MODIFY: + /* We do not support elimination of a register that is modified. + elimination_effects has already make sure that this does not + happen. The only remaining case we need to consider here is + that the increment value may be an eliminable register. */ + if (GET_CODE (XEXP (x, 1)) == PLUS + && XEXP (XEXP (x, 1), 0) == XEXP (x, 0)) + { + rtx new = eliminate_regs_1 (XEXP (XEXP (x, 1), 1), mem_mode, + insn, true); + + if (new != XEXP (XEXP (x, 1), 1)) + return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0), + gen_rtx_PLUS (GET_MODE (x), + XEXP (x, 0), new)); + } + return x; + case STRICT_LOW_PART: case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND: @@ -2743,6 +2767,14 @@ elimination_effects (rtx x, enum machine_mode mem_mode) case POST_DEC: case POST_MODIFY: case PRE_MODIFY: + /* If we modify the source of an elimination rule, disable it. */ + for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) + if (ep->from_rtx == XEXP (x, 0)) + ep->can_eliminate = 0; + + /* If we modify the target of an elimination rule by adding a constant, + update its offset. If we modify the target in any other way, we'll + have to disable the rule as well. */ for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) if (ep->to_rtx == XEXP (x, 0)) { @@ -2757,11 +2789,15 @@ elimination_effects (rtx x, enum machine_mode mem_mode) ep->offset += size; else if (code == PRE_INC || code == POST_INC) ep->offset -= size; - else if ((code == PRE_MODIFY || code == POST_MODIFY) - && GET_CODE (XEXP (x, 1)) == PLUS - && XEXP (x, 0) == XEXP (XEXP (x, 1), 0) - && CONSTANT_P (XEXP (XEXP (x, 1), 1))) - ep->offset -= INTVAL (XEXP (XEXP (x, 1), 1)); + else if (code == PRE_MODIFY || code == POST_MODIFY) + { + if (GET_CODE (XEXP (x, 1)) == PLUS + && XEXP (x, 0) == XEXP (XEXP (x, 1), 0) + && CONST_INT_P (XEXP (XEXP (x, 1), 1))) + ep->offset -= INTVAL (XEXP (XEXP (x, 1), 1)); + else + ep->can_eliminate = 0; + } } /* These two aren't unary operators. */ |