This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix address shape in cse.c:find_best_addr


Hello,

cse.c:find_best_addr tries to fold the address, doing for example
constant propagation in the process -- in situation

reg1 = cst;
(set (mem (plus reg2 reg1)) ...)

we get

(set (mem (plus reg2 cst)) ...)

However if the memory reference contains multiplication

reg1 = cst;
(set (mem (plus (mult reg2 4) reg1)) ...)

find_best_addr fails, because fold_rtx makes

  (mem (plus (ashift reg2 2) cst))

Which is not a valid address because of the ashift.  This patch
makes find_best_addr to undo this mult --> ashift transformation,
thus making the substitution to succeed.

This patch fixes a minor performance regressions with a patch I am
going to send soon.

Bootstrapped & regtested on ia64 and x86_64.

Zdenek

	* cse.c (validize_addr): New function.
	(find_best_addr): Use it.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.345
diff -c -3 -p -r1.345 cse.c
*** cse.c	25 Feb 2005 03:45:37 -0000	1.345
--- cse.c	2 Mar 2005 15:27:41 -0000
*************** canon_reg (rtx x, rtx insn)
*** 2794,2799 ****
--- 2794,2836 ----
    return x;
  }
  
+ /* ADDR comes from fold_rtx, which might have made the address invalid.
+    Try fixing that.  */
+ 
+ static rtx
+ validize_addr (rtx addr)
+ {
+   rtx op0, op1, mby;
+   enum rtx_code code = GET_CODE (addr);
+   enum machine_mode mode = GET_MODE (addr);
+ 
+   switch (code)
+     {
+     case PLUS:
+     case MINUS:
+       op0 = validize_addr (XEXP (addr, 0));
+       op1 = validize_addr (XEXP (addr, 1));
+ 
+       if (op0 == XEXP (addr, 0)
+ 	  && op1 == XEXP (addr, 1))
+ 	return addr;
+ 
+       return gen_rtx_fmt_ee (code, mode, op0, op1);
+ 
+     case ASHIFT:
+       /* Replace shift with multiply.  */
+       op0 = XEXP (addr, 0);
+       op1 = XEXP (addr, 1);
+       if (GET_CODE (op1) != CONST_INT)
+ 	return addr;
+       mby = simplify_gen_binary (ASHIFT, mode, const1_rtx, op1);
+       return gen_rtx_MULT (mode, op0, mby);
+ 
+     default:
+       return addr;
+     }
+ }
+ 
  /* LOC is a location within INSN that is an operand address (the contents of
     a MEM).  Find the best equivalent address to use that is valid for this
     insn.
*************** find_best_addr (rtx insn, rtx *loc, enum
*** 2850,2856 ****
       be valid and produce better code.  */
    if (!REG_P (addr))
      {
!       rtx folded = fold_rtx (addr, NULL_RTX);
        if (folded != addr)
  	{
  	  int addr_folded_cost = address_cost (folded, mode);
--- 2887,2894 ----
       be valid and produce better code.  */
    if (!REG_P (addr))
      {
!       rtx folded = validize_addr (fold_rtx (addr, NULL_RTX));
! 
        if (folded != addr)
  	{
  	  int addr_folded_cost = address_cost (folded, mode);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]