diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2021-08-24 12:13:24 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2021-09-20 16:32:35 -0400 |
commit | 73cf73af2392e00917de042a4692f6a0b6329ee8 (patch) | |
tree | 6cd6cfb9b9569ddf87064cc4563655b74efd3135 /gcc/gimple-range-fold.cc | |
parent | 5d110fe90afcd850ea21aee6429f22edd6b1b592 (diff) | |
download | gcc-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/gimple-range-fold.cc')
-rw-r--r-- | gcc/gimple-range-fold.cc | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 997d02d..80cc5c0 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -760,6 +760,10 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) if (!type) return false; + // Track if all executable arguments are the same. + tree single_arg = NULL_TREE; + bool seen_arg = false; + // Start with an empty range, unioning in each argument's range. r.set_undefined (); for (x = 0; x < gimple_phi_num_args (phi); x++) @@ -767,19 +771,48 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) tree arg = gimple_phi_arg_def (phi, x); edge e = gimple_phi_arg_edge (phi, x); - // Register potential dependencies for stale value tracking. - if (gimple_range_ssa_p (arg) && src.gori ()) - src.gori ()->register_dependency (phi_def, arg); - // Get the range of the argument on its edge. src.get_phi_operand (arg_range, arg, e); - // If we're recomputing the argument elsewhere, try to refine it. - r.union_ (arg_range); + + if (!arg_range.undefined_p ()) + { + // Register potential dependencies for stale value tracking. + r.union_ (arg_range); + if (gimple_range_ssa_p (arg) && src.gori ()) + src.gori ()->register_dependency (phi_def, arg); + + // Track if all arguments are the same. + if (!seen_arg) + { + seen_arg = true; + single_arg = arg; + } + else if (single_arg != arg) + single_arg = NULL_TREE; + } + // Once the value reaches varying, stop looking. - if (r.varying_p ()) + if (r.varying_p () && single_arg == NULL_TREE) break; } + // If the PHI boils down to a single effective argument, look at it. + if (single_arg) + { + // Symbolic arguments are equivalences. + if (gimple_range_ssa_p (single_arg)) + src.register_relation (phi, EQ_EXPR, phi_def, single_arg); + else if (src.get_operand (arg_range, single_arg) + && arg_range.singleton_p ()) + { + // Numerical arguments that are a constant can be returned as + // the constant. This can help fold later cases where even this + // constant might have been UNDEFINED via an unreachable edge. + r = arg_range; + return true; + } + } + // If SCEV is available, query if this PHI has any knonwn values. if (scev_initialized_p () && !POINTER_TYPE_P (TREE_TYPE (phi_def))) { |