[multiple changes]
authorJeff Law <law@gcc.gnu.org>
Fri, 5 Nov 1999 08:31:48 +0000 (01:31 -0700)
committerJeff Law <law@gcc.gnu.org>
Fri, 5 Nov 1999 08:31:48 +0000 (01:31 -0700)
Fri Nov  5 01:24:37 1999  J"orn Rennecke <amylaar@cygnus.co.uk>

        * global.c (CONFLICTP, SET_CONFLICT): Avoid signed division.
        (mirror_conflicts): New function.
        (global_alloc): Call it.
        (expand_preferences): Remove redundant CONFLICTP test.
        (find_reg, dump_conflicts): Likewise.
        (prune_preferences): Process conflicts one word at a time.

Fri Nov  5 01:05:21 1999  Richard Henderson <rth@cygnus.com>

        * global.c (build_insn_chain): Use EXECUTE_IF_SET_IN_BITMAP
        instead of an explicit loop.

From-SVN: r30407

gcc/ChangeLog
gcc/global.c

index a5dec539d2abdf76a946ddbbcf65fc2d45d69d74..f0774977c501f57fc81ea43eb0abf1fbc9518f56 100644 (file)
@@ -1,3 +1,17 @@
+Fri Nov  5 01:24:37 1999  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * global.c (CONFLICTP, SET_CONFLICT): Avoid signed division.
+       (mirror_conflicts): New function.
+       (global_alloc): Call it.
+       (expand_preferences): Remove redundant CONFLICTP test.
+       (find_reg, dump_conflicts): Likewise.
+       (prune_preferences): Process conflicts one word at a time.
+
+Fri Nov  5 01:05:21 1999  Richard Henderson <rth@cygnus.com>
+
+       * global.c (build_insn_chain): Use EXECUTE_IF_SET_IN_BITMAP
+       instead of an explicit loop.
+
 Thu Nov  4 23:07:14 1999  Jim Wilson  <wilson@cygnus.com>
 
        * cse.c (cse_insn): Revert Oct 31 change.  When computing src_elt,
index 2e460265a95b4958465e17b0a996121496c45aa2..3cb6b34ef252f4d8a2fc69b544f86c462b1354e0 100644 (file)
@@ -114,8 +114,7 @@ static int *reg_may_share;
    recording whether two allocno's conflict (can't go in the same
    hardware register).
 
-   `conflicts' is not symmetric; a conflict between allocno's i and j
-   is recorded either in element i,j or in element j,i.  */
+   `conflicts' is symmetric after the call to mirror_conflicts.  */
 
 static INT_TYPE *conflicts;
 
@@ -127,12 +126,18 @@ static int allocno_row_words;
 /* Two macros to test or store 1 in an element of `conflicts'.  */
 
 #define CONFLICTP(I, J) \
- (conflicts[(I) * allocno_row_words + (J) / INT_BITS]  \
-  & ((INT_TYPE) 1 << ((J) % INT_BITS)))
+ (conflicts[(I) * allocno_row_words + (unsigned)(J) / INT_BITS]        \
+  & ((INT_TYPE) 1 << ((unsigned)(J) % INT_BITS)))
 
 #define SET_CONFLICT(I, J) \
- (conflicts[(I) * allocno_row_words + (J) / INT_BITS]  \
-  |= ((INT_TYPE) 1 << ((J) % INT_BITS)))
+ (conflicts[(I) * allocno_row_words + (unsigned)(J) / INT_BITS]        \
+  |= ((INT_TYPE) 1 << ((unsigned)(J) % INT_BITS)))
+
+/* CYGNUS LOCAL LRS */
+#define CLEAR_CONFLICT(I, J) \
+ (conflicts[(I) * allocno_row_words + (J) / INT_BITS]   \
+  &= ~ ((INT_TYPE) 1 << ((J) % INT_BITS)))
+/* END CYGNUS LOCAL */
 
 /* Set of hard regs currently live (during scan of all insns).  */
 
@@ -259,6 +264,7 @@ static HARD_REG_SET eliminable_regset;
 
 static int allocno_compare     PROTO((const PTR, const PTR));
 static void global_conflicts   PROTO((void));
