aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-range-path.cc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2022-01-20 10:28:26 +0100
committerAldy Hernandez <aldyh@redhat.com>2022-01-21 11:19:07 +0100
commiteb5ee6464809e051e0292471597931a660485658 (patch)
tree6c6e3f240670f06d426fed1c8da1266618a4415d /gcc/gimple-range-path.cc
parentc2d9159717b474f9c06dde4d32b48b87164deb50 (diff)
downloadgcc-eb5ee6464809e051e0292471597931a660485658.zip
gcc-eb5ee6464809e051e0292471597931a660485658.tar.gz
gcc-eb5ee6464809e051e0292471597931a660485658.tar.bz2
Reset relations when crossing backedges.
As discussed in PR103721, the problem here is that we are crossing a backedge and causing us to use relations from a previous iteration of a loop. This handles the testcases in both PR103721 and PR104067 which are variants of the same thing. Tested on x86-64 Linux with the usual regstrap as well as verifying the thread count before and after the patch. The number of threads is reduced by a miniscule amount. gcc/ChangeLog: PR tree-optimization/103721 * gimple-range-path.cc (path_range_query::relations_may_be_invalidated): New. (path_range_query::compute_ranges_in_block): Reset relations if they may be invalidated. (path_range_query::maybe_register_phi_relation): Exit if relations may be invalidated on incoming edge. (path_range_query::compute_phi_relations): Pass incoming PHI edge to maybe_register_phi_relation. * gimple-range-path.h (relations_may_be_invalidated): New. (maybe_register_phi_relation): Pass edge instead of tree. * tree-ssa-threadbackward.cc (back_threader::back_threader): Mark DFS edges. * value-relation.cc (path_oracle::path_oracle): Call mark_dfs_back_edges. (path_oracle::register_relation): Add SSA names to m_registered bitmap. (path_oracle::reset_path): Clear m_registered bitmap. * value-relation.h (path_oracle::set_root_oracle): New. gcc/testsuite/ChangeLog: * gcc.dg/pr103721-2.c: New test. * gcc.dg/pr103721.c: New test.
Diffstat (limited to 'gcc/gimple-range-path.cc')
-rw-r--r--gcc/gimple-range-path.cc48
1 files changed, 42 insertions, 6 deletions
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index a1bcca0..3ee4989 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -400,6 +400,19 @@ path_range_query::compute_ranges_in_phis (basic_block bb)
bitmap_ior_into (m_has_cache_entry, phi_set);
}
+// Return TRUE if relations may be invalidated after crossing edge E.
+
+bool
+path_range_query::relations_may_be_invalidated (edge e)
+{
+ // As soon as the path crosses a back edge, we can encounter
+ // definitions of SSA_NAMEs that may have had a use in the path
+ // already, so this will then be a new definition. The relation
+ // code is all designed around seeing things in dominator order, and
+ // crossing a back edge in the path violates this assumption.
+ return (e->flags & EDGE_DFS_BACK);
+}
+
// Compute ranges defined in the current block, or exported to the
// next block.
@@ -440,6 +453,22 @@ path_range_query::compute_ranges_in_block (basic_block bb)
// Solve imports that are exported to the next block.
basic_block next = next_bb ();
edge e = find_edge (bb, next);
+
+ if (m_resolve && relations_may_be_invalidated (e))
+ {
+ if (DEBUG_SOLVER)
+ fprintf (dump_file,
+ "Resetting relations as they may be invalidated in %d->%d.\n",
+ e->src->index, e->dest->index);
+
+ path_oracle *p = get_path_oracle ();
+ p->reset_path ();
+ // ?? Instead of nuking the root oracle altogether, we could
+ // reset the path oracle to search for relations from the top of
+ // the loop with the root oracle. Something for future development.
+ p->set_root_oracle (nullptr);
+ }
+
EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
{
tree name = ssa_name (i);
@@ -742,9 +771,19 @@ path_range_query::range_of_stmt (irange &r, gimple *stmt, tree)
return true;
}
+// If possible, register the relation on the incoming edge E into PHI.
+
void
-path_range_query::maybe_register_phi_relation (gphi *phi, tree arg)
+path_range_query::maybe_register_phi_relation (gphi *phi, edge e)
{
+ tree arg = gimple_phi_arg_def (phi, e->dest_idx);
+
+ if (!gimple_range_ssa_p (arg))
+ return;
+
+ if (relations_may_be_invalidated (e))
+ return;
+
basic_block bb = gimple_bb (phi);
tree result = gimple_phi_result (phi);
@@ -754,7 +793,7 @@ path_range_query::maybe_register_phi_relation (gphi *phi, tree arg)
return;
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " from bb%d:", bb->index);
+ fprintf (dump_file, "maybe_register_phi_relation in bb%d:", bb->index);
get_path_oracle ()->killing_def (result);
m_oracle->register_relation (entry_bb (), EQ_EXPR, arg, result);
@@ -787,10 +826,7 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev)
for (size_t i = 0; i < nargs; ++i)
if (e_in == gimple_phi_arg_edge (phi, i))
{
- tree arg = gimple_phi_arg_def (phi, i);
-
- if (gimple_range_ssa_p (arg))
- maybe_register_phi_relation (phi, arg);
+ maybe_register_phi_relation (phi, e_in);
break;
}
}