aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <apinski@cavium.com>2012-03-12 17:53:57 +0000
committerAndrew Pinski <pinskia@gcc.gnu.org>2012-03-12 10:53:57 -0700
commitb928d32b668a27f88fa29204411a98262d9dfa44 (patch)
tree8ddbdd3046d09f0c4df8090dc9b2e60b4c9b77a8 /gcc
parent2f986dce2c1dd37ac86ae4da1c0e51c9b516858a (diff)
downloadgcc-b928d32b668a27f88fa29204411a98262d9dfa44.zip
gcc-b928d32b668a27f88fa29204411a98262d9dfa44.tar.gz
gcc-b928d32b668a27f88fa29204411a98262d9dfa44.tar.bz2
tree-ssa-phiopt.c (single_non_singleton_phi_for_edges): New function.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/phi-opt-8.c2
-rw-r--r--gcc/tree-ssa-phiopt.c57
5 files changed, 73 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa8cd05..051d7f2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8a630a0..a6bb689 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..944acf9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c
@@ -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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-8.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-8.c
index 31dab46..775926d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-8.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index c195e3b..7987219 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -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");
}