* [RFA][PATCH] Refactor duplicated code used by various dom walkers
@ 2017-11-03 3:49 Jeff Law
2017-11-03 10:05 ` Richard Biener
0 siblings, 1 reply; 4+ messages in thread
From: Jeff Law @ 2017-11-03 3:49 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 612 bytes --]
Several passes which perform dominator walks want to identify when block
has a single incoming edge, ignoring loop backedges.
I'm aware of 4 implementations of this code. 3 of the 4 are identical
in function. The 4th (tree-ssa-dom.c) has an additional twist that it
also ignores edges that are not marked as executable.
So I've taken the more general implementation from tree-ssa-dom.c and
conditionalized the handling of unexecutable edges on a flag and moved
the implementation into cfganal.c where it more naturally belongs.
Bootstrapped and regression tested on x86_64. OK for the trunk?
Jeff
[-- Attachment #2: P --]
[-- Type: text/plain, Size: 8811 bytes --]
* cfganal.c (single_incoming_edge_ignoring_loop_edges): New function
extracted from tree-ssa-dom.c.
* cfganal.h (single_incoming_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_incoming_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_incoming_edge_ignoring_loop_edges call.
* tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Use
single_incoming_edge_ignoring_loop_edges rather than open coding.
* tree-vrp.c (evrp_dom_walker::before_dom_children): Similarly.
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index c506067..14d94b2 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -1554,3 +1554,38 @@ single_pred_before_succ_order (void)
#undef MARK_VISITED
#undef VISITED_P
}
+
+/* Ignoring loop backedges, if BB has precisely one incoming edge then
+ return that edge. Otherwise return NULL. */
+edge
+single_incoming_edge_ignoring_loop_edges (basic_block bb,
+ bool ignore_unreachable)
+{
+ 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_unreachable
+ && (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;
+}
diff --git a/gcc/cfganal.h b/gcc/cfganal.h
index 39bb5e5..74975e5 100644
--- a/gcc/cfganal.h
+++ b/gcc/cfganal.h
@@ -77,5 +77,6 @@ extern void bitmap_intersection_of_preds (sbitmap, sbitmap *, basic_block);
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);
#endif /* GCC_CFGANAL_H */
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 06be69a..31f88b4 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -113,7 +113,6 @@ static void eliminate_redundant_computations (gimple_stmt_iterator *,
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> *);
@@ -1057,39 +1056,6 @@ record_equivalences_from_phis (basic_block bb)
}
}
-/* 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. */
@@ -1107,7 +1073,7 @@ record_equivalences_from_incoming_edge (basic_block bb,
the parent was followed. */
parent = get_immediate_dominator (CDI_DOMINATORS, bb);
- e = single_incoming_edge_ignoring_loop_edges (bb);
+ e = single_incoming_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. */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 306080b..1c99d3b 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -4847,34 +4847,18 @@ sccvn_dom_walker::after_dom_children (basic_block bb)
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_incoming_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
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 200ec70..4cc7714 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -408,40 +408,10 @@ uncprop_into_successor_phis (basic_block bb)
}
}
-/* 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
@@ -450,7 +420,7 @@ uncprop_dom_walker::before_dom_children (basic_block bb)
parent = get_immediate_dominator (CDI_DOMINATORS, bb);
if (parent)
{
- e = single_incoming_edge_ignoring_loop_edges (bb);
+ edge e = single_incoming_edge_ignoring_loop_edges (bb, false);
if (e && e->src == parent && e->aux)
{
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 63ee156..39e9156 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -10970,33 +10970,17 @@ evrp_dom_walker::try_find_new_range (tree name,
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_incoming_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))
@@ -11040,6 +11024,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
/* 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))
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA][PATCH] Refactor duplicated code used by various dom walkers
2017-11-03 3:49 [RFA][PATCH] Refactor duplicated code used by various dom walkers Jeff Law
@ 2017-11-03 10:05 ` Richard Biener
2017-11-03 15:01 ` Jeff Law
0 siblings, 1 reply; 4+ messages in thread
From: Richard Biener @ 2017-11-03 10:05 UTC (permalink / raw)
To: Jeff Law; +Cc: gcc-patches
On Fri, Nov 3, 2017 at 4:49 AM, Jeff Law <law@redhat.com> wrote:
>
>
>
> Several passes which perform dominator walks want to identify when block has
> a single incoming edge, ignoring loop backedges.
>
> I'm aware of 4 implementations of this code. 3 of the 4 are identical in
> function. The 4th (tree-ssa-dom.c) has an additional twist that it also
> ignores edges that are not marked as executable.
>
> So I've taken the more general implementation from tree-ssa-dom.c and
> conditionalized the handling of unexecutable edges on a flag and moved the
> implementation into cfganal.c where it more naturally belongs.
>
> Bootstrapped and regression tested on x86_64. OK for the trunk?
Minor nits (sorry...)
> Jeff
>
> * cfganal.c (single_incoming_edge_ignoring_loop_edges): New function
> extracted from tree-ssa-dom.c.
> * cfganal.h (single_incoming_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_incoming_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_incoming_edge_ignoring_loop_edges call.
> * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Use
> single_incoming_edge_ignoring_loop_edges rather than open coding.
> * tree-vrp.c (evrp_dom_walker::before_dom_children): Similarly.
>
>
>
>
>
> diff --git a/gcc/cfganal.c b/gcc/cfganal.c
> index c506067..14d94b2 100644
> --- a/gcc/cfganal.c
> +++ b/gcc/cfganal.c
> @@ -1554,3 +1554,38 @@ single_pred_before_succ_order (void)
> #undef MARK_VISITED
> #undef VISITED_P
> }
> +
> +/* Ignoring loop backedges, if BB has precisely one incoming edge then
> + return that edge. Otherwise return NULL. */
> +edge
> +single_incoming_edge_ignoring_loop_edges (basic_block bb,
> + bool ignore_unreachable)
single_pred_edge_ignoring_loop_edges and ignore_not_executable
to better match existing CFG functions and actual edge flag use.
Ok with that change.
Thanks,
Richard.
> +{
> + 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_unreachable
> + && (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;
> +}
> diff --git a/gcc/cfganal.h b/gcc/cfganal.h
> index 39bb5e5..74975e5 100644
> --- a/gcc/cfganal.h
> +++ b/gcc/cfganal.h
> @@ -77,5 +77,6 @@ extern void bitmap_intersection_of_preds (sbitmap, sbitmap
> *, basic_block);
> 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);
>
> #endif /* GCC_CFGANAL_H */
> diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
> index 06be69a..31f88b4 100644
> --- a/gcc/tree-ssa-dom.c
> +++ b/gcc/tree-ssa-dom.c
> @@ -113,7 +113,6 @@ static void eliminate_redundant_computations
> (gimple_stmt_iterator *,
> 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>
> *);
>
> @@ -1057,39 +1056,6 @@ record_equivalences_from_phis (basic_block bb)
> }
> }
>
> -/* 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. */
> @@ -1107,7 +1073,7 @@ record_equivalences_from_incoming_edge (basic_block
> bb,
> the parent was followed. */
> parent = get_immediate_dominator (CDI_DOMINATORS, bb);
>
> - e = single_incoming_edge_ignoring_loop_edges (bb);
> + e = single_incoming_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. */
> diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
> index 306080b..1c99d3b 100644
> --- a/gcc/tree-ssa-sccvn.c
> +++ b/gcc/tree-ssa-sccvn.c
> @@ -4847,34 +4847,18 @@ sccvn_dom_walker::after_dom_children (basic_block
> bb)
> 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_incoming_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
> diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
> index 200ec70..4cc7714 100644
> --- a/gcc/tree-ssa-uncprop.c
> +++ b/gcc/tree-ssa-uncprop.c
> @@ -408,40 +408,10 @@ uncprop_into_successor_phis (basic_block bb)
> }
> }
>
> -/* 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
> @@ -450,7 +420,7 @@ uncprop_dom_walker::before_dom_children (basic_block bb)
> parent = get_immediate_dominator (CDI_DOMINATORS, bb);
> if (parent)
> {
> - e = single_incoming_edge_ignoring_loop_edges (bb);
> + edge e = single_incoming_edge_ignoring_loop_edges (bb, false);
>
> if (e && e->src == parent && e->aux)
> {
> diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
> index 63ee156..39e9156 100644
> --- a/gcc/tree-vrp.c
> +++ b/gcc/tree-vrp.c
> @@ -10970,33 +10970,17 @@ evrp_dom_walker::try_find_new_range (tree name,
> 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_incoming_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))
> @@ -11040,6 +11024,8 @@ evrp_dom_walker::before_dom_children (basic_block
> bb)
>
> /* 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))
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA][PATCH] Refactor duplicated code used by various dom walkers
2017-11-03 10:05 ` Richard Biener
@ 2017-11-03 15:01 ` Jeff Law
2017-11-03 16:29 ` Jeff Law
0 siblings, 1 reply; 4+ messages in thread
From: Jeff Law @ 2017-11-03 15:01 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches
On 11/03/2017 04:05 AM, Richard Biener wrote:
> On Fri, Nov 3, 2017 at 4:49 AM, Jeff Law <law@redhat.com> wrote:
>>
>>
>>
>> Several passes which perform dominator walks want to identify when block has
>> a single incoming edge, ignoring loop backedges.
>>
>> I'm aware of 4 implementations of this code. 3 of the 4 are identical in
>> function. The 4th (tree-ssa-dom.c) has an additional twist that it also
>> ignores edges that are not marked as executable.
>>
>> So I've taken the more general implementation from tree-ssa-dom.c and
>> conditionalized the handling of unexecutable edges on a flag and moved the
>> implementation into cfganal.c where it more naturally belongs.
>>
>> Bootstrapped and regression tested on x86_64. OK for the trunk?
>
> Minor nits (sorry...)
No need to apologize. I'm always appreciative of feedback as it
consistently improves what ultimately lands in the tree.
>
>> Jeff
>>
>> * cfganal.c (single_incoming_edge_ignoring_loop_edges): New function
>> extracted from tree-ssa-dom.c.
>> * cfganal.h (single_incoming_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_incoming_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_incoming_edge_ignoring_loop_edges call.
>> * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Use
>> single_incoming_edge_ignoring_loop_edges rather than open coding.
>> * tree-vrp.c (evrp_dom_walker::before_dom_children): Similarly.
>>
>>
>>
>>
>>
>> diff --git a/gcc/cfganal.c b/gcc/cfganal.c
>> index c506067..14d94b2 100644
>> --- a/gcc/cfganal.c
>> +++ b/gcc/cfganal.c
>> @@ -1554,3 +1554,38 @@ single_pred_before_succ_order (void)
>> #undef MARK_VISITED
>> #undef VISITED_P
>> }
>> +
>> +/* Ignoring loop backedges, if BB has precisely one incoming edge then
>> + return that edge. Otherwise return NULL. */
>> +edge
>> +single_incoming_edge_ignoring_loop_edges (basic_block bb,
>> + bool ignore_unreachable)
>
> single_pred_edge_ignoring_loop_edges and ignore_not_executable
>
> to better match existing CFG functions and actual edge flag use.
>
> Ok with that change.
Sure. Easy to change.
Jeff
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA][PATCH] Refactor duplicated code used by various dom walkers
2017-11-03 15:01 ` Jeff Law
@ 2017-11-03 16:29 ` Jeff Law
0 siblings, 0 replies; 4+ messages in thread
From: Jeff Law @ 2017-11-03 16:29 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 3251 bytes --]
On 11/03/2017 09:01 AM, Jeff Law wrote:
> On 11/03/2017 04:05 AM, Richard Biener wrote:
>> On Fri, Nov 3, 2017 at 4:49 AM, Jeff Law <law@redhat.com> wrote:
>>>
>>>
>>>
>>> Several passes which perform dominator walks want to identify when
>>> block has
>>> a single incoming edge, ignoring loop backedges.
>>>
>>> I'm aware of 4 implementations of this code. 3 of the 4 are
>>> identical in
>>> function. The 4th (tree-ssa-dom.c) has an additional twist that it also
>>> ignores edges that are not marked as executable.
>>>
>>> So I've taken the more general implementation from tree-ssa-dom.c and
>>> conditionalized the handling of unexecutable edges on a flag and
>>> moved the
>>> implementation into cfganal.c where it more naturally belongs.
>>>
>>> Bootstrapped and regression tested on x86_64. OK for the trunk?
>>
>> Minor nits (sorry...)
> No need to apologize. I'm always appreciative of feedback as it
> consistently improves what ultimately lands in the tree.
>
>
>>
>>> Jeff
>>>
>>> Â Â Â Â Â Â Â Â * cfganal.c (single_incoming_edge_ignoring_loop_edges): New
>>> function
>>> Â Â Â Â Â Â Â Â extracted from tree-ssa-dom.c.
>>> Â Â Â Â Â Â Â Â * cfganal.h (single_incoming_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_incoming_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_incoming_edge_ignoring_loop_edges call.
>>> Â Â Â Â Â Â Â Â * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Use
>>> Â Â Â Â Â Â Â Â single_incoming_edge_ignoring_loop_edges rather than open
>>> coding.
>>> Â Â Â Â Â Â Â Â * tree-vrp.c (evrp_dom_walker::before_dom_children): Similarly.
>>>
>>>
>>>
>>>
>>>
>>> diff --git a/gcc/cfganal.c b/gcc/cfganal.c
>>> index c506067..14d94b2 100644
>>> --- a/gcc/cfganal.c
>>> +++ b/gcc/cfganal.c
>>> @@ -1554,3 +1554,38 @@ single_pred_before_succ_order (void)
>>> Â #undef MARK_VISITED
>>> Â #undef VISITED_P
>>> Â }
>>> +
>>> +/* Ignoring loop backedges, if BB has precisely one incoming edge then
>>> +  return that edge. Otherwise return NULL. */
>>> +edge
>>> +single_incoming_edge_ignoring_loop_edges (basic_block bb,
>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â bool ignore_unreachable)
>>
>> single_pred_edge_ignoring_loop_edges and ignore_not_executable
>>
>> to better match existing CFG functions and actual edge flag use.
>>
>> Ok with that change.
> Sure. Easy to change.
Final patch attached for archival purposes. I took the liberty of also
documenting the new IGNORE_NOT_EXECUTABLE argument.
Jeff
[-- Attachment #2: P --]
[-- Type: text/plain, Size: 10377 bytes --]
commit 1477a5a7a0a0a93cb8b1c79581134b8ccdca072b
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri Nov 3 16:28:28 2017 +0000
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254383 138bc75d-0d04-0410-961f-82ee72b054a4
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 83dbaaaa8bf..2fc7db44f7b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+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.
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index c506067fdcd..8bf8a53fa58 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -1554,3 +1554,42 @@ single_pred_before_succ_order (void)
#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;
+}
diff --git a/gcc/cfganal.h b/gcc/cfganal.h
index 39bb5e547a5..c5cb51d9cf8 100644
--- a/gcc/cfganal.h
+++ b/gcc/cfganal.h
@@ -77,5 +77,8 @@ extern void bitmap_intersection_of_preds (sbitmap, sbitmap *, basic_block);
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 */
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 06be69a530c..eb85b4a09ad 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -113,7 +113,6 @@ static void eliminate_redundant_computations (gimple_stmt_iterator *,
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> *);
@@ -1057,39 +1056,6 @@ record_equivalences_from_phis (basic_block bb)
}
}
-/* 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. */
@@ -1107,7 +1073,7 @@ record_equivalences_from_incoming_edge (basic_block bb,
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. */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 306080b6a41..f5bc28efa70 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -4847,34 +4847,18 @@ sccvn_dom_walker::after_dom_children (basic_block bb)
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
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 200ec70c9b7..35a49d28420 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -408,40 +408,10 @@ uncprop_into_successor_phis (basic_block bb)
}
}
-/* 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
@@ -450,7 +420,7 @@ uncprop_dom_walker::before_dom_children (basic_block bb)
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)
{
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 63ee1568990..541c5c4eaf9 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -10970,33 +10970,17 @@ evrp_dom_walker::try_find_new_range (tree name,
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))
@@ -11040,6 +11024,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
/* 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))
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-11-03 16:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-03 3:49 [RFA][PATCH] Refactor duplicated code used by various dom walkers Jeff Law
2017-11-03 10:05 ` Richard Biener
2017-11-03 15:01 ` Jeff Law
2017-11-03 16:29 ` Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).