+static void mirror_conflicts   PROTO((void));
 static void expand_preferences PROTO((void));
 static void prune_preferences  PROTO((void));
 static void find_reg           PROTO((int, HARD_REG_SET, int, int, int));
@@ -486,6 +492,8 @@ global_alloc (file)
 
       global_conflicts ();
 
+      mirror_conflicts ();
+
       /* Eliminate conflicts between pseudos and eliminable registers.  If
         the register is not eliminated, the pseudo won't really be able to
         live in the eliminable register, so the conflict doesn't matter.
@@ -818,9 +826,7 @@ expand_preferences ()
            && GET_CODE (XEXP (link, 0)) == REG
            && reg_allocno[REGNO (XEXP (link, 0))] >= 0
            && ! CONFLICTP (reg_allocno[REGNO (SET_DEST (set))],
-                           reg_allocno[REGNO (XEXP (link, 0))])
-           && ! CONFLICTP (reg_allocno[REGNO (XEXP (link, 0))],
-                           reg_allocno[REGNO (SET_DEST (set))]))
+                           reg_allocno[REGNO (XEXP (link, 0))]))
          {
            int a1 = reg_allocno[REGNO (SET_DEST (set))];
            int a2 = reg_allocno[REGNO (XEXP (link, 0))];
@@ -856,6 +862,7 @@ prune_preferences ()
 {
   int i, j;
   int allocno;
+  int *allocno_to_order = (int *) xmalloc (max_allocno * sizeof (int));
   
   /* Scan least most important to most important.
      For each allocno, remove from preferences registers that cannot be used,
@@ -864,9 +871,10 @@ prune_preferences ()
 
   for (i = max_allocno - 1; i >= 0; i--)
     {
-      HARD_REG_SET temp, temp2;
+      HARD_REG_SET temp;
 
       allocno = allocno_order[i];
+      allocno_to_order[allocno] = i;
       COPY_HARD_REG_SET (temp, hard_reg_conflicts[allocno]);
 
       if (allocno_calls_crossed[allocno] == 0)
@@ -881,29 +889,49 @@ prune_preferences ()
       AND_COMPL_HARD_REG_SET (hard_reg_preferences[allocno], temp);
       AND_COMPL_HARD_REG_SET (hard_reg_copy_preferences[allocno], temp);
       AND_COMPL_HARD_REG_SET (hard_reg_full_preferences[allocno], temp);
+    }
 
+  for (i = max_allocno - 1; i >= 0; i--)
+    {
       /* Merge in the preferences of lower-priority registers (they have
         already been pruned).  If we also prefer some of those registers,
         don't exclude them unless we are of a smaller size (in which case
         we want to give the lower-priority allocno the first chance for
         these registers).  */
+      HARD_REG_SET temp, temp2;
+      INT_TYPE *p;
+      int allocno2, allocno3;
+
+      allocno = allocno_order[i];
+      p = conflicts + allocno * allocno_row_words;
+
       CLEAR_HARD_REG_SET (temp);
       CLEAR_HARD_REG_SET (temp2);
-      for (j = i + 1; j < max_allocno; j++)
-       if (CONFLICTP (allocno, allocno_order[j])
-           || CONFLICTP (allocno_order[j], allocno))
-         {
-           if (allocno_size[allocno_order[j]] <= allocno_size[allocno])
-             IOR_HARD_REG_SET (temp,
-                               hard_reg_full_preferences[allocno_order[j]]);
-           else
-             IOR_HARD_REG_SET (temp2,
-                               hard_reg_full_preferences[allocno_order[j]]);
-         }
+
+      for (j = allocno_row_words - 1, allocno2 = 0; j >= 0;
+          j--, allocno2 += INT_BITS)
+       {
+         unsigned INT_TYPE word = (unsigned INT_TYPE) *p++;
+
+         for (allocno3 = allocno2; word; word >>= 1, allocno3++)
+           {
+             if ((word & 1) && allocno_to_order[allocno3] > i)
+               {
+                 if (allocno_size[allocno3] <= allocno_size[allocno])
+                   IOR_HARD_REG_SET (temp,
+                                     hard_reg_full_preferences[allocno3]);
+                 else
+                   IOR_HARD_REG_SET (temp2,
+                                     hard_reg_full_preferences[allocno3]);
+               }
+           }
+       }
+
       AND_COMPL_HARD_REG_SET (temp, hard_reg_full_preferences[allocno]);
       IOR_HARD_REG_SET (temp, temp2);
       COPY_HARD_REG_SET (regs_someone_prefers[allocno], temp);
     }
