combine tweek

Jan Hubicka jh@suse.cz
Mon Nov 6 05:08:00 GMT 2000


Hi
This patch avoids combine from combining loads/stores to hard register with the
instruction.  This was primarily made to fix testcase sent few minutes ago
(that shows up in the x86-64 port due to register passing conventions), but it
also improves the code on 2 address non-SRC machines.

The problem itself is present for returning in register as well - only don't
show up on i386, since ecx is never used for returning and there are no
insturctions having similar behaviour to eax, as shift have for ecx.

Global.c is able to recognize such moves and allocate the pseudo in same
register to avoid it.  This does not happen when hard reg is in the
instruction itself, that just makes regclass to preffer the same register class
resulting in unnecesary move in many cases.

This also fixes testcase currently failing pointed out by Bernd:

__attribute__ ((regparm(3)))
t(int x, int y)
{
	asm(""::"d"(x),"a"(y));
}

I believe that this one is already somewhere in the testsuite.

Honza

Ne lis  5 15:38:13 CET 2000  Jan Hubicka  <jh@suse.cz>
	* combine.c (can_combine_p): Do not combine loads/stores to hard regs.
*** combine.c.old	Sun Nov  5 13:05:42 2000
--- combine.c	Sun Nov  5 14:19:09 2000
*************** can_combine_p (insn, i3, pred, succ, pde
*** 1047,1052 ****
--- 1047,1067 ----
    set = expand_field_assignment (set);
    src = SET_SRC (set), dest = SET_DEST (set);
  
+   /* Never combine load from hard regx.  Register allocator
+      can handle such reg-reg moves as special case and we get better code when
+      we keep value in the pseudo register.  Also this condition is required to
+      avoid reload from crashing on SMALL_REGISTER_CLASSES.  */
+   if (REG_P (src) && REG_P (dest)
+       && REGNO (dest) >= FIRST_PSEUDO_REGISTER
+       && REGNO (src) < FIRST_PSEUDO_REGISTER)
+     return 0;
+   p = single_set (i3);
+   /* Similary for stores into hard insns.  */
+   if (p && REG_P (SET_SRC (p)) && REG_P (SET_DEST (p))
+       && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
+       && REGNO (SET_SRC (p)) >= FIRST_PSEUDO_REGISTER)
+     return 0;
+ 
    /* Don't eliminate a store in the stack pointer.  */
    if (dest == stack_pointer_rtx
        /* If we couldn't eliminate a field assignment, we can't combine.  */


More information about the Gcc-patches mailing list