--- /dev/null
+/* { 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;
+}
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);
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,
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");
}
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))
{
{
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;
}
}
}
+
+ /* Remove dead PHI nodes. */
+ something_changed |= remove_dead_phis (bb);
}
h.release ();
/* 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. */
}
}
}
- FOR_EACH_BB_FN (bb, cfun)
- {
- /* Remove dead PHI nodes. */
- something_changed |= remove_dead_phis (bb);
- }
if (bb_postorder)
free (bb_postorder);