if (!liveout)
init ();
- /* Since we don't have a virtual PHI we can now pick any of the
- incoming edges liveout value. All returns from the function have
- a virtual use forcing generation of virtual PHIs. */
+ /* Since we don't have a virtual PHI and we don't know whether there's
+ a downstream virtual use (and thus PHIs are inserted where necessary)
+ we now have to check each incoming edge live-out. */
edge_iterator ei;
edge e;
+ tree livein = NULL_TREE;
FOR_EACH_EDGE (e, ei, bb->preds)
- if (liveout[e->src->index])
- {
- if (EDGE_PRED (bb, 0) != e)
- liveout[EDGE_PRED (bb, 0)->src->index] = liveout[e->src->index];
- return liveout[e->src->index];
- }
-
- /* Since virtuals are in SSA form at most the immediate dominator can
- contain the definition of the live version. Skipping to that deals
- with CFG cycles as well. */
- return get_live_out (get_immediate_dominator (CDI_DOMINATORS, bb));
+ if (e->flags & EDGE_DFS_BACK)
+ /* We can ignore backedges since if there's a def there it would
+ have forced a PHI in the source because it also acts as use
+ downstream. */
+ continue;
+ else if (!livein)
+ livein = get_live_out (e->src);
+ else if (get_live_out (e->src) != livein)
+ /* When there's no virtual use downstream this indicates a point
+ where we'd insert a PHI merging the different live virtual
+ operands. */
+ return NULL_TREE;
+
+ return livein;
}
/* Compute live-out of BB. */
/* On-demand virtual operand global live analysis. There is at most
a single virtual operand live at a time, the following computes and
caches the virtual operand live at the exit of a basic block
- supporting related live-in and live-on-edge queries. */
+ supporting related live-in and live-on-edge queries. It requires
+ up-to-date marked backedges. */
class virtual_operand_live
{
/* Arrange for the critical edge splitting to be undone if requested. */
unsigned todo = unsplit_edges ? TODO_cleanup_cfg : 0;
connect_infinite_loops_to_exit ();
+ mark_dfs_back_edges (fun);
memset (&sink_stats, 0, sizeof (sink_stats));
calculate_dominance_info (CDI_DOMINATORS);