OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / ira.c
index d7f4e3d..44f7032 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -434,6 +434,8 @@ setup_class_hard_regs (void)
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
       CLEAR_HARD_REG_SET (processed_hard_reg_set);
+      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+       ira_class_hard_reg_index[cl][0] = -1;
       for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        {
 #ifdef REG_ALLOC_ORDER
@@ -714,22 +716,72 @@ enum reg_class ira_important_classes[N_REG_CLASSES];
    classes.  */
 int ira_important_class_nums[N_REG_CLASSES];
 
-/* Check IRA_COVER_CLASSES and sets the four global variables defined
-   above.  */
+/* Set the four global variables defined above.  */
 static void
 setup_cover_and_important_classes (void)
 {
-  int i, j;
+  int i, j, n;
+  bool set_p, eq_p;
   enum reg_class cl;
-  const enum reg_class *classes;
+  const enum reg_class *cover_classes;
   HARD_REG_SET temp_hard_regset2;
+  static enum reg_class classes[LIM_REG_CLASSES + 1];
+
+  if (targetm.ira_cover_classes == NULL)
+    cover_classes = NULL;
+  else
+    cover_classes = targetm.ira_cover_classes ();
+  if (cover_classes == NULL)
+    ira_assert (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY);
+  else
+    {
+      for (i = 0; (cl = cover_classes[i]) != LIM_REG_CLASSES; i++)
+       classes[i] = cl;
+      classes[i] = LIM_REG_CLASSES;
+    }
+
+  if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
+    {
+      n = 0;
+      for (i = 0; i <= LIM_REG_CLASSES; i++)
+       {
+         if (i == NO_REGS)
+           continue;
+#ifdef CONSTRAINT__LIMIT
+         for (j = 0; j < CONSTRAINT__LIMIT; j++)
+           if ((int) regclass_for_constraint (j) == i)
+             break;
+         if (j < CONSTRAINT__LIMIT)
+           {
+             classes[n++] = i;
+             continue;
+           }
+#endif
+         COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]);
+         AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+         for (j = 0; j < LIM_REG_CLASSES; j++)
+           {
+             if (i == j)
+               continue;
+             COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[j]);
+             AND_COMPL_HARD_REG_SET (temp_hard_regset2,
+                                     no_unit_alloc_regs);
+             if (hard_reg_set_equal_p (temp_hard_regset,
+                                       temp_hard_regset2))
+                   break;
+           }
+         if (j >= i)
+           classes[n++] = i;
+       }
+      classes[n] = LIM_REG_CLASSES;
+    }
 
-  classes = targetm.ira_cover_classes ();
   ira_reg_class_cover_size = 0;
   for (i = 0; (cl = classes[i]) != LIM_REG_CLASSES; i++)
     {
       for (j = 0; j < i; j++)
-       if (reg_classes_intersect_p (cl, classes[j]))
+       if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY
+           && reg_classes_intersect_p (cl, classes[j]))
          gcc_unreachable ();
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
@@ -742,22 +794,34 @@ setup_cover_and_important_classes (void)
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
       if (! hard_reg_set_empty_p (temp_hard_regset))
-       for (j = 0; j < ira_reg_class_cover_size; j++)
-         {
-           COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
-           AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-           COPY_HARD_REG_SET (temp_hard_regset2,
-                              reg_class_contents[ira_reg_class_cover[j]]);
-           AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
-           if (cl == ira_reg_class_cover[j]
-               || (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2)
-                   && ! hard_reg_set_equal_p (temp_hard_regset,
-                                              temp_hard_regset2)))
-             {
-               ira_important_class_nums[cl] = ira_important_classes_num;
-               ira_important_classes[ira_important_classes_num++] = cl;
-             }
-         }
+       {
+         set_p = eq_p = false;
+         for (j = 0; j < ira_reg_class_cover_size; j++)
+           {
+             COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+             AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+             COPY_HARD_REG_SET (temp_hard_regset2,
+                                reg_class_contents[ira_reg_class_cover[j]]);
+             AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
+             if (cl == ira_reg_class_cover[j])
+               {
+                 eq_p = false;
+                 set_p = true;
+                 break;
+               }
+             else if (hard_reg_set_equal_p (temp_hard_regset,
+                                            temp_hard_regset2))
+               eq_p = true;
+             else if (hard_reg_set_subset_p (temp_hard_regset,
+                                             temp_hard_regset2))
+               set_p = true;
+           }
+         if (set_p && ! eq_p)
+           {
+             ira_important_class_nums[cl] = ira_important_classes_num;
+             ira_important_classes[ira_important_classes_num++] = cl;
+           }
+       }
     }
 }
 
