OSDN Git Service

2009-07-22 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 22:00:17 +0000 (22:00 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 22:00:17 +0000 (22:00 +0000)
PR target/37488
* ira-lives.c (bb_has_abnormal_call_pred): New function.
(process_bb_node_lives): Use it.

* ira.c (setup_cover_and_important_classes): Don't setup
ira_important_class_nums.  Add cover classes to the end of
important classes.
(cover_class_order, comp_reg_classes_func,
reorder_important_classes): New.
(find_reg_class_closure): Use reorder_important_classes.

* config/i386/i386.h (IRA_COVER_CLASSES): Remove.

* config/i386/i386.c (i386_ira_cover_classes): New function.
(TARGET_IRA_COVER_CLASSES): Redefine.

* doc/tm.texi (TARGET_IRA_COVER_CLASSES): Add a comment about
importance of order of cover classes in the array.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149962 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/doc/tm.texi
gcc/ira-lives.c
gcc/ira.c

index 7f3f756..774c458 100644 (file)
@@ -1,3 +1,24 @@
+2009-07-22  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/37488
+       * ira-lives.c (bb_has_abnormal_call_pred): New function.
+       (process_bb_node_lives): Use it.
+
+       * ira.c (setup_cover_and_important_classes): Don't setup
+       ira_important_class_nums.  Add cover classes to the end of
+       important classes.
+       (cover_class_order, comp_reg_classes_func,
+       reorder_important_classes): New.
+       (find_reg_class_closure): Use reorder_important_classes.
+
+       * config/i386/i386.h (IRA_COVER_CLASSES): Remove.
+
+       * config/i386/i386.c (i386_ira_cover_classes): New function.
+       (TARGET_IRA_COVER_CLASSES): Redefine.
+
+       * doc/tm.texi (TARGET_IRA_COVER_CLASSES): Add a comment about
+       importance of order of cover classes in the array.
+       
 2009-07-22  Diego Novillo  <dnovillo@google.com>
 
        * tree-pass.h (TDF_EH): Define.
index 463d43e..c11c34a 100644 (file)
@@ -26132,6 +26132,22 @@ ix86_free_from_memory (enum machine_mode mode)
     }
 }
 
+/* Implement TARGET_IRA_COVER_CLASSES.  If -mfpmath=sse, we prefer
+   SSE_REGS to FLOAT_REGS if their costs for a pseudo are the
+   same.  */
+static const enum reg_class *
+i386_ira_cover_classes (void)
+{
+  static const enum reg_class sse_fpmath_classes[] = {
+    GENERAL_REGS, SSE_REGS, MMX_REGS, FLOAT_REGS, LIM_REG_CLASSES
+  };
+  static const enum reg_class no_sse_fpmath_classes[] = {
+    GENERAL_REGS, FLOAT_REGS, MMX_REGS, SSE_REGS, LIM_REG_CLASSES
+  };
+
+ return TARGET_SSE_MATH ? sse_fpmath_classes : no_sse_fpmath_classes;
+}
+
 /* Put float CONST_DOUBLE in the constant pool instead of fp regs.
    QImode must go into class Q_REGS.
    Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
@@ -30652,6 +30668,9 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
 
+#undef TARGET_IRA_COVER_CLASSES
+#define TARGET_IRA_COVER_CLASSES i386_ira_cover_classes
+
 #undef TARGET_FRAME_POINTER_REQUIRED
 #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
 
index f9b9dd1..15ac4d3 100644 (file)
@@ -1288,19 +1288,6 @@ enum reg_class
 { 0xffffffff,0x1fffff }                                                        \
 }
 
-/* The following macro defines cover classes for Integrated Register
-   Allocator.  Cover classes is a set of non-intersected register
-   classes covering all hard registers used for register allocation
-   purpose.  Any move between two registers of a cover class should be
-   cheaper than load or store of the registers.  The macro value is
-   array of register classes with LIM_REG_CLASSES used as the end
-   marker.  */
-
-#define IRA_COVER_CLASSES                                                   \
-{                                                                           \
-  GENERAL_REGS, FLOAT_REGS, MMX_REGS, SSE_REGS, LIM_REG_CLASSES                     \
-}
-
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
index 41ed031..8157714 100644 (file)
@@ -2913,6 +2913,10 @@ purposes.  If a move between two registers in the same cover class is
 possible, it should be cheaper than a load or store of the registers.
 The array is terminated by a @code{LIM_REG_CLASSES} element.
 
+The order of cover classes in the array is important.  If two classes
+have the same cost of usage for a pseudo, the class occurred first in
+the array is chosen for the pseudo.
+
 This hook is called once at compiler startup, after the command-line
 options have been processed. It is then re-examined by every call to
 @code{target_reinit}.
