diff options
author | Andrew Pinski <apinski@cavium.com> | 2012-03-12 17:53:57 +0000 |
---|---|---|
committer | Andrew Pinski <pinskia@gcc.gnu.org> | 2012-03-12 10:53:57 -0700 |
commit | b928d32b668a27f88fa29204411a98262d9dfa44 (patch) | |
tree | 8ddbdd3046d09f0c4df8090dc9b2e60b4c9b77a8 /gcc | |
parent | 2f986dce2c1dd37ac86ae4da1c0e51c9b516858a (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/phi-opt-8.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-phiopt.c | 57 |
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"); } |