+2017-11-03 Jeff Law <law@redhat.com>
+
+ * cfganal.c (single_pred_edge_ignoring_loop_edges): New function
+ extracted from tree-ssa-dom.c.
+ * cfganal.h (single_pred_edge_ignoring_loop_edges): Prototype.
+ * tree-ssa-dom.c (single_incoming_edge_ignoring_loop_edges): Remove.
+ (record_equivalences_from_incoming_edge): Add additional argument
+ to single_pred_edge_ignoring_loop_edges call.
+ * tree-ssa-uncprop.c (single_incoming_edge_ignoring_loop_edges): Remove.
+ (uncprop_dom_walker::before_dom_children): Add additional argument
+ to single_pred_edge_ignoring_loop_edges call.
+ * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Use
+ single_pred_edge_ignoring_loop_edges rather than open coding.
+ * tree-vrp.c (evrp_dom_walker::before_dom_children): Similarly.
+
2017-11-03 Marc Glisse <marc.glisse@inria.fr>
* match.pd (-(-A)): Rewrite.
#undef MARK_VISITED
#undef VISITED_P
}
+
+/* Ignoring loop backedges, if BB has precisely one incoming edge then
+ return that edge. Otherwise return NULL.
+
+ When IGNORE_NOT_EXECUTABLE is true, also ignore edges that are not marked
+ as executable. */
+
+edge
+single_pred_edge_ignoring_loop_edges (basic_block bb,
+ bool ignore_not_executable)
+{
+ edge retval = NULL;
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ /* A loop back edge can be identified by the destination of
+ the edge dominating the source of the edge. */
+ if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
+ continue;
+
+ /* We can safely ignore edges that are not executable. */
+ if (ignore_not_executable
+ && (e->flags & EDGE_EXECUTABLE) == 0)
+ continue;
+
+ /* If we have already seen a non-loop edge, then we must have
+ multiple incoming non-loop edges and thus we return NULL. */
+ if (retval)
+ return NULL;
+
+ /* This is the first non-loop incoming edge we have found. Record
+ it. */
+ retval = e;
+ }
+
+ return retval;
+}
extern void bitmap_union_of_succs (sbitmap, sbitmap *, basic_block);
extern void bitmap_union_of_preds (sbitmap, sbitmap *, basic_block);
extern basic_block * single_pred_before_succ_order (void);
+extern edge single_incoming_edge_ignoring_loop_edges (basic_block, bool);
+extern edge single_pred_edge_ignoring_loop_edges (basic_block, bool);
+
#endif /* GCC_CFGANAL_H */
class avail_exprs_stack *);
static void record_equivalences_from_stmt (gimple *, int,
class avail_exprs_stack *);
-static edge single_incoming_edge_ignoring_loop_edges (basic_block);
static void dump_dominator_optimization_stats (FILE *file,
hash_table<expr_elt_hasher> *);
}
}
-/* Ignoring loop backedges, if BB has precisely one incoming edge then
- return that edge. Otherwise return NULL. */
-static edge
-single_incoming_edge_ignoring_loop_edges (basic_block bb)
-{
- edge retval = NULL;
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- /* A loop back edge can be identified by the destination of
- the edge dominating the source of the edge. */
- if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
- continue;
-
- /* We can safely ignore edges that are not executable. */
- if ((e->flags & EDGE_EXECUTABLE) == 0)
- continue;
-
- /* If we have already seen a non-loop edge, then we must have
- multiple incoming non-loop edges and thus we return NULL. */
- if (retval)
- return NULL;
-
- /* This is the first non-loop incoming edge we have found. Record
- it. */
- retval = e;
- }
-
- return retval;
-}
-
/* Record any equivalences created by the incoming edge to BB into
CONST_AND_COPIES and AVAIL_EXPRS_STACK. If BB has more than one
incoming edge, then no equivalence is created. */
the parent was followed. */
parent = get_immediate_dominator (CDI_DOMINATORS, bb);
- e = single_incoming_edge_ignoring_loop_edges (bb);
+ e = single_pred_edge_ignoring_loop_edges (bb, true);
/* If we had a single incoming edge from our parent block, then enter
any data associated with the edge into our tables. */
edge
sccvn_dom_walker::before_dom_children (basic_block bb)
{
- edge e;
- edge_iterator ei;
-
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Visiting BB %d\n", bb->index);
/* If we have a single predecessor record the equivalence from a
possible condition on the predecessor edge. */
- edge pred_e = NULL;
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- /* Ignore simple backedges from this to allow recording conditions
- in loop headers. */
- if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
- continue;
- if (! pred_e)
- pred_e = e;
- else
- {
- pred_e = NULL;
- break;
- }
- }
+ edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
if (pred_e)
{
/* Check if there are multiple executable successor edges in
the source block. Otherwise there is no additional info
to be recorded. */
+ edge_iterator ei;
edge e2;
FOR_EACH_EDGE (e2, ei, pred_e->src->succs)
if (e2 != pred_e
}
}
-/* Ignoring loop backedges, if BB has precisely one incoming edge then
- return that edge. Otherwise return NULL. */
-static edge
-single_incoming_edge_ignoring_loop_edges (basic_block bb)
-{
- edge retval = NULL;
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- /* A loop back edge can be identified by the destination of
- the edge dominating the source of the edge. */
- if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
- continue;
-
- /* If we have already seen a non-loop edge, then we must have
- multiple incoming non-loop edges and thus we return NULL. */
- if (retval)
- return NULL;
-
- /* This is the first non-loop incoming edge we have found. Record
- it. */
- retval = e;
- }
-
- return retval;
-}
-
edge
uncprop_dom_walker::before_dom_children (basic_block bb)
{
basic_block parent;
- edge e;
bool recorded = false;
/* If this block is dominated by a single incoming edge and that edge
parent = get_immediate_dominator (CDI_DOMINATORS, bb);
if (parent)
{
- e = single_incoming_edge_ignoring_loop_edges (bb);
+ edge e = single_pred_edge_ignoring_loop_edges (bb, false);
if (e && e->src == parent && e->aux)
{
edge
evrp_dom_walker::before_dom_children (basic_block bb)
{
- tree op0 = NULL_TREE;
- edge_iterator ei;
- edge e;
-
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Visiting BB%d\n", bb->index);
stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL));
- edge pred_e = NULL;
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- /* Ignore simple backedges from this to allow recording conditions
- in loop headers. */
- if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
- continue;
- if (! pred_e)
- pred_e = e;
- else
- {
- pred_e = NULL;
- break;
- }
- }
+ edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
if (pred_e)
{
gimple *stmt = last_stmt (pred_e->src);
+ tree op0 = NULL_TREE;
+
if (stmt
&& gimple_code (stmt) == GIMPLE_COND
&& (op0 = gimple_cond_lhs (stmt))
/* Visit PHI stmts and discover any new VRs possible. */
bool has_unvisited_preds = false;
+ edge_iterator ei;
+ edge e;
FOR_EACH_EDGE (e, ei, bb->preds)
if (e->flags & EDGE_EXECUTABLE
&& !(e->src->flags & BB_VISITED))