diff options
author | Andrew Macleod <amacleod@gcc.gnu.org> | 2019-05-02 20:35:56 +0000 |
---|---|---|
committer | Andrew Macleod <amacleod@gcc.gnu.org> | 2019-05-02 20:35:56 +0000 |
commit | d105b87c7a42b8c04d7a1efd061afba955c0b097 (patch) | |
tree | e351644d3bf01dde5c8c60c882563c1fa161e894 | |
parent | 90638b0f7e1993b8d8ca92ae7c1c012aba2ee299 (diff) | |
download | gcc-d105b87c7a42b8c04d7a1efd061afba955c0b097.zip gcc-d105b87c7a42b8c04d7a1efd061afba955c0b097.tar.gz gcc-d105b87c7a42b8c04d7a1efd061afba955c0b097.tar.bz2 |
Reworked the rvp driver a bit.
From-SVN: r270824
-rw-r--r-- | gcc/ssa-range-vrp.c | 85 | ||||
-rw-r--r-- | gcc/ssa-range.cc | 34 | ||||
-rw-r--r-- | gcc/ssa-range.h | 1 |
3 files changed, 81 insertions, 39 deletions
diff --git a/gcc/ssa-range-vrp.c b/gcc/ssa-range-vrp.c index 46a5db8..695107d 100644 --- a/gcc/ssa-range-vrp.c +++ b/gcc/ssa-range-vrp.c @@ -321,6 +321,7 @@ public: private: void run (); void visit (basic_block); + void fold_and_simplify (gimple_stmt_iterator &); dom_accumulator *m_dom_accumulator; auto_vec<basic_block> m_bbs; @@ -387,50 +388,64 @@ rvrp_engine::~rvrp_engine () } void -rvrp_engine::visit (basic_block bb) +rvrp_engine::fold_and_simplify (gimple_stmt_iterator &gsi) { + bool changed = false; irange r; + gimple *stmt = gsi_stmt (gsi); + + // Only process statements which are a COND expr or have a valid LHS. + if (gimple_code (stmt) != GIMPLE_COND && + !m_ranger->valid_ssa_p (gimple_get_lhs (stmt))) + return; + + // ?? This is only needed for propagate_mark_stmt_for_cleanup. + // Can we get away with a shallow copy? + gimple *old_stmt = gimple_copy (stmt); + + if (m_ranger->range_of_stmt (r, stmt)) + changed = rvrp_fold (*m_ranger, stmt, m_touched); + if (!changed) + changed = rvrp_simplify (*m_ranger, &gsi); + if (changed) + m_cleanups.record_change (old_stmt, stmt); +} - // If we're only looking at conditionals, there's no need to look at PHIs. - if (m_order != RVRP_ORDER_CONDITIONALS) - for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi); - gsi_next (&gpi)) - { - gphi *phi = gpi.phi (); - tree phi_def = gimple_phi_result (phi); - if (m_ranger->valid_ssa_p (phi_def)) - m_ranger->range_of_stmt (r, phi); - } +void +rvrp_engine::visit (basic_block bb) +{ + irange r; + gimple_stmt_iterator gsi; if (dump_file) fprintf (dump_file, "RVRP: Considering BB %d.\n", bb->index); - for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); - gsi_next (&gsi)) + if (m_order == RVRP_ORDER_CONDITIONALS) { - // When looking at conditionals, there's nothing interesting - // before the last statement. - if (m_order == RVRP_ORDER_CONDITIONALS && !gsi_one_before_end_p (gsi)) - continue; - - gimple *stmt = gsi_stmt (gsi); - tree lhs = gimple_get_lhs (stmt); - if (gimple_code (stmt) == GIMPLE_COND - || (m_order != RVRP_ORDER_CONDITIONALS - && m_ranger->valid_ssa_p (lhs))) - { - bool changed = false; - // ?? This is only needed for propagate_mark_stmt_for_cleanup. - // Can we get away with a shallow copy? - gimple *old_stmt = gimple_copy (stmt); - if (m_ranger->range_of_stmt (r, stmt)) - changed = rvrp_fold (*m_ranger, stmt, m_touched); - if (!changed) - changed = rvrp_simplify (*m_ranger, &gsi); - if (changed) - m_cleanups.record_change (old_stmt, stmt); - } + // Check if there is a conditional at the end of the block and visit it. + gsi = gsi_outgoing_range_stmt (bb); + if (!gsi_end_p (gsi)) + fold_and_simplify (gsi); + return; } + + // Process all the PHI nodes. + for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi); + gsi_next (&gpi)) + { + gphi *phi = gpi.phi (); + tree phi_def = gimple_phi_result (phi); + if (m_ranger->valid_ssa_p (phi_def)) + m_ranger->range_of_stmt (r, phi); + } + + // If processing in reverse, walk the IL bottom up. + if (m_order == RVRP_ORDER_BACKWARD) + for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) + fold_and_simplify (gsi); + else + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + fold_and_simplify (gsi); } void diff --git a/gcc/ssa-range.cc b/gcc/ssa-range.cc index 0dc04d6..2f2f52d 100644 --- a/gcc/ssa-range.cc +++ b/gcc/ssa-range.cc @@ -52,6 +52,10 @@ along with GCC; see the file COPYING3. If not see #include "alloc-pool.h" #include "vr-values.h" +// #define RANGER_SWITCH_NONE +// #define RANGER_SWITCH_CALC + + class switch_edge_manager { public: @@ -122,6 +126,17 @@ switch_edge_manager::get_range (irange &r, gimple *s, edge e, bool must_exist) if (!m_edge_table) init_ranges (); +#ifdef RANGER_SWITCH_NONE + // Turn off switch support in ranger + return NULL; +#endif + +#ifdef RANGER_SWITCH_CALC + // Calculate the switch edge each time. + calc_single_range (r, sw, e); + return s; +#endif + irange **val = m_edge_table->get (e); if (!val) { @@ -244,13 +259,24 @@ switch_edge_manager::calc_single_range (irange &r, gswitch *sw, edge e) // If there is a range control statment at the end of block BB, return it. +gimple_stmt_iterator +gsi_outgoing_range_stmt (basic_block bb) +{ + gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb); + if (!gsi_end_p (gsi)) + { + gimple *s = gsi_stmt (gsi); + if (is_a<gcond *> (s) || is_a<gswitch *> (s)) + return gsi; + } + return gsi_none (); +} + gimple * gimple_outgoing_range_stmt_p (basic_block bb) { - gimple *s = last_stmt (bb); - if (s && (is_a<gcond *> (s) || is_a<gswitch *> (s))) - return s; - return NULL; + // This will return NULL if there is not a branch statement. + return gsi_stmt (gsi_outgoing_range_stmt (bb)); } // Calculate the range forced on on edge E by control flow, if any, and diff --git a/gcc/ssa-range.h b/gcc/ssa-range.h index cb62c81..0d2e1f4 100644 --- a/gcc/ssa-range.h +++ b/gcc/ssa-range.h @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "ssa-range-gori.h" #include "ssa-range-cache.h" +extern gimple_stmt_iterator gsi_outgoing_range_stmt (basic_block bb); extern gimple *gimple_outgoing_range_stmt_p (basic_block bb); extern gimple *gimple_outgoing_edge_range_p (irange &r, edge e); extern bool get_tree_range (irange &r, tree expr); |