re PR tree-optimization/60098 (DSE fails to DSE errno settings)
2014-06-04 Richard Biener <rguenther@suse.de> PR tree-optimization/60098 * tree-ssa-dse.c (dse_possible_dead_store_p): Walk until we hit a kill. (dse_optimize_stmt): Simplify, now that we found a kill earlier. * gcc.dg/tree-ssa/ssa-dse-15.c: New testcase. From-SVN: r211224
This commit is contained in:
parent
b1259d34e9
commit
0ea48022b8
|
@ -1,3 +1,11 @@
|
|||
2014-06-04 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/60098
|
||||
* tree-ssa-dse.c (dse_possible_dead_store_p): Walk until
|
||||
we hit a kill.
|
||||
(dse_optimize_stmt): Simplify, now that we found a kill
|
||||
earlier.
|
||||
|
||||
2014-06-04 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2014-06-04 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/60098
|
||||
* gcc.dg/tree-ssa/ssa-dse-15.c: New testcase.
|
||||
|
||||
2014-06-04 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/ssa-dse-16.c: New testcase.
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-dse1-details" } */
|
||||
|
||||
void *foo (int *p)
|
||||
{
|
||||
void *q;
|
||||
/* We should be able to DSE this store (p may point to errno). */
|
||||
*p = 0;
|
||||
q = __builtin_malloc (4);
|
||||
*p = 0;
|
||||
return q;
|
||||
}
|
||||
|
||||
int j;
|
||||
void bar (int *i)
|
||||
{
|
||||
/* This store is dead as well. */
|
||||
j = 1;
|
||||
*i = 0;
|
||||
j = 2;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "dse1" } } */
|
|
@ -198,10 +198,8 @@ dse_possible_dead_store_p (gimple stmt, gimple *use_stmt)
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* We deliberately stop on clobbering statements and not only on
|
||||
killing ones to make walking cheaper. Otherwise we can just
|
||||
continue walking until both stores have equal reference trees. */
|
||||
while (!stmt_may_clobber_ref_p (temp, gimple_assign_lhs (stmt)));
|
||||
/* Continue walking until we reach a kill. */
|
||||
while (!stmt_kills_ref_p (temp, gimple_assign_lhs (stmt)));
|
||||
|
||||
*use_stmt = temp;
|
||||
|
||||
|
@ -248,57 +246,49 @@ dse_optimize_stmt (gimple_stmt_iterator *gsi)
|
|||
if (!dse_possible_dead_store_p (stmt, &use_stmt))
|
||||
return;
|
||||
|
||||
/* Now we know that use_stmt kills the LHS of stmt. */
|
||||
|
||||
/* But only remove *this_2(D) ={v} {CLOBBER} if killed by
|
||||
another clobber stmt. */
|
||||
if (gimple_clobber_p (stmt)
|
||||
&& !gimple_clobber_p (use_stmt))
|
||||
return;
|
||||
|
||||
/* If we have precisely one immediate use at this point and the
|
||||
stores are to the same memory location or there is a chain of
|
||||
virtual uses from stmt and the stmt which stores to that same
|
||||
memory location, then we may have found redundant store. */
|
||||
if ((gimple_has_lhs (use_stmt)
|
||||
&& (operand_equal_p (gimple_assign_lhs (stmt),
|
||||
gimple_get_lhs (use_stmt), 0)))
|
||||
|| stmt_kills_ref_p (use_stmt, gimple_assign_lhs (stmt)))
|
||||
basic_block bb;
|
||||
|
||||
/* If use_stmt is or might be a nop assignment, e.g. for
|
||||
struct { ... } S a, b, *p; ...
|
||||
b = a; b = b;
|
||||
or
|
||||
b = a; b = *p; where p might be &b,
|
||||
or
|
||||
*p = a; *p = b; where p might be &b,
|
||||
or
|
||||
*p = *u; *p = *v; where p might be v, then USE_STMT
|
||||
acts as a use as well as definition, so store in STMT
|
||||
is not dead. */
|
||||
if (stmt != use_stmt
|
||||
&& ref_maybe_used_by_stmt_p (use_stmt, gimple_assign_lhs (stmt)))
|
||||
return;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
/* If use_stmt is or might be a nop assignment, e.g. for
|
||||
struct { ... } S a, b, *p; ...
|
||||
b = a; b = b;
|
||||
or
|
||||
b = a; b = *p; where p might be &b,
|
||||
or
|
||||
*p = a; *p = b; where p might be &b,
|
||||
or
|
||||
*p = *u; *p = *v; where p might be v, then USE_STMT
|
||||
acts as a use as well as definition, so store in STMT
|
||||
is not dead. */
|
||||
if (stmt != use_stmt
|
||||
&& ref_maybe_used_by_stmt_p (use_stmt, gimple_assign_lhs (stmt)))
|
||||
return;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, " Deleted dead store '");
|
||||
print_gimple_stmt (dump_file, gsi_stmt (*gsi), dump_flags, 0);
|
||||
fprintf (dump_file, "'\n");
|
||||
}
|
||||
|
||||
/* Then we need to fix the operand of the consuming stmt. */
|
||||
unlink_stmt_vdef (stmt);
|
||||
|
||||
/* Remove the dead store. */
|
||||
bb = gimple_bb (stmt);
|
||||
if (gsi_remove (gsi, true))
|
||||
bitmap_set_bit (need_eh_cleanup, bb->index);
|
||||
|
||||
/* And release any SSA_NAMEs set in this statement back to the
|
||||
SSA_NAME manager. */
|
||||
release_defs (stmt);
|
||||
fprintf (dump_file, " Deleted dead store '");
|
||||
print_gimple_stmt (dump_file, gsi_stmt (*gsi), dump_flags, 0);
|
||||
fprintf (dump_file, "'\n");
|
||||
}
|
||||
|
||||
/* Then we need to fix the operand of the consuming stmt. */
|
||||
unlink_stmt_vdef (stmt);
|
||||
|
||||
/* Remove the dead store. */
|
||||
bb = gimple_bb (stmt);
|
||||
if (gsi_remove (gsi, true))
|
||||
bitmap_set_bit (need_eh_cleanup, bb->index);
|
||||
|
||||
/* And release any SSA_NAMEs set in this statement back to the
|
||||
SSA_NAME manager. */
|
||||
release_defs (stmt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue