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:
parent
c686fcbc77
commit
6461f211e0
@ -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
|
||||||
|
@ -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
|
||||||
|
25
gcc/testsuite/gcc.dg/guality/pr89463.c
Normal file
25
gcc/testsuite/gcc.dg/guality/pr89463.c
Normal 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;
|
||||||
|
}
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user