OSDN Git Service

* reg-stack.c (propagate_stack): Always copy the source stack to
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 May 2005 15:37:44 +0000 (15:37 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 May 2005 15:37:44 +0000 (15:37 +0000)
the destination.  This routine is now only called when this is safe.
(better_edge): New function split out from convert_regs_1 to
determine which of two edges is better to propagate across.
(convert_regs_1):  We need only search for a best edge if the
stack layout hasn't been defined yet.  Use better_edge to help
find beste.  No longer traverse unnecessary edges.

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

gcc/ChangeLog
gcc/reg-stack.c

index b0a3949..891b283 100644 (file)
@@ -1,3 +1,13 @@
+2005-05-29  Roger Sayle  <roger@eyesopen.com>
+
+       * reg-stack.c (propagate_stack): Always copy the source stack to
+       the destination.  This routine is now only called when this is safe.
+       (better_edge): New function split out from convert_regs_1 to
+       determine which of two edges is better to propagate across.
+       (convert_regs_1):  We need only search for a best edge if the
+       stack layout hasn't been defined yet.  Use better_edge to help
+       find beste.  No longer traverse unnecessary edges.
+
 2005-05-29  Keith Besaw  <kbesaw@us.ibm.com>
 
        * tree-ssa-alias.c (new_type_alias): New procedure to
index 6aaa8be..85fa881 100644 (file)
@@ -2578,28 +2578,22 @@ convert_regs_exit (void)
     }
 }
 
-/* If the stack of the target block hasn't been processed yet,
-   copy the stack info from the source block.  */
+/* Copy the stack info from the end of edge E's source block to the
+   start of E's destination block.  */
 
 static void
 propagate_stack (edge e)
 {
-  basic_block dest = e->dest;
-  stack dest_stack = &BLOCK_INFO (dest)->stack_in;
-
-  if (dest_stack->top == -2)
-    {
-      basic_block src = e->src;
-      stack src_stack = &BLOCK_INFO (src)->stack_out;
-      int reg;
+  stack src_stack = &BLOCK_INFO (e->src)->stack_out;
+  stack dest_stack = &BLOCK_INFO (e->dest)->stack_in;
+  int reg;
 
-      /* Preserve the order of the original stack, but check whether
-        any pops are needed.  */
-      dest_stack->top = -1;
-      for (reg = 0; reg <= src_stack->top; ++reg)
-       if (TEST_HARD_REG_BIT (dest_stack->reg_set, src_stack->reg[reg]))
-         dest_stack->reg[++dest_stack->top] = src_stack->reg[reg];
-    }
+  /* Preserve the order of the original stack, but check whether
+     any pops are needed.  */
+  dest_stack->top = -1;
+  for (reg = 0; reg <= src_stack->top; ++reg)
+    if (TEST_HARD_REG_BIT (dest_stack->reg_set, src_stack->reg[reg]))
+      dest_stack->reg[++dest_stack->top] = src_stack->reg[reg];
 }
 
 
@@ -2738,6 +2732,37 @@ compensate_edges (FILE *file)
   return inserted;
 }
 
+/* Select the better of two edges E1 and E2 to use to determine the
+   stack layout for their shared destination basic block.  This is
+   typically the more frequently executed.  The edge E1 may be NULL
+   (in which case E2 is returned), but E2 is always non-NULL.  */
+
+static edge
+better_edge (edge e1, edge e2)
+{
+  if (!e1)
+    return e2;
+
+  if (EDGE_FREQUENCY (e1) > EDGE_FREQUENCY (e2))
+    return e1;
+  if (EDGE_FREQUENCY (e1) < EDGE_FREQUENCY (e2))
+    return e2;
+
+  if (e1->count > e2->count)
+    return e1;
+  if (e1->count < e2->count)
+    return e2;
+
+  /* Prefer critical edges to minimize inserting compensation code on
+     critical edges.  */
+
+  if (EDGE_CRITICAL_P (e1) != EDGE_CRITICAL_P (e2))
+    return EDGE_CRITICAL_P (e1) ? e1 : e2;
+
+  /* Avoid non-deterministic behaviour.  */
+  return (e1->src->index < e2->src->index) ? e1 : e2;
+}
+
 /* Convert stack register references in one block.  */
 
 static void
@@ -2747,60 +2772,33 @@ convert_regs_1 (FILE *file, basic_block block)
   block_info bi = BLOCK_INFO (block);
   int reg;
   rtx insn, next;
-  edge e, beste = NULL;
   bool control_flow_insn_deleted = false;
-  edge_iterator ei;
 
   any_malformed_asm = false;
 
-  /* Find the edge we will copy stack from.  It should be the most frequent
-     one as it will get cheapest after compensation code is generated,
-     if multiple such exists, take one with largest count, prefer critical
-     one (as splitting critical edges is more expensive), or one with lowest
-     index, to avoid random changes with different orders of the edges.  */
-  FOR_EACH_EDGE (e, ei, block->preds)
-    {
-      if (e->flags & EDGE_DFS_BACK)
-       ;
-      else if (! beste)
-       beste = e;
-      else if (EDGE_FREQUENCY (beste) < EDGE_FREQUENCY (e))
-       beste = e;
-      else if (EDGE_FREQUENCY (beste) > EDGE_FREQUENCY (e))
-       ;
-      else if (beste->count < e->count)
-       beste = e;
-      else if (beste->count > e->count)
-       ;
-      else if ((EDGE_CRITICAL_P (e) != 0)
-              != (EDGE_CRITICAL_P (beste) != 0))
-       {
-         if (EDGE_CRITICAL_P (e))
-           beste = e;
-       }
-      else if (e->src->index < beste->src->index)
-       beste = e;
-    }
-
-  /* Initialize stack at block entry.  */
+  /* Choose an initial stack layout, if one hasn't already been chosen.  */
   if (bi->stack_in.top == -2)
     {
+      edge e, beste = NULL;
+      edge_iterator ei;
+
+      /* Select the best incoming edge (typically the most frequent) to
+        use as a template for this basic block.  */
+      FOR_EACH_EDGE (e, ei, block->preds)
+       if (BLOCK_INFO (e->src)->done)
+         beste = better_edge (beste, e);
+
       if (beste)
        propagate_stack (beste);
       else
        {
          /* No predecessors.  Create an arbitrary input stack.  */
-         int reg;
-
          bi->stack_in.top = -1;
          for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
            if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
              bi->stack_in.reg[++bi->stack_in.top] = reg;
        }
     }
-  else
-    /* Entry blocks do have stack already initialized.  */
-    beste = NULL;
 
   current_block = block;
 
@@ -2901,28 +2899,6 @@ convert_regs_1 (FILE *file, basic_block block)
   gcc_assert (any_malformed_asm);
  win:
   bi->stack_out = regstack;
-
-  /* Compensate the back edges, as those wasn't visited yet.  */
-  FOR_EACH_EDGE (e, ei, block->succs)
-    {
-      if (e->flags & EDGE_DFS_BACK
-         || (e->dest == EXIT_BLOCK_PTR))
-       {
-         gcc_assert (BLOCK_INFO (e->dest)->done
-                     || e->dest == block);
-         propagate_stack (e);
-       }
-    }
-
-  FOR_EACH_EDGE (e, ei, block->preds)
-    {
-      if (e != beste && !(e->flags & EDGE_DFS_BACK)
-         && e->src != ENTRY_BLOCK_PTR)
-       {
-         gcc_assert (BLOCK_INFO (e->src)->done);
-         propagate_stack (e);
-       }
-    }
 }
 
 /* Convert registers in all blocks reachable from BLOCK.  */