OSDN Git Service

PR tree-optimization/28888
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Sep 2006 10:02:47 +0000 (10:02 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Sep 2006 10:02:47 +0000 (10:02 +0000)
* tree-if-conv.c (combine_blocks): Rewritten.
* tree-cfg.c (tree_verify_flow_info): Check that edges with
EDGE_TRUE/FALSE_VALUE follow COND_EXPR.

* gcc.dg/pr28888.c: New test.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr28888.c [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-if-conv.c

index 11c8865..311f26b 100644 (file)
@@ -1,3 +1,10 @@
+2006-09-22  Zdenek Dvorak <dvorakz@suse.cz>
+
+       PR tree-optimization/28888
+       * tree-if-conv.c (combine_blocks): Rewritten.
+       * tree-cfg.c (tree_verify_flow_info): Check that edges with
+       EDGE_TRUE/FALSE_VALUE follow COND_EXPR.
+
 2006-09-22  Jakub Jelinek  <jakub@redhat.com>
 
        * tree-ssa-propagate.c (set_rhs): Copy EXPR_LOCATION if
index 80097ac..a560131 100644 (file)
@@ -1,3 +1,8 @@
+2006-09-22  Zdenek Dvorak <dvorakz@suse.cz>
+
+       PR tree-optimization/28888
+       * gcc.dg/pr28888.c: New test.
+
 2006-09-21  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/29016
 
 2006-09-21  Lee Millward  <lee.millward@codesourcery.com>
 
-        PR c++/28861
-        * g++.dg/template/spec32.C: New test.
-        * g++.dg/parse/crash9.C: Adjust error markers.
+       PR c++/28861
+       * g++.dg/template/spec32.C: New test.
+       * g++.dg/parse/crash9.C: Adjust error markers.
 
        PR c++/28303
-        * g++.dg/template/typedef6.C: New test.
-        * g++.dg/init/error1.C: Adjust error markers.
-        * g++.dg/parse/crash9.C: Likewise.
-        * g++.dg/template/crash55.C: Likewise.
+       * g++.dg/template/typedef6.C: New test.
+       * g++.dg/init/error1.C: Adjust error markers.
+       * g++.dg/parse/crash9.C: Likewise.
+       * g++.dg/template/crash55.C: Likewise.
        
 2006-09-21  Janis Johnson  <janis187@us.ibm.com>
 
diff --git a/gcc/testsuite/gcc.dg/pr28888.c b/gcc/testsuite/gcc.dg/pr28888.c
new file mode 100644 (file)
index 0000000..c65a26a
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+static const unsigned char _c30[] =
+  "statistic of allocated integer registers:";
+Allocate__WriteStats (void)
+{
+  register int i0, i1, i2, i3, i4, i5;
+l0:i1 = (int) (i5 << 2);
+  if (i0)
+  i4 = i5;
+l1:i2 += i1;
+  if (i1)
+  goto l0;
+l3:i0 = i1 == 255;
+  i1++;
+  Out__LongInt ((int) i0, (int) 0);
+  i0 = i4 >= i1;
+  if (i0)
+    goto l3;
+}
index 52e71a7..67d0491 100644 (file)
@@ -3757,6 +3757,19 @@ tree_verify_flow_info (void)
              }
        }
 
