aboutsummaryrefslogtreecommitdiff
path: root/gcc/vr-values.c
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2021-08-24 12:13:24 -0400
committerAndrew MacLeod <amacleod@redhat.com>2021-09-20 16:32:35 -0400
commit73cf73af2392e00917de042a4692f6a0b6329ee8 (patch)
tree6cd6cfb9b9569ddf87064cc4563655b74efd3135 /gcc/vr-values.c
parent5d110fe90afcd850ea21aee6429f22edd6b1b592 (diff)
downloadgcc-73cf73af2392e00917de042a4692f6a0b6329ee8.zip
gcc-73cf73af2392e00917de042a4692f6a0b6329ee8.tar.gz
gcc-73cf73af2392e00917de042a4692f6a0b6329ee8.tar.bz2
Use EDGE_EXECUTABLE in ranger and return UNDEFINED for those edges.
If an incoming edge is UNDEFINED, don't process it. Track if other edges equate to a single value, and add an equivalence if appropriate. gcc/ * gimple-range-fold.cc (fold_using_range::range_of_phi): Ignore undefined edges, apply an equivalence if appropriate. * gimple-range-gori.cc (gori_compute::outgoing_edge_range_p): Return UNDEFINED if EDGE_EXECUTABLE is not set. * gimple-range.cc (gimple_ranger::gimple_ranger): Set all edges as EXECUTABLE upon startup. (gimple_ranger::range_on_edge): Return UNDEFINED for edges without EDGE_EXECUTABLE set. * vr-values.c (set_and_propagate_unexecutable): New. (simplify_using_ranges::fold_cond): Call set_and_propagate. (simplify_using_ranges::simplify_switch_using_ranges): Ditto. * vr-values.h: Add prototype. gcc/testsuite/ * gcc.dg/tree-ssa/evrp-ignore.c: New.
Diffstat (limited to 'gcc/vr-values.c')
-rw-r--r--gcc/vr-values.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index c999ca8..3b8d067 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -3454,6 +3454,32 @@ range_fits_type_p (const value_range *vr,
return true;
}
+// Clear edge E of EDGE_EXECUTABLE (it is unexecutable). If it wasn't
+// previously clear, propagate to successor blocks if appropriate.
+
+void
+simplify_using_ranges::set_and_propagate_unexecutable (edge e)
+{
+ // If EXECUUTABLE is already clear, we're done.
+ if ((e->flags & EDGE_EXECUTABLE) == 0)
+ return;
+
+ e->flags &= ~EDGE_EXECUTABLE;
+
+ // Check if the destination block needs to propagate the property.
+ basic_block bb = e->dest;
+
+ // If any entry edge is marked EXECUTABLE, we are done.
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->flags & EDGE_EXECUTABLE)
+ return;
+
+ // This block is also unexecutable, propagate to all exit edges as well.
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ set_and_propagate_unexecutable (e);
+}
+
/* If COND can be folded entirely as TRUE or FALSE, rewrite the
conditional as such, and return TRUE. */
@@ -3467,18 +3493,27 @@ simplify_using_ranges::fold_cond (gcond *cond)
if (TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
&& TREE_CODE (gimple_cond_rhs (cond)) != SSA_NAME)
return false;
-
+ edge e0 = EDGE_SUCC (gimple_bb (cond), 0);
+ edge e1 = EDGE_SUCC (gimple_bb (cond), 1);
if (r.zero_p ())
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nPredicate evaluates to: 0\n");
gimple_cond_make_false (cond);
+ if (e0->flags & EDGE_TRUE_VALUE)
+ set_and_propagate_unexecutable (e0);
+ else
+ set_and_propagate_unexecutable (e1);
}
else
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nPredicate evaluates to: 1\n");
gimple_cond_make_true (cond);
+ if (e0->flags & EDGE_FALSE_VALUE)
+ set_and_propagate_unexecutable (e0);
+ else
+ set_and_propagate_unexecutable (e1);
}
update_stmt (cond);
return true;
@@ -3769,7 +3804,7 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
fprintf (dump_file, "removing unreachable case label\n");
}
to_remove_edges.safe_push (e);
- e->flags &= ~EDGE_EXECUTABLE;
+ set_and_propagate_unexecutable (e);
e->flags |= EDGE_IGNORE;
}