@@ -776,25 +840,44 @@ setup_class_translate (void)
 
   for (cl = 0; cl < N_REG_CLASSES; cl++)
     ira_class_translate[cl] = NO_REGS;
+  
+  if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
+    for (cl = 0; cl < LIM_REG_CLASSES; cl++)
+      {
+       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+       for (i = 0; i < ira_reg_class_cover_size; i++)
+         {
+           HARD_REG_SET temp_hard_regset2;
+           
+           cover_class = ira_reg_class_cover[i];
+           COPY_HARD_REG_SET (temp_hard_regset2,
+                              reg_class_contents[cover_class]);
+           AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
+           if (hard_reg_set_equal_p (temp_hard_regset, temp_hard_regset2))
+             ira_class_translate[cl] = cover_class;
+         }
+      }
   for (i = 0; i < ira_reg_class_cover_size; i++)
     {
       cover_class = ira_reg_class_cover[i];
-      for (cl_ptr = &alloc_reg_class_subclasses[cover_class][0];
-          (cl = *cl_ptr) != LIM_REG_CLASSES;
-          cl_ptr++)
-       {
-         if (ira_class_translate[cl] == NO_REGS)
-           ira_class_translate[cl] = cover_class;
+      if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY)
+       for (cl_ptr = &alloc_reg_class_subclasses[cover_class][0];
+            (cl = *cl_ptr) != LIM_REG_CLASSES;
+            cl_ptr++)
+         {
+           if (ira_class_translate[cl] == NO_REGS)
+             ira_class_translate[cl] = cover_class;
 #ifdef ENABLE_IRA_CHECKING
-         else
-           {
-             COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
-             AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-             if (! hard_reg_set_empty_p (temp_hard_regset))
-               gcc_unreachable ();
-           }
+           else
+             {
+               COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+               AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+               if (! hard_reg_set_empty_p (temp_hard_regset))
+                 gcc_unreachable ();
+             }
 #endif
-       }
+         }
       ira_class_translate[cover_class] = cover_class;
     }
   /* For classes which are not fully covered by a cover class (in
@@ -842,6 +925,17 @@ setup_class_translate (void)
    account.  */
 enum reg_class ira_reg_class_intersect[N_REG_CLASSES][N_REG_CLASSES];
 
+/* True if the two classes (that is calculated taking only hard
+   registers available for allocation into account) are
+   intersected.  */
+bool ira_reg_classes_intersect_p[N_REG_CLASSES][N_REG_CLASSES];
+
+/* Important classes with end marker LIM_REG_CLASSES which are
+   supersets with given important class (the first index).  That
+   includes given class itself.  This is calculated taking only hard
+   registers available for allocation into account.  */
+enum reg_class ira_reg_class_super_classes[N_REG_CLASSES][N_REG_CLASSES];
+
 /* The biggest important reg_class inside of union of the two
    reg_classes (that is calculated taking only hard registers
    available for allocation into account).  If the both reg_classes
@@ -851,17 +945,23 @@ enum reg_class ira_reg_class_intersect[N_REG_CLASSES][N_REG_CLASSES];
    reg_class_subunion value.  */
 enum reg_class ira_reg_class_union[N_REG_CLASSES][N_REG_CLASSES];
 