+      if (TREE_CODE (stmt) != COND_EXPR)
+       {
+         /* Verify that there are no edges with EDGE_TRUE/FALSE_FLAG set
+            after anything else but if statement.  */
+         FOR_EACH_EDGE (e, ei, bb->succs)
+           if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))
+             {
+               error ("true/false edge after a non-COND_EXPR in bb %d",
+                      bb->index);
+               err = 1;
+             }
+       }
+
       switch (TREE_CODE (stmt))
        {
        case COND_EXPR:
index 6e16a40..3a50741 100644 (file)
@@ -866,71 +866,73 @@ combine_blocks (struct loop *loop)
   basic_block bb, exit_bb, merge_target_bb;
   unsigned int orig_loop_num_nodes = loop->num_nodes;
   unsigned int i;
-  unsigned int n_exits;
-  edge *exits;
+  edge e;
+  edge_iterator ei;
 
-  exits = get_loop_exit_edges (loop, &n_exits);
-  free (exits);
   /* Process phi nodes to prepare blocks for merge.  */
   process_phi_nodes (loop);
 
+  /* Merge basic blocks.  First remove all the edges in the loop, except
+     for those from the exit block.  */
   exit_bb = NULL;
+  for (i = 0; i < orig_loop_num_nodes; i++)
+    {
+      bb = ifc_bbs[i];
+      if (bb_with_exit_edge_p (loop, bb))
+       {
+         exit_bb = bb;
+         break;
+       }
+    }
+  gcc_assert (exit_bb != loop->latch);
 
-  /* Merge basic blocks */
-  merge_target_bb = loop->header;
   for (i = 1; i < orig_loop_num_nodes; i++)
     {
-      edge e;
-      block_stmt_iterator bsi;
-      tree_stmt_iterator last;
-
       bb = ifc_bbs[i];
 
-      if (!exit_bb && bb_with_exit_edge_p (loop, bb))
-         exit_bb = bb;
-
-      if (bb == exit_bb)
+      for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
        {
-         edge_iterator ei;
+         if (e->src == exit_bb)
+           ei_next (&ei);
+         else
+           remove_edge (e);
+       }
+    }
 
+  if (exit_bb != NULL)
+    {
+      if (exit_bb != loop->header)
+       {
          /* Connect this node with loop header.  */
-         make_edge (ifc_bbs[0], bb, EDGE_FALLTHRU);
-         set_immediate_dominator (CDI_DOMINATORS, bb, ifc_bbs[0]);
-
-         if (exit_bb != loop->latch)
-           {
-             /* Redirect non-exit edge to loop->latch.  */
-             FOR_EACH_EDGE (e, ei, bb->succs)
-               {
-                 if (!loop_exit_edge_p (loop, e))
-                   {
-                     redirect_edge_and_branch (e, loop->latch);
-                     set_immediate_dominator (CDI_DOMINATORS, loop->latch, bb);
-                   }
-               }
-           }
-         continue;
+         make_edge (loop->header, exit_bb, EDGE_FALLTHRU);
+         set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
        }
 
-      if (bb == loop->latch && empty_block_p (bb))
-       continue;
+      /* Redirect non-exit edges to loop->latch.  */
+      FOR_EACH_EDGE (e, ei, exit_bb->succs)
+       {
+         if (!loop_exit_edge_p (loop, e))
+           redirect_edge_and_branch (e, loop->latch);
+       }
+      set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
+    }
+  else
+    {
+      /* If the loop does not have exit then reconnect header and latch.  */
+      make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
+      set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
+    }
 
-      /* It is time to remove this basic block.         First remove edges.  */
-      while (EDGE_COUNT (bb->preds) > 0)
-       remove_edge (EDGE_PRED (bb, 0));
+  merge_target_bb = loop->header;
+  for (i = 1; i < orig_loop_num_nodes; i++)
+    {
+      block_stmt_iterator bsi;
+      tree_stmt_iterator last;
 
-      /* This is loop latch and loop does not have exit then do not
-        delete this basic block. Just remove its PREDS and reconnect 
-        loop->header and loop->latch blocks.  */
-      if (bb == loop->latch && n_exits == 0)
-       {
-         make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
-         set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
-         continue;
-       }
+      bb = ifc_bbs[i];
 
-      while (EDGE_COUNT (bb->succs) > 0)
-       remove_edge (EDGE_SUCC (bb, 0));
+      if (bb == exit_bb || bb == loop->latch)
+       continue;
 
       /* Remove labels and make stmts member of loop->header.  */
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
@@ -956,8 +958,6 @@ combine_blocks (struct loop *loop)
        delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
 
       /* Remove basic block.  */
-      if (bb == loop->latch)
-       loop->latch = merge_target_bb;
       remove_bb_from_loops (bb);
       expunge_block (bb);
     }
@@ -966,15 +966,11 @@ combine_blocks (struct loop *loop)
      This reduces number of basic blocks to 2. Auto vectorizer addresses
      loops with two nodes only.  FIXME: Use cleanup_tree_cfg().  */
   if (exit_bb
-      && loop->header != loop->latch
-      && exit_bb != loop->latch 
-      && empty_block_p (loop->latch))
+      && exit_bb != loop->header
+      && can_merge_blocks_p (loop->header, exit_bb))
     {
-      if (can_merge_blocks_p (loop->header, exit_bb))
-       {
-         remove_bb_from_loops (exit_bb);
-         merge_blocks (loop->header, exit_bb);
-       }
+      remove_bb_from_loops (exit_bb);
+      merge_blocks (loop->header, exit_bb);
     }
 }