re PR debug/89463 (debug information for iterator of an empty loop is gone (at -O3))

2019-03-27  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/89463
	* tree-ssa-dce.c (remove_dead_stmt): Take output vector to
	queue edges to remove.
	(eliminate_unnecessary_stmts): Remove dead PHIs alongside
	dead stmts.  Delay edge removal until PHIs are removed to
	make debug-stmt creation not confused by seemingly degenerate
	PHIs.

	* gcc.dg/guality/pr89463.c: New testcase.

From-SVN: r269961
This commit is contained in:
Richard Biener 2019-03-27 09:31:53 +00:00 committed by Richard Biener
parent c686fcbc77
commit 6461f211e0
4 changed files with 57 additions and 14 deletions

View File

@ -1,3 +1,13 @@
2019-03-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/89463
* tree-ssa-dce.c (remove_dead_stmt): Take output vector to
queue edges to remove.
(eliminate_unnecessary_stmts): Remove dead PHIs alongside
dead stmts. Delay edge removal until PHIs are removed to
make debug-stmt creation not confused by seemingly degenerate
PHIs.
2019-03-27 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.h: Rename NON_SPECIAL_REGS to GEN_OR_FLOAT_REGS

View File

@ -1,3 +1,8 @@
2019-03-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/89463
* gcc.dg/guality/pr89463.c: New testcase.
2019-03-26 Uroš Bizjak <ubizjak@gmail.com>
PR target/89827

View File

@ -0,0 +1,25 @@
/* { dg-do run } */
/* { dg-options "-g" } */
void __attribute__((noinline))
optimize_me_not ()
{
__asm__ volatile ("" : : : "memory");
}
int a;
int main()
{
int i;
for (; a < 10; a++)
i = 0;
for (; i < 6; i++)
;
/* i may very well be optimized out, so we cannot test for i == 6.
Instead test i + 1 which will make the test UNSUPPORTED if i
is optimized out. Since the test previously had wrong debug
with i == 0 this is acceptable. Optimally we'd produce a
debug stmt for the final value of the loop which would fix
the UNSUPPORTED cases. */
optimize_me_not(); /* { dg-final { gdb-test . "i + 1" "7" } } */
return 0;
}

View File

@ -985,7 +985,8 @@ remove_dead_phis (basic_block bb)
containing I so that we don't have to look it up. */
static void
remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb)
remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb,
vec<edge> &to_remove_edges)
{
gimple *stmt = gsi_stmt (*i);
@ -1045,20 +1046,17 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb)
e->flags |= EDGE_FALLTHRU;
/* Remove the remaining outgoing edges. */
for (ei = ei_start (bb->succs); (e2 = ei_safe_edge (ei)); )
FOR_EACH_EDGE (e2, ei, bb->succs)
if (e != e2)
{
cfg_altered = true;
/* If we made a BB unconditionally exit a loop or removed
an entry into an irreducible region, then this transform
alters the set of BBs in the loop. Schedule a fixup. */
if (loop_exit_edge_p (bb->loop_father, e)
|| (e2->dest->flags & BB_IRREDUCIBLE_LOOP))
loops_state_set (LOOPS_NEED_FIXUP);
remove_edge (e2);
to_remove_edges.safe_push (e2);
}
else
ei_next (&ei);
}
/* If this is a store into a variable that is being optimized away,
@ -1201,6 +1199,7 @@ eliminate_unnecessary_stmts (void)
gimple *stmt;
tree call;
vec<basic_block> h;
auto_vec<edge> to_remove_edges;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nEliminating unnecessary statements:\n");
@ -1287,7 +1286,7 @@ eliminate_unnecessary_stmts (void)
}
if (!is_gimple_debug (stmt))
something_changed = true;
remove_dead_stmt (&gsi, bb);
remove_dead_stmt (&gsi, bb, to_remove_edges);
}
else if (is_gimple_call (stmt))
{
@ -1331,7 +1330,7 @@ eliminate_unnecessary_stmts (void)
{
case IFN_GOMP_SIMD_LANE:
case IFN_ASAN_POISON:
remove_dead_stmt (&gsi, bb);
remove_dead_stmt (&gsi, bb, to_remove_edges);
break;
default:
break;
@ -1354,6 +1353,9 @@ eliminate_unnecessary_stmts (void)
}
}
}
/* Remove dead PHI nodes. */
something_changed |= remove_dead_phis (bb);
}
h.release ();
@ -1361,10 +1363,16 @@ eliminate_unnecessary_stmts (void)
/* Since we don't track liveness of virtual PHI nodes, it is possible that we
rendered some PHI nodes unreachable while they are still in use.
Mark them for renaming. */
if (cfg_altered)
if (!to_remove_edges.is_empty ())
{
basic_block prev_bb;
/* Remove edges. We've delayed this to not get bogus debug stmts
during PHI node removal. */
for (unsigned i = 0; i < to_remove_edges.length (); ++i)
remove_edge (to_remove_edges[i]);
cfg_altered = true;
find_unreachable_blocks ();
/* Delete all unreachable basic blocks in reverse dominator order. */
@ -1430,11 +1438,6 @@ eliminate_unnecessary_stmts (void)
}
}
}
FOR_EACH_BB_FN (bb, cfun)
{
/* Remove dead PHI nodes. */
something_changed |= remove_dead_phis (bb);
}
if (bb_postorder)
free (bb_postorder);