diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1994-02-28 08:43:23 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1994-02-28 08:43:23 -0500 |
commit | 981c7390cca5fcadebeb0cc928d3301289019cbe (patch) | |
tree | 71bfce3c8b9f494b26086257e0cba9566f518bf8 | |
parent | 7633af950689bc65a75284525a7032595c94ad67 (diff) | |
download | gcc-981c7390cca5fcadebeb0cc928d3301289019cbe.zip gcc-981c7390cca5fcadebeb0cc928d3301289019cbe.tar.gz gcc-981c7390cca5fcadebeb0cc928d3301289019cbe.tar.bz2 |
(eliminate_regs, case MULT): New case, to apply distributive law, when
needed.
From-SVN: r6676
-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 ac75a51..90a4573 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: |