diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1994-02-28 13:43:23 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1994-02-28 13:43:23 +0000 |
commit | 7f24d2b8d76caa278ae7bc104af7741e5cda2a40 (patch) | |
tree | 71bfce3c8b9f494b26086257e0cba9566f518bf8 /gcc/reload1.c | |
parent | 33b3d5c97b670a061ccb429b7f9889afb0817ed3 (diff) | |
download | gcc-7f24d2b8d76caa278ae7bc104af7741e5cda2a40.tar.gz |
(eliminate_regs, case MULT): New case, to apply distributive law, when
needed.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@6676 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index ac75a5181e1..90a4573282e 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -2800,33 +2800,35 @@ eliminate_regs (x, mem_mode, insn) } return x; - case EXPR_LIST: - /* If we have something in XEXP (x, 0), the usual case, eliminate it. */ - if (XEXP (x, 0)) - { - new = eliminate_regs (XEXP (x, 0), mem_mode, insn); - if (new != XEXP (x, 0)) - x = gen_rtx (EXPR_LIST, REG_NOTE_KIND (x), new, XEXP (x, 1)); - } + case MULT: + /* If this is the product of an eliminable register and a + constant, apply the distribute law and move the constant out + so that we have (plus (mult ..) ..). This is needed in order + to keep load-address insns valid. This case is pathalogical. + We ignore the possibility of overflow here. */ + if (GET_CODE (XEXP (x, 0)) == REG + && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER + && GET_CODE (XEXP (x, 1)) == CONST_INT) + for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; + ep++) + if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate) + { + if (! mem_mode + /* Refs inside notes don't count for this purpose. */ + && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST + || GET_CODE (insn) == INSN_LIST))) + ep->ref_outside_mem = 1; + + return + plus_constant (gen_rtx (MULT, Pmode, ep->to_rtx, XEXP (x, 1)), + ep->previous_offset * INTVAL (XEXP (x, 1))); + } /* ... fall through ... */ - case INSN_LIST: - /* Now do eliminations in the rest of the chain. If this was - an EXPR_LIST, this might result in allocating more memory than is - strictly needed, but it simplifies the code. */ - if (XEXP (x, 1)) - { - new = eliminate_regs (XEXP (x, 1), mem_mode, insn); - if (new != XEXP (x, 1)) - return gen_rtx (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new); - } - return x; - case CALL: case COMPARE: case MINUS: - case MULT: case DIV: case UDIV: case MOD: case UMOD: case AND: case IOR: case XOR: @@ -2845,6 +2847,29 @@ eliminate_regs (x, mem_mode, insn) } return x; + case EXPR_LIST: + /* If we have something in XEXP (x, 0), the usual case, eliminate it. */ + if (XEXP (x, 0)) + { + new = eliminate_regs (XEXP (x, 0), mem_mode, insn); + if (new != XEXP (x, 0)) + x = gen_rtx (EXPR_LIST, REG_NOTE_KIND (x), new, XEXP (x, 1)); + } + + /* ... fall through ... */ + + case INSN_LIST: + /* Now do eliminations in the rest of the chain. If this was + an EXPR_LIST, this might result in allocating more memory than is + strictly needed, but it simplifies the code. */ + if (XEXP (x, 1)) + { + new = eliminate_regs (XEXP (x, 1), mem_mode, insn); + if (new != XEXP (x, 1)) + return gen_rtx (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new); + } + return x; + case PRE_INC: case POST_INC: case PRE_DEC: |