aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2008-09-18 13:58:55 +0000
committerAndrew Macleod <amacleod@gcc.gnu.org>2008-09-18 13:58:55 +0000
commitffd327a731d2a63c5d1110f52596641d3b7aa819 (patch)
treebecb2d6db49aba4ceae227e0ba5ac61c61928142 /gcc
parent3d9fbb9abd4785660983bc1d239f3f03e8dbc67c (diff)
downloadgcc-ffd327a731d2a63c5d1110f52596641d3b7aa819.zip
gcc-ffd327a731d2a63c5d1110f52596641d3b7aa819.tar.gz
gcc-ffd327a731d2a63c5d1110f52596641d3b7aa819.tar.bz2
fix PR 37102 by having out of ssa remove dead PHI nodes.
From-SVN: r140455
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr37102.c25
-rw-r--r--gcc/tree-outof-ssa.c69
4 files changed, 101 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f680fd6..0988e70 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2008-09-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/37102
+ * tree-outof-ssa.c (remove_gimple_phi_args): Remove all the arguments from a PHI
+ node. If it is a final use of an SSA_NAME, check to see if another PHI is dead.
+ (eliminate_useless_phis): Rename from eliminate_virtual_phis and remove real
+ PHIs which have no uses.
+ (rewrite_out_of_ssa): Call eliminate_useless_phis.
+
2008-09-18 Richard Guenther <rguenther@suse.de>
PR middle-end/37284
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 477455e..72e590c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-09-18 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/37102
+ * gcc.c-torture/execute/pr37102.c: New Test.
+
2008-09-18 Richard Guenther <rguenther@suse.de>
PR middle-end/37284
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr37102.c b/gcc/testsuite/gcc.c-torture/execute/pr37102.c
new file mode 100644
index 0000000..32c18ba
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr37102.c
@@ -0,0 +1,25 @@
+extern void abort (void);
+
+unsigned int a, b = 1, c;
+
+void __attribute__ ((noinline))
+foo (int x)
+{
+ if (x != 5)
+ abort ();
+}
+
+int
+main ()
+{
+ unsigned int d, e;
+ for (d = 1; d < 5; d++)
+ if (c)
+ a = b;
+ a = b;
+ e = a << 1;
+ if (e)
+ e = (e << 1) ^ 1;
+ foo (e);
+ return 0;
+}
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 58aed88..042e349 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -606,25 +606,69 @@ replace_def_variable (var_map map, def_operand_p def_p, tree *expr)
}
-/* Remove any PHI node which is a virtual PHI. */
+/* Remove each argument from a PHI node. If an arg was the last use of an SSA_NAME,
+ check to see if this allows another PHI node to be removed. */
static void
-eliminate_virtual_phis (void)
+remove_gimple_phi_args (gimple phi)
+{
+ use_operand_p arg_p;
+ ssa_op_iter iter;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Removing Dead PHI definition: ");
+ print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
+ }
+
+ FOR_EACH_PHI_ARG (arg_p, phi, iter, SSA_OP_USE)
+ {
+ tree arg = USE_FROM_PTR (arg_p);
+ if (TREE_CODE (arg) == SSA_NAME)
+ {
+ /* Remove the reference to the existing argument. */
+ SET_USE (arg_p, NULL_TREE);
+ if (has_zero_uses (arg))
+ {
+ gimple stmt;
+ gimple_stmt_iterator gsi;
+
+ stmt = SSA_NAME_DEF_STMT (arg);
+
+ /* Also remove the def if it is a PHI node. */
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ {
+ remove_gimple_phi_args (stmt);
+ gsi = gsi_for_stmt (stmt);
+ remove_phi_node (&gsi, true);
+ }
+
+ }
+ }
+ }
+}
+
+/* Remove any PHI node which is a virtual PHI, or a PHI with no uses. */
+
+static void
+eliminate_useless_phis (void)
{
basic_block bb;
gimple_stmt_iterator gsi;
+ tree result;
FOR_EACH_BB (bb)
{
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
{
gimple phi = gsi_stmt (gsi);
- if (!is_gimple_reg (SSA_NAME_VAR (gimple_phi_result (phi))))
+ result = gimple_phi_result (phi);
+ if (!is_gimple_reg (SSA_NAME_VAR (result)))
{
#ifdef ENABLE_CHECKING
size_t i;
- /* There should be no arguments of this PHI which are in
- the partition list, or we get incorrect results. */
+ /* There should be no arguments of this PHI which are not virtual, or we
+ get incorrect results. */
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = PHI_ARG_DEF (phi, i);
@@ -642,7 +686,16 @@ eliminate_virtual_phis (void)
remove_phi_node (&gsi, true);
}
else
- gsi_next (&gsi);
+ {
+ /* Also remove real PHIs with no uses. */
+ if (has_zero_uses (result))
+ {
+ remove_gimple_phi_args (phi);
+ remove_phi_node (&gsi, true);
+ }
+ else
+ gsi_next (&gsi);
+ }
}
}
}
@@ -1443,7 +1496,9 @@ rewrite_out_of_ssa (void)
copies into the loop itself. */
insert_backedge_copies ();
- eliminate_virtual_phis ();
+
+ /* Eliminate PHIs which are of no use, such as virtual or dead phis. */
+ eliminate_useless_phis ();
if (dump_file && (dump_flags & TDF_DETAILS))
gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);