diff options
author | Andrew Pinski <pinskia@physics.uc.edu> | 2004-11-25 23:10:27 +0000 |
---|---|---|
committer | Andrew Pinski <pinskia@gcc.gnu.org> | 2004-11-25 15:10:27 -0800 |
commit | b7ca416f49abaa58b45bad5be31b9e58cf306481 (patch) | |
tree | cf03c67c70949b50f401104d29aba73b079b217f /gcc/cse.c | |
parent | d2e398dfc83188c4a94e191d51689ab56e0991a0 (diff) | |
download | gcc-b7ca416f49abaa58b45bad5be31b9e58cf306481.zip gcc-b7ca416f49abaa58b45bad5be31b9e58cf306481.tar.gz gcc-b7ca416f49abaa58b45bad5be31b9e58cf306481.tar.bz2 |
parts of PR rtl-opt/18463, rtl-opt/17647
2004-11-25 Andrew Pinski <pinskia@physics.uc.edu>
parts of PR rtl-opt/18463, rtl-opt/17647
* cse.c (canon_for_address): New function.
(find_best_addr): Call canon_for_address before getting the
address's cost when checking if we should take that address.
From-SVN: r91308
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 56 |
1 files changed, 56 insertions, 0 deletions
@@ -761,6 +761,57 @@ approx_reg_cost (rtx x) return cost; } +/* Returns a canonical version of X for the address, from the point of view, + that all multiplications are repesented as MULT instead of the multiply + by a power of 2 being repesented as ASHIFT. */ + +static rtx +canon_for_address (rtx x) +{ + enum rtx_code code; + enum machine_mode mode; + rtx new = 0; + int i; + const char *fmt; + + if (!x) + return x; + + code = GET_CODE (x); + mode = GET_MODE (x); + + switch (code) + { + case ASHIFT: + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode) + && INTVAL (XEXP (x, 1)) >= 0) + { + new = canon_for_address (XEXP (x, 0)); + new = gen_rtx_MULT (mode, new, + gen_int_mode ((HOST_WIDE_INT) 1 + << INTVAL (XEXP (x, 1)), + mode)); + } + break; + default: + break; + + } + if (new) + return new; + + /* Now recursively process each operand of this operation. */ + fmt = GET_RTX_FORMAT (code); + for (i = 0; i < GET_RTX_LENGTH (code); i++) + if (fmt[i] == 'e') + { + new = canon_for_address (XEXP (x, i)); + XEXP (x, i) = new; + } + return x; +} + /* Return a negative value if an rtx A, whose costs are given by COST_A and REGCOST_A, is more desirable than an rtx B. Return a positive value if A is less desirable, or 0 if the two are @@ -2933,6 +2984,11 @@ find_best_addr (rtx insn, rtx *loc, enum machine_mode mode) rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode, p->exp, op1); int new_cost; + + /* Get the canonical version of the address so we can accept + more. */ + new = canon_for_address (new); + new_cost = address_cost (new, mode); if (new_cost < best_addr_cost |