+  free (allocno_to_order);
 }
 \f
 /* Assign a hard register to ALLOCNO; look for one that is the beginning
@@ -1219,7 +1247,7 @@ find_reg (allocno, losers, alt_regs_p, accept_call_clobbered, retrying)
         mark it as conflicting with the hard regs this one occupies.  */
       lim = allocno;
       for (j = 0; j < max_allocno; j++)
-       if (CONFLICTP (lim, j) || CONFLICTP (j, lim))
+       if (CONFLICTP (j, lim))
          {
            IOR_HARD_REG_SET (hard_reg_conflicts[j], this_reg);
          }
@@ -1327,6 +1355,38 @@ record_conflicts (allocno_vec, len)
        conflicts[ialloc_prod + j] |= allocnos_live[j];
     }
 }
+
+/* If CONFLICTP (i, j) is true, make sure CONFLICTP (j, i) is also true.  */
+static void
+mirror_conflicts ()
+{
+  register int i, j;
+  int rw = allocno_row_words;
+  int rwb = rw * INT_BITS;
+  INT_TYPE *p = conflicts;
+  INT_TYPE *q0 = conflicts, *q1, *q2;
+  unsigned INT_TYPE mask;
+
+  for (i = max_allocno - 1, mask = 1; i >= 0; i--, mask <<= 1)
+    {
+      if (! mask)
+       {
+         mask = 1;
+         q0++;
+       }
+      for (j = allocno_row_words - 1, q1 = q0; j >= 0; j--, q1 += rwb)
+       {
+         unsigned INT_TYPE word;
+
+         for (word = (unsigned INT_TYPE) *p++, q2 = q1; word;
+              word >>= 1, q2 += rw)
+           {
+             if (word & 1)
+               *q2 |= mask;
+           }
+       }
+    }
+}
 \f
 /* Handle the case where REG is set by the insn being scanned,
    during the forward scan to accumulate conflicts.
@@ -1689,17 +1749,18 @@ build_insn_chain (first)
       if (first == BLOCK_HEAD (b))
        {
          int i;
+
          CLEAR_REG_SET (live_relevant_regs);
-         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-           if (REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start, i)
-               && ! TEST_HARD_REG_BIT (eliminable_regset, i))
-             SET_REGNO_REG_SET (live_relevant_regs, i);
-
-         for (; i < max_regno; i++)
-           if (reg_renumber[i] >= 0
-               && REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start, i))
-             SET_REGNO_REG_SET (live_relevant_regs, i);
-       }
+
+         EXECUTE_IF_SET_IN_BITMAP
+           (BASIC_BLOCK (b)->global_live_at_start, 0, i,
+            {
+              if (i < FIRST_PSEUDO_REGISTER
+                  ? ! TEST_HARD_REG_BIT (eliminable_regset, i)
+                  : reg_renumber[i] >= 0)
+                SET_REGNO_REG_SET (live_relevant_regs, i);
+            });
+       }
 
       if (GET_CODE (first) != NOTE && GET_CODE (first) != BARRIER)
        {
@@ -1805,7 +1866,7 @@ dump_conflicts (file)
       register int j;
       fprintf (file, ";; %d conflicts:", allocno_reg[i]);
       for (j = 0; j < max_allocno; j++)
-       if (CONFLICTP (i, j) || CONFLICTP (j, i))
+       if (CONFLICTP (j, i))
          fprintf (file, " %d", allocno_reg[j]);
       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
        if (TEST_HARD_REG_BIT (hard_reg_conflicts[i], j))