]> gcc.gnu.org Git - gcc.git/commitdiff
ira.h (target_ira): Add x_ira_class_singleton.
authorRichard Sandiford <rdsandiford@googlemail.com>
Tue, 2 Oct 2012 19:34:38 +0000 (19:34 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 2 Oct 2012 19:34:38 +0000 (19:34 +0000)
gcc/
* ira.h (target_ira): Add x_ira_class_singleton.
(ira_class_singleton): New macro.
* ira.c (setup_prohibited_class_mode_regs): Set up ira_class_singleton.
* ira-build.c (update_conflict_hard_reg_costs): Use
ira_class_singleton to check for classes with a single
allocatable register.
* ira-lives.c (ira_implicitly_set_insn_hard_regs): Likewise.
(single_reg_class): Likewise.  When more than one class is specified,
check whether they have the same singleton register.
(process_single_reg_class_operands): Require single_reg_class
to return NO_REGS or a class with a single allocatable register.
Obtain that register from ira_class_singleton.

From-SVN: r191995

gcc/ChangeLog
gcc/ira-build.c
gcc/ira-lives.c
gcc/ira.c
gcc/ira.h

index 0a6a13953fb9aed5ff7b41439638c3e1e0afc4f7..ad6c14bac818ca27288795def10d8a1e1f476fbd 100644 (file)
@@ -1,3 +1,18 @@
+2012-10-02  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * ira.h (target_ira): Add x_ira_class_singleton.
+       (ira_class_singleton): New macro.
+       * ira.c (setup_prohibited_class_mode_regs): Set up ira_class_singleton.
+       * ira-build.c (update_conflict_hard_reg_costs): Use
+       ira_class_singleton to check for classes with a single
+       allocatable register.
+       * ira-lives.c (ira_implicitly_set_insn_hard_regs): Likewise.
+       (single_reg_class): Likewise.  When more than one class is specified,
+       check whether they have the same singleton register.
+       (process_single_reg_class_operands): Require single_reg_class
+       to return NO_REGS or a class with a single allocatable register.
+       Obtain that register from ira_class_singleton.
+
 2012-10-02  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000.c (rs6000_option_override_internal): If
index dba1d467ad7d8db35639e6b620e0d63a12d49f80..1181813d92b98ffa529f19c18e51daecedea5f3c 100644 (file)
@@ -3047,11 +3047,10 @@ update_conflict_hard_reg_costs (void)
     {
       reg_class_t aclass = ALLOCNO_CLASS (a);
       reg_class_t pref = reg_preferred_class (ALLOCNO_REGNO (a));
-
-      if (reg_class_size[(int) pref] != 1)
+      int singleton = ira_class_singleton[pref][ALLOCNO_MODE (a)];
+      if (singleton < 0)
        continue;
-      index = ira_class_hard_reg_index[(int) aclass]
-                                     [ira_class_hard_regs[(int) pref][0]];
+      index = ira_class_hard_reg_index[(int) aclass][singleton];
       if (index < 0)
        continue;
       if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) == NULL
index 0de1b81b73faf73211d7b0c7d1aa95e401c05d5a..853832e3c9faefacda22d746de84be6dc697ff5f 100644 (file)
@@ -849,9 +849,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
          next_cl = (c == 'r'
                     ? GENERAL_REGS
                     : REG_CLASS_FROM_CONSTRAINT (c, constraints));
-         if ((cl != NO_REGS && next_cl != cl)
-             || (ira_class_hard_regs_num[next_cl]
-                 > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
+         if (cl == NO_REGS
+             ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
+             : (ira_class_singleton[cl][GET_MODE (op)]
+                != ira_class_singleton[next_cl][GET_MODE (op)]))
            return NO_REGS;
          cl = next_cl;
          break;
@@ -861,10 +862,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
          next_cl
            = single_reg_class (recog_data.constraints[c - '0'],
                                recog_data.operand[c - '0'], NULL_RTX);
-         if ((cl != NO_REGS && next_cl != cl)
-             || next_cl == NO_REGS
-             || (ira_class_hard_regs_num[next_cl]
-                 > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
+         if (cl == NO_REGS
+             ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
+             : (ira_class_singleton[cl][GET_MODE (op)]
+                != ira_class_singleton[next_cl][GET_MODE (op)]))
            return NO_REGS;
          cl = next_cl;
          break;
@@ -939,13 +940,14 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
                  cl = (c == 'r'
                        ? GENERAL_REGS
                        : REG_CLASS_FROM_CONSTRAINT (c, p));
-                 if (cl != NO_REGS
+                 if (cl != NO_REGS)
+                   {
                      /* There is no register pressure problem if all of the
                         regs in this class are fixed.  */
-                     && ira_class_hard_regs_num[cl] != 0
-                     && (ira_class_hard_regs_num[cl]
-                         <= ira_reg_class_max_nregs[cl][mode]))
-                   IOR_HARD_REG_SET (*set, reg_class_contents[cl]);
+                     int regno = ira_class_singleton[cl][mode];
+                     if (regno >= 0)
+                       add_to_hard_reg_set (set, mode, regno);
+                   }
                  break;
                }
        }
@@ -989,8 +991,7 @@ process_single_reg_class_operands (bool in_p, int freq)
 
          operand_a = ira_curr_regno_allocno_map[regno];
          aclass = ALLOCNO_CLASS (operand_a);
-         if (ira_class_subset_p[cl][aclass]
-             && ira_class_hard_regs_num[cl] != 0)
+         if (ira_class_subset_p[cl][aclass])
            {
              /* View the desired allocation of OPERAND as:
 
@@ -1004,7 +1005,8 @@ process_single_reg_class_operands (bool in_p, int freq)
              HOST_WIDE_INT offset;
 
              xmode = recog_data.operand_mode[i];
-             xregno = ira_class_hard_regs[cl][0];
+             xregno = ira_class_singleton[cl][xmode];
+             gcc_assert (xregno >= 0);
              ymode = ALLOCNO_MODE (operand_a);
              offset = subreg_lowpart_offset (ymode, xmode);
              yregno = simplify_subreg_regno (xregno, xmode, offset, ymode);
index ad0ae0a8e6efc184d6e202073e79e86aaacb2c93..8436f606d97800a00eae9e914514688c4d61fe44 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1451,16 +1451,21 @@ setup_reg_class_nregs (void)
 
 \f
 
-/* Set up IRA_PROHIBITED_CLASS_MODE_REGS.  */
+/* Set up IRA_PROHIBITED_CLASS_MODE_REGS and IRA_CLASS_SINGLETON.
+   This function is called once IRA_CLASS_HARD_REGS has been initialized.  */
 static void
 setup_prohibited_class_mode_regs (void)
 {
-  int j, k, hard_regno, cl;
+  int j, k, hard_regno, cl, last_hard_regno, count;
 
   for (cl = (int) N_REG_CLASSES - 1; cl >= 0; 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 (j = 0; j < NUM_MACHINE_MODES; j++)
        {
+         count = 0;
+         last_hard_regno = -1;
          CLEAR_HARD_REG_SET (ira_prohibited_class_mode_regs[cl][j]);
          for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
            {
@@ -1468,7 +1473,14 @@ setup_prohibited_class_mode_regs (void)
              if (! HARD_REGNO_MODE_OK (hard_regno, (enum machine_mode) j))
                SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
                                  hard_regno);
+             else if (in_hard_reg_set_p (temp_hard_regset,
+                                         (enum machine_mode) j, hard_regno))
+               {
+                 last_hard_regno = hard_regno;
+                 count++;
+               }
            }
+         ira_class_singleton[cl][j] = (count == 1 ? last_hard_regno : -1);
        }
     }
 }
index d53db4e0cee8511b3b1cee489dbf41ed7d98fa48..6870c4bf3039e570065f77137d689511825b94f2 100644 (file)
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -79,6 +79,10 @@ struct target_ira {
      class.  */
   int x_ira_class_hard_regs_num[N_REG_CLASSES];
 
+  /* If class CL has a single allocatable register of mode M,
+     index [CL][M] gives the number of that register, otherwise it is -1.  */
+  short x_ira_class_singleton[N_REG_CLASSES][MAX_MACHINE_MODE];
+
   /* Function specific hard registers can not be used for the register
      allocation.  */
   HARD_REG_SET x_ira_no_alloc_regs;
@@ -117,6 +121,8 @@ extern struct target_ira *this_target_ira;
   (this_target_ira->x_ira_class_hard_regs)
 #define ira_class_hard_regs_num \
   (this_target_ira->x_ira_class_hard_regs_num)
+#define ira_class_singleton \
+  (this_target_ira->x_ira_class_singleton)
 #define ira_no_alloc_regs \
   (this_target_ira->x_ira_no_alloc_regs)
 
This page took 0.120016 seconds and 5 git commands to generate.