Hello!

This patch rewrites ix86_conditional_register_usage to improve following things:

- Do not mark REX registers in FIXED_REGISTERS. We know that no 32bit
target supports them, so we can disable REX registers at
ix86_conditional_register_usage as well.
- Use bitmaps in CALL_USED_REGISTERS to conditionally mark used
registers for different ABIs, while still allowing -fcall-used-REG and
-fcall-saved-REG options to be used. This brings TARGET_64BIT_MS_ABI
to the same level as other ABIs and  allows future ABIs to be handled.
- Calculate CLOBBERED_REGS for 32bit targets in the same way as for
64bit targets, removing another 32bit/64bit difference. The regclass
definition has to be moved just before GENERAL_REGS, since it is
derived from this register class. We depend on fixed register
definition to avoid allocation of ESP and REX registers for
CLOBBERED_REGS class. This is the same approach as 64bit targets have
to avoid ESP, and the same approach as 32bit targets have to avoid REX
registers in  GENERAL_REGS class.
- Some trivial code reorderings, so we don't process non-existing registers.

2012-08-13  Uros Bizjak  <ubiz...@gmail.com>

        * config/i386/i386.h (FIXED_REGISTERS): Do not mark REX registers here.
        (CALL_USED_REGISTERS): Use bitmaps to mark call-used registers
        for different ABIs.
        (enum reg_class): Move CLOBBERED_REGS just before GENERAL_REGS.
        (REG_CLASS_NAMES): Update.
        (REG_CLASS_CONTENTS): Update.  Clear CLOBBERED_REGS members.
        * config/i386/i386.c (ix86_conditional_register_usage): Disable
        REX registers on 32bit targets.  Handle bitmaps from
        CALL_USED_REGISTERS initializer.  Calculate CLOBBERED_REGS register
        set from GENERAL_REGS also for 32bit targets.  Do not change call
        used register set for TARGET_64BIT_MS_ABI separately.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu
{,-m32} and i686-pc-linux-gnu.

Patch was committed to mainline SVN.

Uros.
Index: i386.c
===================================================================
--- i386.c      (revision 190347)
+++ i386.c      (working copy)
@@ -4135,43 +4135,42 @@ ix86_option_override (void)
 static void
 ix86_conditional_register_usage (void)
 {
-  int i;
+  int i, c_mask;
   unsigned int j;
 
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    {
-      if (fixed_regs[i] > 1)
-       fixed_regs[i] = (fixed_regs[i] == (TARGET_64BIT ? 3 : 2));
-      if (call_used_regs[i] > 1)
-       call_used_regs[i] = (call_used_regs[i] == (TARGET_64BIT ? 3 : 2));
-    }
-
   /* The PIC register, if it exists, is fixed.  */
   j = PIC_OFFSET_TABLE_REGNUM;
   if (j != INVALID_REGNUM)
     fixed_regs[j] = call_used_regs[j] = 1;
 
-  /* The 64-bit MS_ABI changes the set of call-used registers.  */
-  if (TARGET_64BIT_MS_ABI)
+  /* For 32-bit targets, squash the REX registers.  */
+  if (! TARGET_64BIT)
     {
-      call_used_regs[SI_REG] = 0;
-      call_used_regs[DI_REG] = 0;
-      call_used_regs[XMM6_REG] = 0;
-      call_used_regs[XMM7_REG] = 0;
+      for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
+       fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
       for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
-       call_used_regs[i] = 0;
+       fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
     }
 
-  /* The default setting of CLOBBERED_REGS is for 32-bit; add in the
-     other call-clobbered regs for 64-bit.  */
-  if (TARGET_64BIT)
+  /*  See the definition of CALL_USED_REGISTERS in i386.h.  */
+  c_mask = (TARGET_64BIT_MS_ABI ? (1 << 3)
+           : TARGET_64BIT ? (1 << 2)
+           : (1 << 1));
+  
+  CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
+
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
-      CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
+      /* Set/reset conditionally defined registers from
+        CALL_USED_REGISTERS initializer.  */
+      if (call_used_regs[i] > 1)
+       call_used_regs[i] = !!(call_used_regs[i] & c_mask);
 
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-       if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
-           && call_used_regs[i])
-         SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
+      /* Calculate registers of CLOBBERED_REGS register set
+        as call used registers from GENERAL_REGS register set.  */
+      if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
+         && call_used_regs[i])
+       SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
     }
 
   /* If MMX is disabled, squash the registers.  */
@@ -4191,15 +4190,6 @@ ix86_conditional_register_usage (void)
     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
       if (TEST_HARD_REG_BIT (reg_class_contents[(int)FLOAT_REGS], i))
        fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
-
-  /* If 32-bit, squash the 64-bit registers.  */
-  if (! TARGET_64BIT)
-    {
-      for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
-       reg_names[i] = "";
-      for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
-       reg_names[i] = "";
-    }
 }
 
 
Index: i386.h
===================================================================
--- i386.h      (revision 190347)
+++ i386.h      (working copy)
@@ -921,12 +921,9 @@ enum target_cpu_default
    and are not available for the register allocator.
    On the 80386, the stack pointer is such, as is the arg pointer.
 
