Patchwork RFC: LRA for x86/x86-64 [3/9]

login
register
mail settings
Submitter Vladimir Makarov
Date Sept. 27, 2012, 10:57 p.m.
Message ID <5064D9E5.2040901@redhat.com>
Download mbox | patch
Permalink /patch/187520/
State New
Headers show

Comments

Vladimir Makarov - Sept. 27, 2012, 10:57 p.m.
LRA creates a lot of new pseudos.  So the following patch implements
ahead allocation reg info information which is important for LRA
compilation speed.

2012-09-27  Vladimir Makarov  <vmakarov@redhat.com>

     * reginfo.c (max_regno_since_last_resize): New.
     (reg_preferred_class, reg_alternate_class): Add assert.
     (allocate_reg_info): Initialize allocated reg info.
     (resize_reg_info): Make bigger reg_info and initialize new memory.
     (reginfo_init): Initialize max_regno_since_last_resize.
     (setup_reg_classes): Change assert.
Paolo Bonzini - Sept. 28, 2012, 5:06 p.m.
Il 28/09/2012 00:57, Vladimir Makarov ha scritto:
> LRA creates a lot of new pseudos.  So the following patch implements
> ahead allocation reg info information which is important for LRA
> compilation speed.
> 
> 2012-09-27  Vladimir Makarov  <vmakarov@redhat.com>
> 
>     * reginfo.c (max_regno_since_last_resize): New.
>     (reg_preferred_class, reg_alternate_class): Add assert.
>     (allocate_reg_info): Initialize allocated reg info.
>     (resize_reg_info): Make bigger reg_info and initialize new memory.
>     (reginfo_init): Initialize max_regno_since_last_resize.
>     (setup_reg_classes): Change assert.
> 

Is this considered dataflow stuff?  If so, I also want to approve part
of LRA! :)

This is ok.

Paolo
Jeff Law - Sept. 28, 2012, 7:08 p.m.
On 09/27/2012 04:57 PM, Vladimir Makarov wrote:
> LRA creates a lot of new pseudos.  So the following patch implements
> ahead allocation reg info information which is important for LRA
> compilation speed.
>
> 2012-09-27  Vladimir Makarov  <vmakarov@redhat.com>
>
>      * reginfo.c (max_regno_since_last_resize): New.
>      (reg_preferred_class, reg_alternate_class): Add assert.
>      (allocate_reg_info): Initialize allocated reg info.
>      (resize_reg_info): Make bigger reg_info and initialize new memory.
>      (reginfo_init): Initialize max_regno_since_last_resize.
>      (setup_reg_classes): Change assert.
This is fine.  FWIW, it roughly mirrors code I wrote a couple years ago 
when working on range splitting.
jeff
Vladimir Makarov - Sept. 28, 2012, 11:15 p.m.
On 12-09-28 3:08 PM, Jeff Law wrote:
> On 09/27/2012 04:57 PM, Vladimir Makarov wrote:
>> LRA creates a lot of new pseudos.  So the following patch implements
>> ahead allocation reg info information which is important for LRA
>> compilation speed.
>>
>> 2012-09-27  Vladimir Makarov <vmakarov@redhat.com>
>>
>>      * reginfo.c (max_regno_since_last_resize): New.
>>      (reg_preferred_class, reg_alternate_class): Add assert.
>>      (allocate_reg_info): Initialize allocated reg info.
>>      (resize_reg_info): Make bigger reg_info and initialize new memory.
>>      (reginfo_init): Initialize max_regno_since_last_resize.
>>      (setup_reg_classes): Change assert.
> This is fine.  FWIW, it roughly mirrors code I wrote a couple years 
> ago when working on range splitting.
I repeated it too several times for some my projects.  So the history 
repeats.  I think we should have added the code even if it would be 
never used.

Patch

Index: reginfo.c
===================================================================
--- reginfo.c	(revision 191771)
+++ reginfo.c	(working copy)
@@ -839,6 +839,8 @@  static struct reg_pref *reg_pref;
 
 /* Current size of reg_info.  */
 static int reg_info_size;