-/* Set up IRA_REG_CLASS_INTERSECT and IRA_REG_CLASS_UNION.  */
+/* Set up the above reg class relations.  */
 static void
-setup_reg_class_intersect_union (void)
+setup_reg_class_relations (void)
 {
   int i, cl1, cl2, cl3;
   HARD_REG_SET intersection_set, union_set, temp_set2;
+  bool important_class_p[N_REG_CLASSES];
 
+  memset (important_class_p, 0, sizeof (important_class_p));
+  for (i = 0; i < ira_important_classes_num; i++)
+    important_class_p[ira_important_classes[i]] = true;
   for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
     {
+      ira_reg_class_super_classes[cl1][0] = LIM_REG_CLASSES;
       for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
        {
+         ira_reg_classes_intersect_p[cl1][cl2] = false;
          ira_reg_class_intersect[cl1][cl2] = NO_REGS;
          COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl1]);
          AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
@@ -882,6 +982,19 @@ setup_reg_class_intersect_union (void)
              ira_reg_class_union[cl1][cl2] = reg_class_subunion[cl1][cl2];
              continue;
            }
+         ira_reg_classes_intersect_p[cl1][cl2]
+           = hard_reg_set_intersect_p (temp_hard_regset, temp_set2);
+         if (important_class_p[cl1] && important_class_p[cl2]
+             && hard_reg_set_subset_p (temp_hard_regset, temp_set2))
+           {
+             enum reg_class *p;
+
+             p = &ira_reg_class_super_classes[cl1][0];
+             while (*p != LIM_REG_CLASSES)
+               p++;
+             *p++ = (enum reg_class) cl2;
+             *p = LIM_REG_CLASSES;
+           }
          ira_reg_class_union[cl1][cl2] = NO_REGS;
          COPY_HARD_REG_SET (intersection_set, reg_class_contents[cl1]);
          AND_HARD_REG_SET (intersection_set, reg_class_contents[cl2]);
@@ -966,12 +1079,9 @@ static void
 find_reg_class_closure (void)
 {
   setup_reg_subclasses ();
-  if (targetm.ira_cover_classes)
-    {
-      setup_cover_and_important_classes ();
-      setup_class_translate ();
-      setup_reg_class_intersect_union ();
-    }
+  setup_cover_and_important_classes ();
+  setup_class_translate ();
+  setup_reg_class_relations ();
 }
 
 \f
@@ -1725,7 +1835,6 @@ ira (FILE *f)
   bool loops_p;
   int max_regno_before_ira, ira_max_point_before_emit;
   int rebuild_p;
-  int saved_flag_ira_algorithm;
   int saved_flag_ira_share_spill_slots;
   basic_block bb;
 
@@ -1801,15 +1910,12 @@ ira (FILE *f)
   ira_assert (current_loops == NULL);
   flow_loops_find (&ira_loops);
   current_loops = &ira_loops;
-  saved_flag_ira_algorithm = flag_ira_algorithm;
-  if (optimize && number_of_loops () > (unsigned) IRA_MAX_LOOPS_NUM)
-    flag_ira_algorithm = IRA_ALGORITHM_CB;
       
   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
     fprintf (ira_dump_file, "Building IRA IR\n");
   loops_p = ira_build (optimize
-                      && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
-                          || flag_ira_algorithm == IRA_ALGORITHM_MIXED));
+                      && (flag_ira_region == IRA_REGION_ALL
+                          || flag_ira_region == IRA_REGION_MIXED));
 
   saved_flag_ira_share_spill_slots = flag_ira_share_spill_slots;
   if (too_high_register_pressure_p ())
@@ -1935,8 +2041,6 @@ ira (FILE *f)
     bb->loop_father = NULL;
   current_loops = NULL;
 
-  flag_ira_algorithm = saved_flag_ira_algorithm;
-
   regstat_free_ri ();
   regstat_free_n_sets_and_refs ();