-   The value is zero if the register is not fixed on either 32 or
-   64 bit targets, one if the register if fixed on both 32 and 64
-   bit targets, two if it is only fixed on 32bit targets and three
-   if its only fixed on 64bit targets.
-   Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE.
- */
+   REX registers are disabled for 32bit targets in
+   TARGET_CONDITIONAL_REGISTER_USAGE.  */
+
 #define FIXED_REGISTERS                                                \
 /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/     \
 {  0, 0, 0, 0, 0, 0, 0, 1, 0,  0,  0,  0,  0,  0,  0,  0,      \
@@ -937,11 +934,10 @@ enum target_cpu_default
 /* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/                    \
      0,   0,   0,   0,   0,   0,   0,   0,                     \
 /*  r8,  r9, r10, r11, r12, r13, r14, r15*/                    \
-     2,   2,   2,   2,   2,   2,   2,   2,                     \
+     0,   0,   0,   0,   0,   0,   0,   0,                     \
 /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/              \
-     2,   2,    2,    2,    2,    2,    2,    2 }
+     0,   0,    0,    0,    0,    0,    0,    0 }
 
-
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
    registers that can be used without being saved.
@@ -949,25 +945,26 @@ enum target_cpu_default
    and the register where structure-value addresses are passed.
    Aside from that, you can include as many other registers as you like.
 
-   The value is zero if the register is not call used on either 32 or
-   64 bit targets, one if the register if call used on both 32 and 64
-   bit targets, two if it is only call used on 32bit targets and three
-   if its only call used on 64bit targets.
-   Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE.
-*/
+   Value is set to 1 if the register is call used unconditionally.
+   Bit one is set if the register is call used on TARGET_32BIT ABI.
+   Bit two is set if the register is call used on TARGET_64BIT ABI.
+   Bit three is set if the register is call used on TARGET_64BIT_MS_ABI.
+
+   Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE.  */
+
 #define CALL_USED_REGISTERS                                    \
 /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/     \
-{  1, 1, 1, 0, 3, 3, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,      \
+{  1, 1, 1, 0, 4, 4, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,      \
 /*arg,flags,fpsr,fpcr,frame*/                                  \
     1,   1,    1,   1,    1,                                   \
 /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/                    \
-     1,   1,   1,   1,   1,   1,   1,   1,                     \
+     1,   1,   1,   1,   1,   1,   6,   6,                     \
 /* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/                    \
      1,   1,   1,   1,   1,   1,   1,   1,                     \
 /*  r8,  r9, r10, r11, r12, r13, r14, r15*/                    \
      1,   1,   1,   1,   2,   2,   2,   2,                     \
 /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/              \
-     1,   1,    1,    1,    1,    1,    1,    1 }
+     6,   6,    6,    6,    6,    6,    6,    6 }
 
 /* Order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.  List frame pointer
@@ -1203,11 +1200,11 @@ enum reg_class
   NO_REGS,
   AREG, DREG, CREG, BREG, SIREG, DIREG,
   AD_REGS,                     /* %eax/%edx for DImode */
-  CLOBBERED_REGS,              /* call-clobbered integers */
   Q_REGS,                      /* %eax %ebx %ecx %edx */
   NON_Q_REGS,                  /* %esi %edi %ebp %esp */
   INDEX_REGS,                  /* %eax %ebx %ecx %edx %esi %edi %ebp */
   LEGACY_REGS,                 /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
+  CLOBBERED_REGS,              /* call-clobbered integer registers */
   GENERAL_REGS,                        /* %eax %ebx %ecx %edx %esi %edi %ebp 
%esp
                                   %r8 %r9 %r10 %r11 %r12 %r13 %r14 %r15 */
   FP_TOP_REG, FP_SECOND_REG,   /* %st(0) %st(1) */
@@ -1253,10 +1250,10 @@ enum reg_class
    "AREG", "DREG", "CREG", "BREG",     \
    "SIREG", "DIREG",                   \
    "AD_REGS",                          \
-   "CLOBBERED_REGS",                   \
    "Q_REGS", "NON_Q_REGS",             \
    "INDEX_REGS",                       \
    "LEGACY_REGS",                      \
+   "CLOBBERED_REGS",                   \
    "GENERAL_REGS",                     \
    "FP_TOP_REG", "FP_SECOND_REG",      \
    "FLOAT_REGS",                       \
@@ -1274,9 +1271,8 @@ enum reg_class
 /* Define which registers fit in which classes.  This is an initializer
    for a vector of HARD_REG_SET of length N_REG_CLASSES.
 
-   Note that the default setting of CLOBBERED_REGS is for 32-bit; this
-   is adjusted by TARGET_CONDITIONAL_REGISTER_USAGE for the 64-bit ABI
-   in effect.  */
+   Note that CLOBBERED_REGS are calculated by
+   TARGET_CONDITIONAL_REGISTER_USAGE.  */
 
 #define REG_CLASS_CONTENTS                                             \
 {     { 0x00,     0x0 },                                               \
@@ -1284,11 +1280,11 @@ enum reg_class
       { 0x04,     0x0 }, { 0x08, 0x0 },        /* CREG, BREG */                
\
       { 0x10,     0x0 }, { 0x20, 0x0 },        /* SIREG, DIREG */              
\
       { 0x03,     0x0 },               /* AD_REGS */                   \
-      { 0x07,     0x0 },               /* CLOBBERED_REGS */            \
       { 0x0f,     0x0 },               /* Q_REGS */                    \
   { 0x1100f0,  0x1fe0 },               /* NON_Q_REGS */                \
       { 0x7f,  0x1fe0 },               /* INDEX_REGS */                \
   { 0x1100ff,     0x0 },               /* LEGACY_REGS */               \
+      { 0x00,     0x0 },               /* CLOBBERED_REGS */            \
   { 0x1100ff,  0x1fe0 },               /* GENERAL_REGS */              \
      { 0x100,     0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\
     { 0xff00,     0x0 },               /* FLOAT_REGS */                \

Reply via email to