OSDN Git Service

* reg-stack.c (change_stack): Avoid placing the new top-of-stack in
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 12 Dec 2004 01:41:27 +0000 (01:41 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 12 Dec 2004 01:41:27 +0000 (01:41 +0000)
its correct location during popping if we need to permute the stack
afterwards.  Attempt to preserve the original stack ordering.

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

gcc/ChangeLog
gcc/reg-stack.c

index c828107..c2e5865 100644 (file)
@@ -1,3 +1,9 @@
+2004-12-11  Roger Sayle  <roger@eyesopen.com>
+
+       * reg-stack.c (change_stack): Avoid placing the new top-of-stack in
+       its correct location during popping if we need to permute the stack
+       afterwards.  Attempt to preserve the original stack ordering.
+
 2004-12-12  Kazu Hirata  <kazu@cs.umass.edu>
 
        * lcm.c (optimize_mode_switching): Free insert and delete in
index 11dd849..2ba963e 100644 (file)
@@ -2374,13 +2374,14 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
     {
       bool slots[REG_STACK_SIZE];
       int pops[REG_STACK_SIZE];
-      int next, dest;
+      int next, dest, topsrc;
 
       /* First pass to determine the free slots.  */
       for (reg = 0; reg <= new->top; reg++)
        slots[reg] = TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]);
 
       /* Second pass to allocate preferred slots.  */
+      topsrc = -1;
       for (reg = old->top; reg > new->top; reg--)
        if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
          {
@@ -2388,6 +2389,10 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
            for (next = 0; next <= new->top; next++)
              if (!slots[next] && new->reg[next] == old->reg[reg])
                {
+                 /* If this is a preference for the new top of stack, record
+                    the fact by remembering it's old->reg in topsrc.  */
+                  if (next == new->top)
+                   topsrc = reg;
                  slots[next] = true;
                  dest = next;
                  break;
@@ -2397,8 +2402,23 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
        else
          pops[reg] = reg;
 
+      /* Intentionally, avoid placing the top of stack in it's correct
+        location, if we still need to permute the stack below and we
+        can usefully place it somewhere else.  This is the case if any
+        slot is still unallocated, in which case we should place the
+        top of stack there.  */
+      if (topsrc != -1)
+       for (reg = 0; reg < new->top; reg++)
+         if (!slots[reg])
+           {
+             pops[topsrc] = reg;
+             slots[new->top] = false;
+             slots[reg] = true;
+             break;
+           }
+
       /* Third pass allocates remaining slots and emits pop insns.  */
-      next = 0;
+      next = new->top;
       for (reg = old->top; reg > new->top; reg--)
        {
          dest = pops[reg];
@@ -2406,27 +2426,38 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
            {
              /* Find next free slot.  */
              while (slots[next])
-               next++;
-             dest = next++;
+               next--;
+             dest = next--;
            }
          emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], DFmode),
                         EMIT_BEFORE);
        }
     }
   else
-    /* The following loop attempts to maximize the number of times we
-       pop the top of the stack, as this permits the use of the faster
-       ffreep instruction on platforms that support it.  */
-    for (reg = 0; reg <= old->top; reg++)
-      if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
-       {
-         while (old->top > reg
-                && ! TEST_HARD_REG_BIT (new->reg_set, old->reg[old->top]))
-           emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], DFmode),
+    {
+      /* The following loop attempts to maximize the number of times we
+        pop the top of the stack, as this permits the use of the faster
+        ffreep instruction on platforms that support it.  */
+      int live, next;
+
+      live = 0;
+      for (reg = 0; reg <= old->top; reg++)
+        if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
+          live++;
+
+      next = live;
+      while (old->top >= live)
+        if (TEST_HARD_REG_BIT (new->reg_set, old->reg[old->top]))
+         {
+           while (TEST_HARD_REG_BIT (new->reg_set, old->reg[next]))
+             next--;
+           emit_pop_insn (insn, old, FP_MODE_REG (old->reg[next], DFmode),
                           EMIT_BEFORE);
-         emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode),
+         }
+       else
+         emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], DFmode),
                         EMIT_BEFORE);
-       }
+    }
 
   if (new->top == -2)
     {