tree-ssa-phiopt.c (single_non_singleton_phi_for_edges): New function.
authorAndrew Pinski <apinski@cavium.com>
Mon, 12 Mar 2012 17:53:57 +0000 (17:53 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Mon, 12 Mar 2012 17:53:57 +0000 (10:53 -0700)
2012-03-12  Andrew Pinski  <apinski@cavium.com>

* tree-ssa-phiopt.c (single_non_singleton_phi_for_edges): New function.
(tree_ssa_phiopt_worker): Use single_non_singleton_phi_for_edges.
(value_replacement): Likewise.
(empty_block_p): Check also if the PHIs for the block are empty.

2012-03-12  Andrew Pinski  <apinski@cavium.com>

* gcc.dg/tree-ssa/phi-opt-7.c: New testcase.

From-SVN: r185254

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-8.c
gcc/tree-ssa-phiopt.c

index fa8cd05016a231cdc2dfb6614e698ee860031c63..051d7f2507989e2d6fc5e291682f79a282f93ba1 100644 (file)
@@ -1,3 +1,10 @@
+2012-03-12  Andrew Pinski  <apinski@cavium.com>
+
+       * tree-ssa-phiopt.c (single_non_singleton_phi_for_edges): New function.
+       (tree_ssa_phiopt_worker): Use single_non_singleton_phi_for_edges.
+       (value_replacement): Likewise.
+       (empty_block_p): Check also if the PHIs for the block are empty.
+
 2012-03-12  Georg-Johann Lay  <avr@gjlay.de>
 
        PR target/52148
index 8a630a0d76404326ce40ddbbfb3571d49e985982..a6bb689a2851ca7f283b3d6495ae302175d3c103 100644 (file)
@@ -1,3 +1,7 @@
+2012-03-12  Andrew Pinski  <apinski@cavium.com>
+
+       * gcc.dg/tree-ssa/phi-opt-7.c: New testcase.
+
 2012-03-12  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * g++.dg/abi/rtti3.C: Remove alpha*-dec-osf* handling.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c
new file mode 100644 (file)
index 0000000..944acf9
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+int g(int,int);
+int f(int t, int c)
+{
+  int d = 0;
+  int e = 0;
+  if (t)
+    {
+      d = t;
+      if (c) e = 1;
+    }
+  else d = 0, e = 0;
+  return g(d,e);
+}
+
+/* There should be one ifs as one of them should be changed into
+   a conditional and the other should be there still.  */
+/* { dg-final { scan-tree-dump-times "if" 1 "optimized" }  }*/
+/* { dg-final { scan-tree-dump-times "D.\[0-9\]*_\[0-9\]* = c_\[0-9\]*.D. != 0" 1 "optimized"  } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
index 31dab46a79595d05674f410aa1b358f57bab905c..775926da98065c7695f9be7946b85e8d18c07c66 100644 (file)
@@ -19,7 +19,7 @@ int f(int t, int c)
    but currently is not as PHI-OPT does not reduce the t PHI as we have
    two phis.  Note this is fixed with
    http://gcc.gnu.org/ml/gcc-patches/2012-01/msg01195.html .  */
-/* { dg-final { scan-tree-dump-not "if" "phiopt1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-not "if" "phiopt1" } } */
 /* { dg-final { scan-tree-dump "g .t_\[0-9\]*.D.," "optimized" } } */
 /* { dg-final { scan-tree-dump-not "PHI" "optimized" } } */
 /* { dg-final { cleanup-tree-dump "phiopt1" } } */
index c195e3bcc4d7ae58dce2ac98c5306dd99e9759f5..798721993cd4ecb4430631dab97199148502b214 100644 (file)
@@ -193,6 +193,33 @@ tree_ssa_cs_elim (void)
   return tree_ssa_phiopt_worker (true);
 }
 
+/* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
+
+static gimple
+single_non_singleton_phi_for_edges (gimple_seq seq, edge e0, edge e1)
+{
+  gimple_stmt_iterator i;
+  gimple phi = NULL;
+  if (gimple_seq_singleton_p (seq))
+    return gsi_stmt (gsi_start (seq));
+  for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+    {
+      gimple p = gsi_stmt (i);
+      /* If the PHI arguments are equal then we can skip this PHI. */
+      if (operand_equal_for_phi_arg_p (gimple_phi_arg_def (p, e0->dest_idx),
+                                      gimple_phi_arg_def (p, e1->dest_idx)))
+       continue;
+
+      /* If we already have a PHI that has the two edge arguments are
+        different, then return it is not a singleton for these PHIs. */
+      if (phi)
+       return NULL;
+
+      phi = p;
+    }
+  return phi;
+}
+
 /* For conditional store replacement we need a temporary to
    put the old contents of the memory in.  */
 static tree condstoretemp;
@@ -316,6 +343,7 @@ tree_ssa_phiopt_worker (bool do_store_elim)
          gimple_seq phis = phi_nodes (bb2);
          gimple_stmt_iterator gsi;
          bool candorest = true;
+
          /* Value replacement can work with more than one PHI
             so try that first. */
          for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -333,21 +361,8 @@ tree_ssa_phiopt_worker (bool do_store_elim)
 
          if (!candorest)
            continue;
-         /* Check to make sure that there is only one non-virtual PHI node.
-            TODO: we could do it with more than one iff the other PHI nodes
-            have the same elements for these two edges.  */
-         phi = NULL;
-         for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
-           {
-             if (!is_gimple_reg (gimple_phi_result (gsi_stmt (gsi))))
-               continue;
-             if (phi)
-               {
-                 phi = NULL;
-                 break;
-               }
-             phi = gsi_stmt (gsi);
-           }
+         
+         phi = single_non_singleton_phi_for_edges (phis, e1, e2);
          if (!phi)
            continue;
 
@@ -447,6 +462,8 @@ empty_block_p (basic_block bb)
 {
   /* BB must have no executable statements.  */
   gimple_stmt_iterator gsi = gsi_after_labels (bb);
+  if (phi_nodes (bb))
+    return false;
   if (gsi_end_p (gsi))
     return true;
   if (is_gimple_debug (gsi_stmt (gsi)))
@@ -736,10 +753,11 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
        arg = arg1;
 
       /* If the middle basic block was empty or is defining the
-        PHI arguments and this is a singleton phi then we can remove
-         the middle basic block. */
+        PHI arguments and this is a single phi where the args are different
+        for the edges e0 and e1 then we can remove the middle basic block. */
       if (emtpy_or_with_defined_p
-         && gimple_seq_singleton_p (phi_nodes (gimple_bb (phi))))
+         && single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)),
+                                                           e0, e1))
        {
           replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
          /* Note that we optimized this PHI.  */
@@ -754,7 +772,8 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
            {
              fprintf (dump_file, "PHI ");
              print_generic_expr (dump_file, gimple_phi_result (phi), 0);
-             fprintf (dump_file, " reduced for COND_EXPR in block %d to ", cond_bb->index);
+             fprintf (dump_file, " reduced for COND_EXPR in block %d to ",
+                      cond_bb->index);
              print_generic_expr (dump_file, arg, 0);
              fprintf (dump_file, ".\n");
             }