fix PR 37102 by having out of ssa remove dead PHI nodes.

From-SVN: r140455
This commit is contained in:
Andrew MacLeod 2008-09-18 13:58:55 +00:00 committed by Andrew Macleod
parent 3d9fbb9abd
commit ffd327a731
4 changed files with 101 additions and 7 deletions

View File

@ -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> 2008-09-18 Richard Guenther <rguenther@suse.de>
PR middle-end/37284 PR middle-end/37284

View File

@ -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> 2008-09-18 Richard Guenther <rguenther@suse.de>
PR middle-end/37284 PR middle-end/37284

View File

@ -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;
}

View File

@ -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 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; basic_block bb;
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
tree result;
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
{ {
gimple phi = gsi_stmt (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 #ifdef ENABLE_CHECKING
size_t i; size_t i;
/* There should be no arguments of this PHI which are in /* There should be no arguments of this PHI which are not virtual, or we
the partition list, or we get incorrect results. */ get incorrect results. */
for (i = 0; i < gimple_phi_num_args (phi); i++) for (i = 0; i < gimple_phi_num_args (phi); i++)
{ {
tree arg = PHI_ARG_DEF (phi, i); tree arg = PHI_ARG_DEF (phi, i);
@ -642,7 +686,16 @@ eliminate_virtual_phis (void)
remove_phi_node (&gsi, true); remove_phi_node (&gsi, true);
} }
else 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. */ copies into the loop itself. */
insert_backedge_copies (); 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)) if (dump_file && (dump_flags & TDF_DETAILS))
gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS); gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);