[PATCH] Avoid 0 in leal 0(%esp), %ecx

Jakub Jelinek jakub@redhat.com
Fri May 29 09:11:00 GMT 2009


On Thu, May 28, 2009 at 06:14:35PM +0200, Jakub Jelinek wrote:
> 3) it seems gas optimizes away 0(%rdi) into (%rdi), not sure if it
>    is allowed to do so, but perhaps gcc should try to avoid outputting the
>    0 in such cases:
> 3 leal	0(%esp), %edi	#	*lea_1	[length = 4]
> 3 movzbl	0(%esi), %edi	#	*movqi_1/6	[length = 4]
> 4 leaq  0(%rsp), %rax   #       *lea_2_rex64    [length = 5]

Here is a patch which cures this.  E.g. the leal 0(%esp), %edi
comes from eliminate_regs_1:
                if (mem_mode != 0 && GET_CODE (XEXP (x, 1)) == CONST_INT
                    && INTVAL (XEXP (x, 1)) == - ep->previous_offset)
                  return ep->to_rtx;
                else
                  return gen_rtx_PLUS (Pmode, ep->to_rtx,
                                       plus_constant (XEXP (x, 1),
                                                      ep->previous_offset));
as this wasn't inside MEM (mem_mode is VOIDmode), we don't optimize
the two offsets cancelling each other and apparently no further pass
optimizes that (plus (reg) (const_int 0)) into (reg).
In addition to dropping the useless 0 I've noticed that the code
on the other side adds 0 if base is hard frame pointer or arg pointer
(as %ebp base requires a displacement), but doesn't handle pseudos allocated
in %ebp/%rbp (when not using frame pointer) or %r13.
And scale && scale == 2 also demanded a cleanup.

Ok for trunk?

2009-05-29  Jakub Jelinek  <jakub@redhat.com>

	* config/i386/i386.c (ix86_decompose_address): Avoid useless
	0 displacement.  Add 0 displacement if base is %[er]bp or %r13.

--- gcc/config/i386/i386.c.jj	2009-05-29 00:04:31.000000000 +0200
+++ gcc/config/i386/i386.c	2009-05-29 10:06:41.000000000 +0200
@@ -8898,6 +8898,10 @@ ix86_decompose_address (rtx addr, struct
   base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
   index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
 
+  /* Avoid useless 0 displacement.  */
+  if (disp == const0_rtx && (base || index))
+    disp = NULL_RTX;
+
   /* Allow arg pointer and stack pointer as index if there is not scaling.  */
   if (base_reg && index_reg && scale == 1
       && (index_reg == arg_pointer_rtx
@@ -8909,10 +8913,16 @@ ix86_decompose_address (rtx addr, struct
       tmp = base_reg, base_reg = index_reg, index_reg = tmp;
     }
 
-  /* Special case: %ebp cannot be encoded as a base without a displacement.  */
-  if ((base_reg == hard_frame_pointer_rtx
-       || base_reg == frame_pointer_rtx
-       || base_reg == arg_pointer_rtx) && !disp)
+  /* Special case: %ebp cannot be encoded as a base without a displacement.
+     Similarly %r13.  */
+  if (!disp
+      && base_reg
+      && (base_reg == hard_frame_pointer_rtx
+	  || base_reg == frame_pointer_rtx
+	  || base_reg == arg_pointer_rtx
+	  || (REG_P (base_reg)
+	      && (REGNO (base_reg) == HARD_FRAME_POINTER_REGNUM
+		  || REGNO (base_reg) == R13_REG))))
     disp = const0_rtx;
 
   /* Special case: on K6, [%esi] makes the instruction vector decoded.
@@ -8926,7 +8936,7 @@ ix86_decompose_address (rtx addr, struct
     disp = const0_rtx;
 
   /* Special case: encode reg+reg instead of reg*2.  */
-  if (!base && index && scale && scale == 2)
+  if (!base && index && scale == 2)
     base = index, base_reg = index_reg, scale = 1;
 
   /* Special case: scaling cannot be encoded without base or displacement.  */


	Jakub



More information about the Gcc-patches mailing list