index 0812c84..c010f67 100644 (file)
@@ -814,6 +814,22 @@ process_single_reg_class_operands (bool in_p, int freq)
     }
 }
 
+/* Return true when one of the predecessor edges of BB is marked with
+   EDGE_ABNORMAL_CALL or EDGE_EH.  */
+static bool
+bb_has_abnormal_call_pred (basic_block bb)
+{
+  edge e;
+  edge_iterator ei;
+  
+  FOR_EACH_EDGE (e, ei, bb->preds)
+    {
+      if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
+       return true;
+    }
+  return false;
+}
+
 /* Process insns of the basic block given by its LOOP_TREE_NODE to
    update allocno live ranges, allocno hard register conflicts,
    intersected calls, and register pressure info for allocnos for the
@@ -1062,7 +1078,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
          /* No need to record conflicts for call clobbered regs if we
             have nonlocal labels around, as we don't ever try to
             allocate such regs in this case.  */
-         if (!cfun->has_nonlocal_label)
+         if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb))
            for (px = 0; px < FIRST_PSEUDO_REGISTER; px++)
              if (call_used_regs[px])
                make_regno_born (px);
index 7a2efe9..e4caf31 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -729,7 +729,7 @@ static void
 setup_cover_and_important_classes (void)
 {
   int i, j, n, cl;
-  bool set_p, eq_p;
+  bool set_p;
   const enum reg_class *cover_classes;
   HARD_REG_SET temp_hard_regset2;
   static enum reg_class classes[LIM_REG_CLASSES + 1];
@@ -802,7 +802,7 @@ setup_cover_and_important_classes (void)
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
       if (! hard_reg_set_empty_p (temp_hard_regset))
        {
-         set_p = eq_p = false;
+         set_p = false;
          for (j = 0; j < ira_reg_class_cover_size; j++)
            {
              COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
@@ -810,27 +810,22 @@ setup_cover_and_important_classes (void)
              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 ((enum reg_class) 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;
+             if ((enum reg_class) cl == ira_reg_class_cover[j]
+                 || hard_reg_set_equal_p (temp_hard_regset,
+                                          temp_hard_regset2))
+               break;
              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++] =
-               (enum reg_class) cl;
-           }
+         if (set_p && j >= ira_reg_class_cover_size)
+           ira_important_classes[ira_important_classes_num++]
+             = (enum reg_class) cl;
        }
     }
+  for (j = 0; j < ira_reg_class_cover_size; j++)
+    ira_important_classes[ira_important_classes_num++]
+      = ira_reg_class_cover[j];
 }
 
 /* Map of all register classes to corresponding cover class containing
@@ -925,6 +920,43 @@ setup_class_translate (void)
     }
 }
 
+/* Order numbers of cover classes in original target cover class
+   array, -1 for non-cover classes.  */ 
+static int cover_class_order[N_REG_CLASSES];
+
+/* The function used to sort the important classes.  */
+static int
+comp_reg_classes_func (const void *v1p, const void *v2p)
+{
+  enum reg_class cl1 = *(const enum reg_class *) v1p;
+  enum reg_class cl2 = *(const enum reg_class *) v2p;
+  int diff;
+
+  cl1 = ira_class_translate[cl1];
+  cl2 = ira_class_translate[cl2];
+  if (cl1 != NO_REGS && cl2 != NO_REGS
+      && (diff = cover_class_order[cl1] - cover_class_order[cl2]) != 0)
+    return diff;
+  return (int) cl1 - (int) cl2;
+}
+
+/* Reorder important classes according to the order of their cover
+   classes.  Set up array ira_important_class_nums too.  */
+static void
+reorder_important_classes (void)
+{
+  int i;
+
+  for (i = 0; i < N_REG_CLASSES; i++)
+    cover_class_order[i] = -1;
+  for (i = 0; i < ira_reg_class_cover_size; i++)
+    cover_class_order[ira_reg_class_cover[i]] = i;
+  qsort (ira_important_classes, ira_important_classes_num,
+        sizeof (enum reg_class), comp_reg_classes_func);
+  for (i = 0; i < ira_important_classes_num; i++)
+    ira_important_class_nums[ira_important_classes[i]] = i;
+}
+
 /* The biggest important reg_class inside of intersection of the two
    reg_classes (that is calculated taking only hard registers
    available for allocation into account).  If the both reg_classes
@@ -1089,6 +1121,7 @@ find_reg_class_closure (void)
   setup_reg_subclasses ();
   setup_cover_and_important_classes ();
   setup_class_translate ();
+  reorder_important_classes ();
   setup_reg_class_relations ();
 }