diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 316ca15473eeaf2c176bbb057edc6c14bf87705a..54fe27c5da37008c02df6b294f02ea85bd848257 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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. + 2004-11-25 Kazu Hirata <kazu@cs.umass.edu> * tree-phinodes.c (add_phi_arg): Take "tree" instead of diff --git a/gcc/cse.c b/gcc/cse.c index 0858b0252b8fa0bf5ea2fd944d979a7a9427c1c0..9ea5297caaff86697a5941d3830f64576e3949a6 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -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