+/* Max_reg_num still last resize_reg_info call.  */
+static int max_regno_since_last_resize;
 
 /* Return the reg_class in which pseudo reg number REGNO is best allocated.
    This function is sometimes called before the info has been computed.
@@ -849,6 +851,7 @@  reg_preferred_class (int regno)
   if (reg_pref == 0)
     return GENERAL_REGS;
 
+  gcc_assert (regno < reg_info_size);
   return (enum reg_class) reg_pref[regno].prefclass;
 }
 
@@ -858,6 +861,7 @@  reg_alternate_class (int regno)
   if (reg_pref == 0)
     return ALL_REGS;
 
+  gcc_assert (regno < reg_info_size);
   return (enum reg_class) reg_pref[regno].altclass;
 }
 
@@ -868,45 +872,64 @@  reg_allocno_class (int regno)
   if (reg_pref == 0)
     return NO_REGS;
 
+  gcc_assert (regno < reg_info_size);
   return (enum reg_class) reg_pref[regno].allocnoclass;
 }
 
 
 
-/* Allocate space for reg info.  */
+/* Allocate space for reg info and initilize it.  */
 static void
 allocate_reg_info (void)
 {
-  reg_info_size = max_reg_num ();
+  int i;
+
+  max_regno_since_last_resize = max_reg_num ();
+  reg_info_size = max_regno_since_last_resize * 3 / 2 + 1;
   gcc_assert (! reg_pref && ! reg_renumber);
   reg_renumber = XNEWVEC (short, reg_info_size);
   reg_pref = XCNEWVEC (struct reg_pref, reg_info_size);
   memset (reg_renumber, -1, reg_info_size * sizeof (short));
+  for (i = 0; i < reg_info_size; i++)
+    {
+      reg_pref[i].prefclass = GENERAL_REGS;
+      reg_pref[i].altclass = ALL_REGS;
+      reg_pref[i].allocnoclass = GENERAL_REGS;
+    }
 }
 
 
-/* Resize reg info. The new elements will be uninitialized.  Return
-   TRUE if new elements (for new pseudos) were added.  */
+/* Resize reg info. The new elements will be initialized.  Return TRUE
+   if new pseudos were added since the last call.  */
 bool
 resize_reg_info (void)
 {
-  int old;
+  int old, i;
+  bool change_p;
 
   if (reg_pref == NULL)
     {
       allocate_reg_info ();
       return true;
     }
-  if (reg_info_size == max_reg_num ())
-    return false;
+  change_p = max_regno_since_last_resize != max_reg_num ();
+  max_regno_since_last_resize = max_reg_num ();
+  if (reg_info_size >= max_reg_num ())
+    return change_p;
   old = reg_info_size;
-  reg_info_size = max_reg_num ();
+  reg_info_size = max_reg_num () * 3 / 2 + 1;
   gcc_assert (reg_pref && reg_renumber);
   reg_renumber = XRESIZEVEC (short, reg_renumber, reg_info_size);
   reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, reg_info_size);
   memset (reg_pref + old, -1,
 	  (reg_info_size - old) * sizeof (struct reg_pref));
   memset (reg_renumber + old, -1, (reg_info_size - old) * sizeof (short));
+  for (i = old; i < reg_info_size; i++)
+    {
+      reg_pref[i].prefclass = GENERAL_REGS;
+      reg_pref[i].altclass = ALL_REGS;
+      reg_pref[i].allocnoclass = GENERAL_REGS;
+    }
   return true;
 }
 
@@ -938,6 +961,7 @@  reginfo_init (void)
   /* This prevents dump_reg_info from losing if called
      before reginfo is run.  */
   reg_pref = NULL;
+  reg_info_size = max_regno_since_last_resize = 0;
   /* No more global register variables may be declared.  */
   no_global_reg_vars = 1;
   return 1;
@@ -964,7 +988,7 @@  struct rtl_opt_pass pass_reginfo_init =
 
 
 
-/* Set up preferred, alternate, and cover classes for REGNO as
+/* Set up preferred, alternate, and allocno classes for REGNO as
    PREFCLASS, ALTCLASS, and ALLOCNOCLASS.  */
 void
 setup_reg_classes (int regno,
@@ -973,7 +997,7 @@  setup_reg_classes (int regno,
 {
   if (reg_pref == NULL)
     return;
-  gcc_assert (reg_info_size == max_reg_num ());
+  gcc_assert (reg_info_size >= max_reg_num ());
   reg_pref[regno].prefclass = prefclass;
   reg_pref[regno].altclass = altclass;
   reg_pref[regno].allocnoclass = allocnoclass;