tree-if-conv.c (find_phi_replacement_condition): Avoid generating x = !(a == b) ...
authorDevang Patel <dpatel@apple.com>
Thu, 21 Apr 2005 17:03:23 +0000 (10:03 -0700)
committerDevang Patel <dpatel@gcc.gnu.org>
Thu, 21 Apr 2005 17:03:23 +0000 (10:03 -0700)
  * tree-if-conv.c (find_phi_replacement_condition): Avoid
  generating x = !(a == b) : p : q;.
  (pass_if_conversion): Verify stmts and flow.

  * gcc.dg/tree-ssa/ifc-3.c: New test.

From-SVN: r98514

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ifc-3.c [new file with mode: 0644]
gcc/tree-if-conv.c

index e2b5cd64beaab68b9456e2f2980bb8a66192e189..b4c34975168fada090096540aa3757cc5dd9527d 100644 (file)
@@ -1,3 +1,10 @@
+2005-04-21  Devang Patel  <dpatel@apple.com>
+
+       PR optimization/20994
+       * tree-if-conv.c (find_phi_replacement_condition): Avoid generating
+       x = !(a == b) : p , q;.
+       (pass_if_conversion): Verify stmts and flow.
+       
 2005-04-21  Nathan Sidwell  <nathan@codesourcery.com>
 
        * optabs.c (gen_conditional_trap): Restore #define.
index 522c884be9f3487b690862eb474fe7836ca8051d..179b8bfe67385b9d3d5a375fc4b1b38105814688 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-21  Devang Patel  <dpatel@apple.com>
+
+       PR optimization/20994
+       * gcc.dg/tree-ssa/ifc-3.c: New test.
+       
 2005-04-20  Joseph S. Myers  <joseph@codesourcery.com>
 
        PR c/12913
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-3.c
new file mode 100644 (file)
index 0000000..e853ec4
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR 20994 */
+/* { dg-do compile } */
+int foo(double* p, double* q)
+{
+    int i=0;
+
+    for (; q!=p; ++q)
+        if (*q)
+            ++i;
+
+    return i;
+}
index 2770539d435bf671f140e9cd8febc50bba690642..4eb5a26e6c9b2e1a178d6235fc66c57ca7eddba9 100644 (file)
@@ -665,46 +665,64 @@ find_phi_replacement_condition (struct loop *loop,
                                basic_block bb, tree *cond,
                                 block_stmt_iterator *bsi)
 {
-  edge e;
-  basic_block p1 = NULL;
-  basic_block p2 = NULL;
-  basic_block true_bb = NULL; 
+  basic_block first_bb = NULL;
+  basic_block second_bb = NULL;
   tree tmp_cond;
-  edge_iterator ei;
 
-  FOR_EACH_EDGE (e, ei, bb->preds)
-    {
-      if (p1 == NULL)
-       p1 = e->src;
-      else 
-       {
-         gcc_assert (!p2);
-         p2 = e->src;
-       }
-    }
+  gcc_assert (EDGE_COUNT (bb->preds) == 2);
+  first_bb = (EDGE_PRED (bb, 0))->src;
+  second_bb = (EDGE_PRED (bb, 1))->src;
 
-  /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr.  */
-  tmp_cond = p1->aux;
+  /* Use condition based on following criteria:
+     1)
+       S1: x = !c ? a : b;
+
+       S2: x = c ? b : a;
+
+       S2 is preferred over S1. Make 'b' first_bb and use its condition.
+
+     2) Do not make loop header first_bb.
+
+     3)
+       S1: x = !(c == d)? a : b;
+
+       S21: t1 = c == d;
+       S22: x = t1 ? b : a;
+
+       S3: x = (c == d) ? b : a;
+
+       S3 is preferred over S1 and S2*, Make 'b' first_bb and use 
+       its condition.  */
+
+  /* Select condition that is not TRUTH_NOT_EXPR.  */
+  tmp_cond = first_bb->aux;
   if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
     {
-      /* If p2 is loop->header than its aux field does not have useful
-        info. Instead use !(cond) where cond is p1's aux field.  */
-      if (p2 == loop->header)
-       *cond = invert_truthvalue (unshare_expr (p1->aux));
-      else
-       *cond  = p2->aux;
-      true_bb = p2;
+      basic_block tmp_bb;
+      tmp_bb = first_bb;
+      first_bb = second_bb;
+      second_bb = first_bb;
     }
-  else
+
+  /* Check if FIRST_BB is loop header or not.  */
+  if (first_bb == loop->header) 
     {
-      /* If p1 is loop->header than its aux field does not have useful
-        info. Instead use !(cond) where cond is p2's aux field.  */
-      if (p1 == loop->header)
-       *cond = invert_truthvalue (unshare_expr (p2->aux));
+      tmp_cond = second_bb->aux;
+      if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
+       {
+         /* Select non loop header condition but do not switch basic blocks.  */
+         *cond = invert_truthvalue (unshare_expr (tmp_cond));
+       }
       else
-       *cond  = p1->aux;
-      true_bb = p1;
+       {
+         /* Select non loop header condition.  */
+         first_bb = second_bb;
+         *cond = first_bb->aux;
+       }
     }
+  else
+    /* FIRST_BB is not loop header */
+    *cond = first_bb->aux;
 
   /* Create temp. for the condition. Vectorizer prefers to have gimple
      value as condition. Various targets use different means to communicate
@@ -722,7 +740,7 @@ find_phi_replacement_condition (struct loop *loop,
 
   gcc_assert (*cond);
 
-  return true_bb;
+  return first_bb;
 }
 
 
@@ -1119,6 +1137,7 @@ struct tree_opt_pass pass_if_conversion =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops,  /* todo_flags_finish */
+  TODO_dump_func | TODO_verify_loops | TODO_verify_stmts | TODO_verify_flow,   
+                                        /* todo_flags_finish */
   0                                    /* letter */
 };