diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range-path.cc | 114 | ||||
-rw-r--r-- | gcc/gimple-range-path.h | 22 | ||||
-rw-r--r-- | gcc/tree-ssa-dom.cc | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ch.cc | 12 | ||||
-rw-r--r-- | gcc/tree-ssa-threadbackward.cc | 20 | ||||
-rw-r--r-- | gcc/tree-ssa-threadedge.cc | 30 | ||||
-rw-r--r-- | gcc/tree-ssa-threadedge.h | 5 |
7 files changed, 106 insertions, 99 deletions
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index ff991b7..ba7c2ed 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -36,33 +36,52 @@ along with GCC; see the file COPYING3. If not see // Internal construct to help facilitate debugging of solver. #define DEBUG_SOLVER (dump_file && (param_threader_debug == THREADER_DEBUG_ALL)) -path_range_query::path_range_query (bool resolve, gimple_ranger *ranger) +path_range_query::path_range_query (gimple_ranger &ranger, + const vec<basic_block> &path, + const bitmap_head *dependencies, + bool resolve) : m_cache (new ssa_global_cache), m_has_cache_entry (BITMAP_ALLOC (NULL)), - m_resolve (resolve), - m_alloced_ranger (!ranger) + m_ranger (ranger), + m_resolve (resolve) { - if (m_alloced_ranger) - m_ranger = new gimple_ranger; - else - m_ranger = ranger; + m_oracle = new path_oracle (m_ranger.oracle ()); + + reset_path (path, dependencies); +} - m_oracle = new path_oracle (m_ranger->oracle ()); +path_range_query::path_range_query (gimple_ranger &ranger, bool resolve) + : m_cache (new ssa_global_cache), + m_has_cache_entry (BITMAP_ALLOC (NULL)), + m_ranger (ranger), + m_resolve (resolve) +{ + m_oracle = new path_oracle (m_ranger.oracle ()); +} - if (m_resolve && flag_checking) - verify_marked_backedges (cfun); +path_range_query::path_range_query (gimple_ranger &ranger, + edge e, + bool resolve) + : m_cache (new ssa_global_cache), + m_has_cache_entry (BITMAP_ALLOC (NULL)), + m_ranger (ranger), + m_resolve (resolve) +{ + m_oracle = new path_oracle (m_ranger.oracle ()); + auto_vec<basic_block> bbs (2); + bbs.quick_push (e->dest); + bbs.quick_push (e->src); + reset_path (bbs, NULL); } path_range_query::~path_range_query () { delete m_oracle; - if (m_alloced_ranger) - delete m_ranger; BITMAP_FREE (m_has_cache_entry); delete m_cache; } -// Return TRUE if NAME is an exit depenency for the path. +// Return TRUE if NAME is an exit dependency for the path. bool path_range_query::exit_dependency_p (tree name) @@ -153,7 +172,7 @@ path_range_query::range_on_path_entry (vrange &r, tree name) { gcc_checking_assert (defined_outside_path (name)); basic_block entry = entry_bb (); - m_ranger->range_on_entry (r, entry, name); + m_ranger.range_on_entry (r, entry, name); } // Return the range of NAME at the end of the path being analyzed. @@ -211,19 +230,19 @@ path_range_query::unreachable_path_p () return m_undefined_path; } -// Initialize the current path to PATH. The current block is set to -// the entry block to the path. -// -// Note that the blocks are in reverse order, so the exit block is -// path[0]. +// Reset the current path to PATH. void -path_range_query::set_path (const vec<basic_block> &path) +path_range_query::reset_path (const vec<basic_block> &path, + const bitmap_head *dependencies) { gcc_checking_assert (path.length () > 1); m_path = path.copy (); m_pos = m_path.length () - 1; + m_undefined_path = false; bitmap_clear (m_has_cache_entry); + + compute_ranges (dependencies); } bool @@ -248,7 +267,7 @@ path_range_query::ssa_range_in_phi (vrange &r, gphi *phi) if (at_entry ()) { - if (m_resolve && m_ranger->range_of_expr (r, name, phi)) + if (m_resolve && m_ranger.range_of_expr (r, name, phi)) return; // Try to fold the phi exclusively with global or cached values. @@ -290,7 +309,7 @@ path_range_query::ssa_range_in_phi (vrange &r, gphi *phi) range_on_path_entry (r, arg); else r.set_varying (TREE_TYPE (name)); - m_ranger->range_on_edge (tmp, e_in, arg); + m_ranger.range_on_edge (tmp, e_in, arg); r.intersect (tmp); return; } @@ -325,7 +344,7 @@ path_range_query::range_defined_in_block (vrange &r, tree name, basic_block bb) } if (bb && POINTER_TYPE_P (TREE_TYPE (name))) - m_ranger->m_cache.m_exit.maybe_adjust_range (r, name, bb); + m_ranger.m_cache.m_exit.maybe_adjust_range (r, name, bb); if (DEBUG_SOLVER && (bb || !r.varying_p ())) { @@ -441,7 +460,7 @@ path_range_query::compute_ranges_in_block (basic_block bb) p->reset_path (); } - gori_compute &g = m_ranger->gori (); + gori_compute &g = m_ranger.gori (); bitmap exports = g.exports (bb); EXECUTE_IF_AND_IN_BITMAP (m_exit_dependencies, exports, 0, i, bi) { @@ -495,7 +514,7 @@ path_range_query::adjust_for_non_null_uses (basic_block bb) else r.set_varying (TREE_TYPE (name)); - if (m_ranger->m_cache.m_exit.maybe_adjust_range (r, name, bb)) + if (m_ranger.m_cache.m_exit.maybe_adjust_range (r, name, bb)) set_cache (r, name); } } @@ -515,12 +534,11 @@ path_range_query::add_to_exit_dependencies (tree name, bitmap dependencies) // SSA names used to calculate the final conditional along the path. void -path_range_query::compute_exit_dependencies (bitmap dependencies, - const vec<basic_block> &path) +path_range_query::compute_exit_dependencies (bitmap dependencies) { // Start with the imports from the exit block... - basic_block exit = path[0]; - gori_compute &gori = m_ranger->gori (); + basic_block exit = m_path[0]; + gori_compute &gori = m_ranger.gori (); bitmap_copy (dependencies, gori.imports (exit)); auto_vec<tree> worklist (bitmap_count_bits (dependencies)); @@ -538,7 +556,7 @@ path_range_query::compute_exit_dependencies (bitmap dependencies, tree name = worklist.pop (); gimple *def_stmt = SSA_NAME_DEF_STMT (name); if (SSA_NAME_IS_DEFAULT_DEF (name) - || !path.contains (gimple_bb (def_stmt))) + || !m_path.contains (gimple_bb (def_stmt))) continue; if (gphi *phi = dyn_cast <gphi *> (def_stmt)) @@ -549,7 +567,7 @@ path_range_query::compute_exit_dependencies (bitmap dependencies, tree arg = gimple_phi_arg (phi, i)->def; if (TREE_CODE (arg) == SSA_NAME - && path.contains (e->src) + && m_path.contains (e->src) && bitmap_set_bit (dependencies, SSA_NAME_VERSION (arg))) worklist.safe_push (arg); } @@ -565,9 +583,9 @@ path_range_query::compute_exit_dependencies (bitmap dependencies, } // Exported booleans along the path, may help conditionals. if (m_resolve) - for (i = 0; i < path.length (); ++i) + for (i = 0; i < m_path.length (); ++i) { - basic_block bb = path[i]; + basic_block bb = m_path[i]; tree name; FOR_EACH_GORI_EXPORT_NAME (gori, bb, name) if (TREE_CODE (TREE_TYPE (name)) == BOOLEAN_TYPE) @@ -583,32 +601,28 @@ path_range_query::compute_exit_dependencies (bitmap dependencies, // calculated from the final conditional in the path. void -path_range_query::compute_ranges (const vec<basic_block> &path, - const bitmap_head *dependencies) +path_range_query::compute_ranges (const bitmap_head *dependencies) { if (DEBUG_SOLVER) fprintf (dump_file, "\n==============================================\n"); - set_path (path); - m_undefined_path = false; - if (dependencies) bitmap_copy (m_exit_dependencies, dependencies); else - compute_exit_dependencies (m_exit_dependencies, m_path); + compute_exit_dependencies (m_exit_dependencies); if (m_resolve) { path_oracle *p = get_path_oracle (); - p->reset_path (m_ranger->oracle ()); + p->reset_path (m_ranger.oracle ()); } if (DEBUG_SOLVER) { fprintf (dump_file, "path_range_query: compute_ranges for path: "); - for (unsigned i = path.length (); i > 0; --i) + for (unsigned i = m_path.length (); i > 0; --i) { - basic_block bb = path[i - 1]; + basic_block bb = m_path[i - 1]; fprintf (dump_file, "%d", bb->index); if (i > 1) fprintf (dump_file, "->"); @@ -636,18 +650,6 @@ path_range_query::compute_ranges (const vec<basic_block> &path, } } -// Convenience function to compute ranges along a path consisting of -// E->SRC and E->DEST. - -void -path_range_query::compute_ranges (edge e) -{ - auto_vec<basic_block> bbs (2); - bbs.quick_push (e->dest); - bbs.quick_push (e->src); - compute_ranges (bbs); -} - // A folding aid used to register and query relations along a path. // When queried, it returns relations as they would appear on exit to // the path. @@ -730,7 +732,7 @@ path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree) if (m_resolve) { fold_using_range f; - jt_fur_source src (stmt, this, &m_ranger->gori (), m_path); + jt_fur_source src (stmt, this, &m_ranger.gori (), m_path); if (!f.fold_stmt (r, stmt, src)) r.set_varying (type); } @@ -820,7 +822,7 @@ path_range_query::compute_outgoing_relations (basic_block bb, basic_block next) else gcc_unreachable (); - jt_fur_source src (NULL, this, &m_ranger->gori (), m_path); + jt_fur_source src (NULL, this, &m_ranger.gori (), m_path); src.register_outgoing_edges (cond, r, e0, e1); } } diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h index 3cb794e..483fde0 100644 --- a/gcc/gimple-range-path.h +++ b/gcc/gimple-range-path.h @@ -32,13 +32,14 @@ along with GCC; see the file COPYING3. If not see class path_range_query : public range_query { public: - path_range_query (bool resolve = true, class gimple_ranger *ranger = NULL); + path_range_query (class gimple_ranger &ranger, + const vec<basic_block> &path, + const bitmap_head *dependencies = NULL, + bool resolve = true); + path_range_query (gimple_ranger &ranger, bool resolve = true); + path_range_query (gimple_ranger &ranger, edge e, bool resolve = true); virtual ~path_range_query (); - void compute_ranges (const vec<basic_block> &, - const bitmap_head *dependencies = NULL); - void compute_ranges (edge e); - void compute_exit_dependencies (bitmap dependencies, - const vec<basic_block> &); + void reset_path (const vec<basic_block> &, const bitmap_head *dependencies); bool range_of_expr (vrange &r, tree name, gimple * = NULL) override; bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override; bool unreachable_path_p (); @@ -47,6 +48,8 @@ public: private: bool internal_range_of_expr (vrange &r, tree name, gimple *); + void compute_ranges (const bitmap_head *dependencies); + void compute_exit_dependencies (bitmap_head *dependencies); bool defined_outside_path (tree name); void range_on_path_entry (vrange &r, tree name); path_oracle *get_path_oracle () { return (path_oracle *)m_oracle; } @@ -71,7 +74,6 @@ private: bool relations_may_be_invalidated (edge); // Path navigation. - void set_path (const vec<basic_block> &); basic_block entry_bb () { return m_path[m_path.length () - 1]; } basic_block exit_bb () { return m_path[0]; } basic_block curr_bb () { return m_path[m_pos]; } @@ -99,7 +101,7 @@ private: // A ranger used to resolve ranges for SSA names whose values come // from outside the path. - gimple_ranger *m_ranger; + gimple_ranger &m_ranger; // Current path position. unsigned m_pos; @@ -109,10 +111,6 @@ private: // Set if there were any undefined expressions while pre-calculating path. bool m_undefined_path; - - // True if m_ranger was allocated in this class and must be freed at - // destruction. - bool m_alloced_ranger; }; #endif // GCC_TREE_SSA_THREADSOLVER_H diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc index 44dc27b..513e0c8 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -798,7 +798,7 @@ pass_dominator::execute (function *fun) /* Recursively walk the dominator tree optimizing statements. */ gimple_ranger *ranger = enable_ranger (fun); - path_range_query path_query (/*resolve=*/true, ranger); + path_range_query path_query (*ranger); dom_jt_simplifier simplifier (avail_exprs_stack, ranger, &path_query); dom_jt_state state (const_and_copies, avail_exprs_stack); jump_threader threader (&simplifier, &state); diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 3b91a89..96816b8 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see be statically determined. */ static bool -entry_loop_condition_is_static (class loop *l, path_range_query *query) +entry_loop_condition_is_static (class loop *l, gimple_ranger *ranger) { edge e = loop_preheader_edge (l); gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest)); @@ -72,8 +72,8 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query) desired_static_value = boolean_true_node; int_range<2> r; - query->compute_ranges (e); - query->range_of_stmt (r, last); + path_range_query query (*ranger, e); + query.range_of_stmt (r, last); return r == int_range<2> (desired_static_value, desired_static_value); } @@ -385,7 +385,7 @@ ch_base::copy_headers (function *fun) auto_vec<std::pair<edge, loop_p> > copied; mark_dfs_back_edges (); - path_range_query *query = new path_range_query; + gimple_ranger *ranger = new gimple_ranger; for (auto loop : loops_list (cfun, 0)) { int initial_limit = param_max_loop_header_insns; @@ -409,7 +409,7 @@ ch_base::copy_headers (function *fun) iteration. */ if (optimize_loop_for_size_p (loop) && !loop->force_vectorize - && !entry_loop_condition_is_static (loop, query)) + && !entry_loop_condition_is_static (loop, ranger)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, @@ -422,7 +422,7 @@ ch_base::copy_headers (function *fun) candidates.safe_push (loop); } /* Do not use ranger after we change the IL and not have updated SSA. */ - delete query; + delete ranger; for (auto loop : candidates) { diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc index 7698e1f..3218ad9 100644 --- a/gcc/tree-ssa-threadbackward.cc +++ b/gcc/tree-ssa-threadbackward.cc @@ -116,7 +116,6 @@ private: virtual void dump (FILE *out); back_threader_registry m_registry; - path_range_query *m_solver; // Current path being analyzed. auto_vec<basic_block> m_path; @@ -136,6 +135,8 @@ private: // with the ranger. Otherwise, unknown SSA names are assumed to be // VARYING. Setting to true is more precise but slower. function *m_fun; + // Ranger for the path solver. + gimple_ranger *m_ranger; unsigned m_flags; // Set to TRUE for the first of each thread[12] pass or the first of // each threadfull[12] pass. This is used to differentiate between @@ -162,13 +163,13 @@ back_threader::back_threader (function *fun, unsigned flags, bool first) // The path solver needs EDGE_DFS_BACK in resolving mode. if (flags & BT_RESOLVE) mark_dfs_back_edges (); - m_solver = new path_range_query (flags & BT_RESOLVE); + + m_ranger = new gimple_ranger; } back_threader::~back_threader () { - delete m_solver; - + delete m_ranger; loop_optimizer_finalize (); } @@ -305,8 +306,8 @@ back_threader::find_taken_edge_switch (const vec<basic_block> &path, tree name = gimple_switch_index (sw); int_range_max r; - m_solver->compute_ranges (path, m_imports); - m_solver->range_of_expr (r, name, sw); + path_range_query solver (*m_ranger, path, m_imports, m_flags & BT_RESOLVE); + solver.range_of_expr (r, name, sw); if (r.undefined_p ()) return UNREACHABLE_EDGE; @@ -329,10 +330,10 @@ back_threader::find_taken_edge_cond (const vec<basic_block> &path, { int_range_max r; - m_solver->compute_ranges (path, m_imports); - m_solver->range_of_stmt (r, cond); + path_range_query solver (*m_ranger, path, m_imports, m_flags & BT_RESOLVE); + solver.range_of_stmt (r, cond); - if (m_solver->unreachable_path_p ()) + if (solver.unreachable_path_p ()) return UNREACHABLE_EDGE; int_range<2> true_range (boolean_true_node, boolean_true_node); @@ -583,7 +584,6 @@ debug (const vec <basic_block> &path) void back_threader::dump (FILE *out) { - m_solver->dump (out); fprintf (out, "\nCandidates for pre-computation:\n"); fprintf (out, "===================================\n"); diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc index e64e4f2..905a98c 100644 --- a/gcc/tree-ssa-threadedge.cc +++ b/gcc/tree-ssa-threadedge.cc @@ -1399,7 +1399,6 @@ jt_state::register_equivs_stmt (gimple *stmt, basic_block bb, // Hybrid threader implementation. - hybrid_jt_simplifier::hybrid_jt_simplifier (gimple_ranger *r, path_range_query *q) { @@ -1411,7 +1410,12 @@ tree hybrid_jt_simplifier::simplify (gimple *stmt, gimple *, basic_block, jt_state *state) { - compute_ranges_from_state (stmt, state); + auto_bitmap dependencies; + auto_vec<basic_block> path; + + state->get_path (path); + compute_exit_dependencies (dependencies, path, stmt); + m_query->reset_path (path, dependencies); if (gimple_code (stmt) == GIMPLE_COND || gimple_code (stmt) == GIMPLE_ASSIGN) @@ -1432,22 +1436,25 @@ hybrid_jt_simplifier::simplify (gimple *stmt, gimple *, basic_block, return NULL; } -// Use STATE to generate the list of imports needed for the solver, -// and calculate the ranges along the path. +// Calculate the set of exit dependencies for a path and statement to +// be simplified. This is different than the +// compute_exit_dependencies in the path solver because the forward +// threader asks questions about statements not necessarily in the +// path. Using the default compute_exit_dependencies in the path +// solver gets noticeably less threads. void -hybrid_jt_simplifier::compute_ranges_from_state (gimple *stmt, jt_state *state) +hybrid_jt_simplifier::compute_exit_dependencies (bitmap dependencies, + const vec<basic_block> &path, + gimple *stmt) { - auto_bitmap imports; gori_compute &gori = m_ranger->gori (); - state->get_path (m_path); - // Start with the imports to the final conditional. - bitmap_copy (imports, gori.imports (m_path[0])); + bitmap_copy (dependencies, gori.imports (path[0])); // Add any other interesting operands we may have missed. - if (gimple_bb (stmt) != m_path[0]) + if (gimple_bb (stmt) != path[0]) { for (unsigned i = 0; i < gimple_num_ops (stmt); ++i) { @@ -1455,8 +1462,7 @@ hybrid_jt_simplifier::compute_ranges_from_state (gimple *stmt, jt_state *state) if (op && TREE_CODE (op) == SSA_NAME && Value_Range::supports_type_p (TREE_TYPE (op))) - bitmap_set_bit (imports, SSA_NAME_VERSION (op)); + bitmap_set_bit (dependencies, SSA_NAME_VERSION (op)); } } - m_query->compute_ranges (m_path, imports); } diff --git a/gcc/tree-ssa-threadedge.h b/gcc/tree-ssa-threadedge.h index ca70b33..790ac2e 100644 --- a/gcc/tree-ssa-threadedge.h +++ b/gcc/tree-ssa-threadedge.h @@ -69,11 +69,12 @@ public: tree simplify (gimple *stmt, gimple *, basic_block, jt_state *) override; private: - void compute_ranges_from_state (gimple *stmt, jt_state *); + void compute_exit_dependencies (bitmap dependencies, + const vec<basic_block> &path, + gimple *stmt); gimple_ranger *m_ranger; path_range_query *m_query; - auto_vec<basic_block> m_path; }; // This is the high level threader. The entry point is |