global.c (build_insn_chain): Use EXECUTE_IF_SET_IN_REG_SET to invert loops.
authorRichard Henderson <rth@cygnus.com>
Sat, 7 Aug 1999 17:05:46 +0000 (10:05 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 7 Aug 1999 17:05:46 +0000 (10:05 -0700)
        * global.c (build_insn_chain): Use EXECUTE_IF_SET_IN_REG_SET
        to invert loops.  Simplify block scanning.

From-SVN: r28583

gcc/ChangeLog
gcc/global.c

index a9ef4a6302329b7d1b65288740301944ca07773b..d3715d620a3ae7da53ce84a49cd4d5dec16dd22d 100644 (file)
@@ -1,3 +1,8 @@
+Sat Aug  7 17:09:36 1999  Richard Henderson  <rth@cygnus.com>
+
+       * global.c (build_insn_chain): Use EXECUTE_IF_SET_IN_REG_SET
+       to invert loops.  Simplify block scanning.
+
 Sat Aug  7 02:11:13 1999  Bernd Schmidt <bernds@cygnus.co.uk>
 
        * gcse.c (hash_scan_set): Treat SYMBOL_REFs like CONST_INTs.
index 3a98f590ffc82378412fa37211b6d6c804941e49..138b32b6a3195d7f74d8efa3b58a0e3f72fca49c 100644 (file)
@@ -271,7 +271,7 @@ static void set_preference  PROTO((rtx, rtx));
 static void dump_conflicts     PROTO((FILE *));
 static void reg_becomes_live   PROTO((rtx, rtx));
 static void reg_dies           PROTO((int, enum machine_mode));
-static void build_insn_chain   PROTO((rtx));
+static void build_insn_chain   PROTO((void));
 \f
 /* Perform allocation of pseudo-registers not allocated by local_alloc.
    FILE is a file to output debugging information on,
@@ -578,7 +578,7 @@ global_alloc (file)
   if (n_basic_blocks > 0)
 #endif
     {
-      build_insn_chain (get_insns ());
+      build_insn_chain ();
       retval = reload (get_insns (), 1, file);
     }
 
@@ -1667,96 +1667,88 @@ reg_dies (regno, mode)
 /* Walk the insns of the current function and build reload_insn_chain,
    and record register life information.  */
 static void
-build_insn_chain (first)
-     rtx first;
+build_insn_chain ()
 {
   struct insn_chain **p = &reload_insn_chain;
   struct insn_chain *prev = 0;
-  int b = 0;
+  int b;
 
   live_relevant_regs = ALLOCA_REG_SET ();
 
-  for (; first; first = NEXT_INSN (first))
+  for (b = n_basic_blocks - 1; b >= 0; --b)
     {
-      struct insn_chain *c;
+      basic_block bb = BASIC_BLOCK (b);
+      rtx insn, end;
+      int i;
 
-      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);
-       }
+      CLEAR_REG_SET (live_relevant_regs);
 
-      if (GET_CODE (first) != NOTE && GET_CODE (first) != BARRIER)
+      EXECUTE_IF_SET_IN_REG_SET (bb->global_live_at_start, 0, i,
        {
-         c = new_insn_chain ();
-         c->prev = prev;
-         prev = c;
-         *p = c;
-         p = &c->next;
-         c->insn = first;
-         c->block = b;
-
-         COPY_REG_SET (c->live_before, live_relevant_regs);
+         if ((i < FIRST_PSEUDO_REGISTER
+              && ! TEST_HARD_REG_BIT (eliminable_regset, i))
+             || (i >= FIRST_PSEUDO_REGISTER
+                 && reg_renumber[i] >= 0))
+           SET_REGNO_REG_SET (live_relevant_regs, i);
+       });
+
+      insn = bb->head, end = bb->end;
+      while (1)
+       {
+         struct insn_chain *c;
 
-         if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
+         if (GET_CODE (insn) != NOTE)
            {
-             rtx link;
-
-             /* Mark the death of everything that dies in this instruction.  */
+             c = new_insn_chain ();
+             c->prev = prev;
+             prev = c;
+             *p = c;
+             p = &c->next;
+             c->insn = insn;
+             c->block = b;
 
-             for (link = REG_NOTES (first); link; link = XEXP (link, 1))
-               if (REG_NOTE_KIND (link) == REG_DEAD
-                   && GET_CODE (XEXP (link, 0)) == REG)
-                 reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)));
+             COPY_REG_SET (c->live_before, live_relevant_regs);
 
-             /* Mark everything born in this instruction as live.  */
-
-             note_stores (PATTERN (first), reg_becomes_live);
-           }
-
-         /* Remember which registers are live at the end of the insn, before
-            killing those with REG_UNUSED notes.  */
-         COPY_REG_SET (c->live_after, live_relevant_regs);
-
-         if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
-           {
-             rtx link;
+             if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+               {
+                 rtx link;
+
+                 /* Mark the death of everything that dies in this
+                    instruction.  */
+                 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+                   if (REG_NOTE_KIND (link) == REG_DEAD
+                       && GET_CODE (XEXP (link, 0)) == REG)
+                     reg_dies (REGNO (XEXP (link, 0)),
+                               GET_MODE (XEXP (link, 0)));
+
+                 /* Mark everything born in this instruction as live.  */
+                 note_stores (PATTERN (insn), reg_becomes_live);
+               }
 
-             /* Mark anything that is set in this insn and then unused as dying.  */
+             /* Remember which registers are live at the end of the insn,
+                before killing those with REG_UNUSED notes.  */
+             COPY_REG_SET (c->live_after, live_relevant_regs);
 
-             for (link = REG_NOTES (first); link; link = XEXP (link, 1))
-               if (REG_NOTE_KIND (link) == REG_UNUSED
-                   && GET_CODE (XEXP (link, 0)) == REG)
-                 reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)));
+             if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+               {
+                 rtx link;
+
+                 /* Mark anything that is set in this insn and then unused
+                    as dying.  */
+                 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+                   if (REG_NOTE_KIND (link) == REG_UNUSED
+                       && GET_CODE (XEXP (link, 0)) == REG)
+                     reg_dies (REGNO (XEXP (link, 0)),
+                               GET_MODE (XEXP (link, 0)));
+               }
            }
-       }
-
-      if (first == BLOCK_END (b))
-       b++;
 
-      /* Stop after we pass the end of the last basic block.  Verify that
-        no real insns are after the end of the last basic block.
-
-        We may want to reorganize the loop somewhat since this test should
-        always be the right exit test.  */
-      if (b == n_basic_blocks)
-       {
-         for (first = NEXT_INSN (first) ; first; first = NEXT_INSN (first))
-           if (GET_RTX_CLASS (GET_CODE (first)) == 'i'
-               && GET_CODE (PATTERN (first)) != USE)
-             abort ();
-         break;
+         if (insn == end)
+           break;
+         insn = NEXT_INSN (insn);
        }
     }
+
   FREE_REG_SET (live_relevant_regs);
   *p = 0;
 }