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> 2019-03-27 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.h: Rename NON_SPECIAL_REGS to GEN_OR_FLOAT_REGS * 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> 2019-03-26 Uroš Bizjak <ubizjak@gmail.com>
PR target/89827 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. */ containing I so that we don't have to look it up. */
static void 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); gimple *stmt = gsi_stmt (*i);
@ -1045,20 +1046,17 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb)
e->flags |= EDGE_FALLTHRU; e->flags |= EDGE_FALLTHRU;
/* Remove the remaining outgoing edges. */ /* 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) if (e != e2)
{ {
cfg_altered = true;
/* If we made a BB unconditionally exit a loop or removed /* If we made a BB unconditionally exit a loop or removed
an entry into an irreducible region, then this transform an entry into an irreducible region, then this transform
alters the set of BBs in the loop. Schedule a fixup. */ alters the set of BBs in the loop. Schedule a fixup. */
if (loop_exit_edge_p (bb->loop_father, e) if (loop_exit_edge_p (bb->loop_father, e)
|| (e2->dest->flags & BB_IRREDUCIBLE_LOOP)) || (e2->dest->flags & BB_IRREDUCIBLE_LOOP))
loops_state_set (LOOPS_NEED_FIXUP); 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, /* If this is a store into a variable that is being optimized away,
@ -1201,6 +1199,7 @@ eliminate_unnecessary_stmts (void)
gimple *stmt; gimple *stmt;
tree call; tree call;
vec<basic_block> h; vec<basic_block> h;
auto_vec<edge> to_remove_edges;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nEliminating unnecessary statements:\n"); fprintf (dump_file, "\nEliminating unnecessary statements:\n");
@ -1287,7 +1286,7 @@ eliminate_unnecessary_stmts (void)
} }
if (!is_gimple_debug (stmt)) if (!is_gimple_debug (stmt))
something_changed = true; something_changed = true;
remove_dead_stmt (&gsi, bb); remove_dead_stmt (&gsi, bb, to_remove_edges);
} }
else if (is_gimple_call (stmt)) else if (is_gimple_call (stmt))
{ {
@ -1331,7 +1330,7 @@ eliminate_unnecessary_stmts (void)
{ {
case IFN_GOMP_SIMD_LANE: case IFN_GOMP_SIMD_LANE:
case IFN_ASAN_POISON: case IFN_ASAN_POISON:
remove_dead_stmt (&gsi, bb); remove_dead_stmt (&gsi, bb, to_remove_edges);
break; break;
default: default:
break; break;
@ -1354,6 +1353,9 @@ eliminate_unnecessary_stmts (void)
} }
} }
} }
/* Remove dead PHI nodes. */
something_changed |= remove_dead_phis (bb);
} }
h.release (); 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 /* 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. rendered some PHI nodes unreachable while they are still in use.
Mark them for renaming. */ Mark them for renaming. */
if (cfg_altered) if (!to_remove_edges.is_empty ())
{ {
basic_block prev_bb; 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 (); find_unreachable_blocks ();
/* Delete all unreachable basic blocks in reverse dominator order. */ /* 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) if (bb_postorder)
free (bb_postorder); free (bb_postorder);