public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aldyh/heads/ranger-staging)] Change the loop extraction nterface to SCEV and cleanup gimple-ssa-evrp.c
@ 2020-09-26 3:40 Andrew Macleod
0 siblings, 0 replies; only message in thread
From: Andrew Macleod @ 2020-09-26 3:40 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:c231d9e9518ce8e0ac35501c3323b4b4f54226fe
commit c231d9e9518ce8e0ac35501c3323b4b4f54226fe
Author: Andrew MacLeod <amacleod@redhat.com>
Date: Fri Sep 25 23:39:16 2020 -0400
Change the loop extraction nterface to SCEV and cleanup gimple-ssa-evrp.c
Diff:
---
gcc/gimple-range-trace.h | 5 +-
gcc/gimple-range.cc | 88 +++++++++++-----------------------
gcc/gimple-range.h | 6 +--
gcc/gimple-ssa-evrp.c | 111 ++++++++++++++++++++-----------------------
gcc/gimple-ssa-warn-alloca.c | 2 +-
gcc/tree-vrp.c | 14 ------
6 files changed, 83 insertions(+), 143 deletions(-)
diff --git a/gcc/gimple-range-trace.h b/gcc/gimple-range-trace.h
index 77f5fd37c2b..6ccb822b325 100644
--- a/gcc/gimple-range-trace.h
+++ b/gcc/gimple-range-trace.h
@@ -1,7 +1,7 @@
class trace_ranger : public gimple_ranger
{
public:
- trace_ranger (bool use_loop_info);
+ trace_ranger ();
virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
virtual bool range_of_expr (irange &r, tree name, gimple *s = NULL);
virtual bool range_on_edge (irange &r, edge e, tree name);
@@ -21,8 +21,7 @@ private:
// trace_ranger implementation.
inline
-trace_ranger::trace_ranger (bool use_loop_info)
- : gimple_ranger (use_loop_info)
+trace_ranger::trace_ranger ()
{
indent = 0;
trace_count = 0;
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 032b039ffa5..682dcfb16a8 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -475,34 +475,16 @@ gimple_ranger::range_of_phi (irange &r, gphi *phi)
{
tree phi_def = gimple_phi_result (phi);
tree type = TREE_TYPE (phi_def);
- int_range_max phi_range;
+ int_range_max arg_range;
unsigned x;
if (!irange::supports_type_p (type))
return false;
- if (loop_aware_p ())
- {
- // If there is no global range for a PHI, start the party with
- // whatever information SCEV may have.
- tree phi_result = PHI_RESULT (phi);
- if (!POINTER_TYPE_P (TREE_TYPE (phi_result))
- && !m_cache.m_globals.get_global_range (r, phi_result)
- && range_with_loop_info (r, phi_result))
- {
- value_range loop_range;
- get_range_info (phi_result, loop_range);
- r.intersect (loop_range);
- if (!r.varying_p ())
- set_range_info (phi_result, r);
- }
- }
-
- // And start with an empty range, unioning in each argument's range.
+ // start with an empty range, unioning in each argument's range.
r.set_undefined ();
for (x = 0; x < gimple_phi_num_args (phi); x++)
{
- int_range_max arg_range;
tree arg = gimple_phi_arg_def (phi, x);
edge e = gimple_phi_arg_edge (phi, x);
@@ -513,6 +495,31 @@ gimple_ranger::range_of_phi (irange &r, gphi *phi)
break;
}
+ // If SCEV is available, query if this PHI has any knonwn values.
+ if (scev_initialized_p () && !POINTER_TYPE_P (TREE_TYPE (phi_def)))
+ {
+ value_range loop_range;
+ class loop *l = loop_containing_stmt (phi);
+ if (l)
+ {
+ range_of_ssa_name_with_loop_info (loop_range, phi_def, l, phi);
+ if (!loop_range.varying_p ())
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Loops range found for ");
+ print_generic_expr (dump_file, phi_def, TDF_SLIM);
+ fprintf (dump_file, ": ");
+ loop_range.dump (dump_file);
+ fprintf (dump_file, " and calculated range :");
+ r.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ r.intersect (loop_range);
+ }
+ }
+ }
+
return true;
}
@@ -931,12 +938,6 @@ gimple_ranger::range_on_edge (irange &r, edge e, tree name)
if (m_cache.outgoing_edge_range_p (edge_range, e, name))
r.intersect (edge_range);
- if (loop_aware_p ())
- {
- int_range<2> loop_range;
- if (range_with_loop_info (loop_range, name))
- r.intersect (loop_range);
- }
return true;
}
@@ -1132,38 +1133,3 @@ gimple_ranger::range_of_ssa_name_with_loop_info (irange &r, tree name,
else
r.set_varying (type);
}
-
-// If NAME is either a PHI result or a PHI argument, see if we can
-// determine range information by querying loop info. If so, return
-// TRUE and set the range in R.
-
-bool
-gimple_ranger::range_with_loop_info (irange &r, tree name)
-{
- if (!scev_initialized_p ())
- return false;
-
- gimple *def = SSA_NAME_DEF_STMT (name);
- class loop *l = loop_containing_stmt (def);
- if (!l)
- return false;
-
- basic_block header = l->header;
- for (gphi_iterator iter = gsi_start_phis (header);
- !gsi_end_p (iter); gsi_next (&iter))
- {
- gphi *phi = iter.phi ();
- if (PHI_RESULT (phi) == name)
- {
- range_of_ssa_name_with_loop_info (r, name, l, phi);
- return true;
- }
- for (size_t i = 0; i < gimple_phi_num_args (phi); ++i)
- if (PHI_ARG_DEF (phi, i) == name)
- {
- range_of_ssa_name_with_loop_info (r, name, l, phi);
- return true;
- }
- }
- return false;
-}
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index b67aded30cb..9a421cc319f 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -46,8 +46,7 @@ along with GCC; see the file COPYING3. If not see
class gimple_ranger : public range_query
{
public:
- gimple_ranger (bool use_loop_info) : m_cache (*this),
- m_use_loop_info (use_loop_info) { }
+ gimple_ranger () : m_cache (*this) { }
virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL) OVERRIDE;
virtual bool range_of_expr (irange &r, tree name, gimple * = NULL) OVERRIDE;
virtual bool range_on_edge (irange &r, edge e, tree name) OVERRIDE;
@@ -69,9 +68,6 @@ private:
bool range_with_loop_info (irange &r, tree name);
void range_of_ssa_name_with_loop_info (irange &, tree, class loop *,
gphi *);
- bool loop_aware_p () { return m_use_loop_info; }
-
- bool m_use_loop_info;
};
// Calculate a basic range for a tree expression.
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index dff78116337..3088a388374 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -44,6 +44,9 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-range.h"
#include "gimple-range-trace.h"
+// This is the classic EVRP folder which uses a dominator walk and pushes
+// ranges into the next block if it is a single predecessor block.
+
class evrp_folder : public substitute_and_fold_engine
{
public:
@@ -106,8 +109,9 @@ protected:
simplify_using_ranges simplifier;
};
-// -------------------------------------------------------------------------
-
+// This is a ranger based folder which continues to use the dominator
+// walk to access the substitute and fold machinery. Ranges are calculated
+// on demand.
class rvrp_folder : public substitute_and_fold_engine
{
@@ -117,9 +121,9 @@ public:
{
if (flag_evrp_mode == EVRP_MODE_RVRP_TRACE
|| flag_evrp_mode == EVRP_MODE_RVRP_DEBUG)
- m_ranger = new trace_ranger (true);
+ m_ranger = new trace_ranger ();
else
- m_ranger = new gimple_ranger (true);
+ m_ranger = new gimple_ranger ();
m_simplifier.set_range_query (m_ranger);
}
@@ -138,7 +142,6 @@ public:
return m_ranger->value_of_stmt (s, name);
}
-
~rvrp_folder ()
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -152,28 +155,38 @@ public:
}
private:
+ DISABLE_COPY_AND_ASSIGN (rvrp_folder);
gimple_ranger *m_ranger;
simplify_using_ranges m_simplifier;
};
-
-
// In a hybrid folder, start with an EVRP folder, and add the required fold_stmt
// bits do either try the ranger first or second.
+//
+// The 3 value_* routines will always query both EVRP and the ranger for
+// a result, and ensure they return the same value. If either returns a value
+// when the other doesn't it is flagged in the listing, and the discoverd
+// value is returned.
+//
+// The simplifier is unable to process 2 different sources, thus we try to
+// use one engine, and if it fails to simplify, try using the other engine.
+// It is reported when the first attempt fails and the second succeeds.
class hybrid_folder : public evrp_folder
{
public:
- hybrid_folder () :
- evrp_folder (),
- m_ranger (&m_range_analyzer),
- m_evrp_try_first (flag_evrp_mode == EVRP_MODE_EVRP_FIRST)
+ hybrid_folder (bool evrp_first)
{
- // Default to the hybrid evaluator if we should try it first
- if (!m_evrp_try_first)
- {
- simplifier.set_range_query (&m_ranger);
- }
+ if (evrp_first)
+ {
+ first = &m_range_analyzer;
+ second = &m_ranger;
+ }
+ else
+ {
+ first = &m_ranger;
+ second = &m_range_analyzer;
+ }
}
~hybrid_folder ()
@@ -182,49 +195,35 @@ public:
m_ranger.dump (dump_file);
}
- tree value_of_expr (tree name, gimple * = NULL) OVERRIDE;
- tree value_on_edge (edge, tree name) OVERRIDE;
- tree value_of_stmt (gimple *, tree name = NULL) OVERRIDE;
-
bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE
- {
- if (m_evrp_try_first)
- {
- simplifier.set_range_query (&m_range_analyzer);
- if (simplifier.simplify (gsi))
- return true;
-
- simplifier.set_range_query (&m_ranger);
- if (simplifier.simplify (gsi))
- {
- if (dump_file)
- fprintf (dump_file, "EVRP:hybrid: RVRP simplifed stmt\n");
- return true;
- }
- return false;
- }
+ {
+ simplifier.set_range_query (first);
+ if (simplifier.simplify (gsi))
+ return true;
- simplifier.set_range_query (&m_ranger);
- if (simplifier.simplify (gsi))
- return true;
+ simplifier.set_range_query (second);
+ if (simplifier.simplify (gsi))
+ {
+ if (dump_file)
+ fprintf (dump_file, "EVRP:hybrid: Second query simplifed stmt\n");
+ return true;
+ }
+ return false;
+ }
- simplifier.set_range_query (&m_range_analyzer);
- if (simplifier.simplify (gsi))
- {
- if (dump_file)
- fprintf (dump_file, "EVRP:hybrid: EVRP simplifed stmt\n");
- return true;
- }
- return false;
- }
+ tree value_of_expr (tree name, gimple *) OVERRIDE;
+ tree value_on_edge (edge, tree name) OVERRIDE;
+ tree value_of_stmt (gimple *, tree name) OVERRIDE;
private:
DISABLE_COPY_AND_ASSIGN (hybrid_folder);
gimple_ranger m_ranger;
- bool m_evrp_try_first;
+ range_query *first;
+ range_query *second;
tree choose_value (tree evrp_val, tree ranger_val);
};
+
tree
hybrid_folder::value_of_expr (tree op, gimple *stmt)
{
@@ -249,6 +248,9 @@ hybrid_folder::value_of_stmt (gimple *stmt, tree op)
return choose_value (evrp_ret, ranger_ret);
}
+// Given trees returned by EVRP and Ranger, choose/report the value to use
+// by the folder.
+
tree
hybrid_folder::choose_value (tree evrp_val, tree ranger_val)
{
@@ -286,9 +288,6 @@ hybrid_folder::choose_value (tree evrp_val, tree ranger_val)
return ranger_val;
}
-
-
-
/* Main entry point for the early vrp pass which is a simplified non-iterative
version of vrp where basic blocks are visited in dominance order. Value
ranges discovered in early vrp will also be used by ipa-vrp. */
@@ -309,12 +308,6 @@ execute_early_vrp ()
{
case EVRP_MODE_EVRP_ONLY:
{
- /* ?? We could do:
- evrp_range_analyzer range_analyzer;
- evrp_folder folder (range_analyzer);
- And then we wouldn't need we could instantiate
- substitute_and_fold_engine with the correct vr_values
- instead of calling set_range_query. */
evrp_folder folder;
folder.substitute_and_fold ();
break;
@@ -330,7 +323,7 @@ execute_early_vrp ()
case EVRP_MODE_EVRP_FIRST:
case EVRP_MODE_RVRP_FIRST:
{
- hybrid_folder folder;
+ hybrid_folder folder (flag_evrp_mode == EVRP_MODE_EVRP_FIRST);
folder.substitute_and_fold ();
break;
}
diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c
index 59b1bb5957f..44b22ff2fe3 100644
--- a/gcc/gimple-ssa-warn-alloca.c
+++ b/gcc/gimple-ssa-warn-alloca.c
@@ -264,7 +264,7 @@ in_loop_p (gimple *stmt)
unsigned int
pass_walloca::execute (function *fun)
{
- gimple_ranger ranger (false);
+ gimple_ranger ranger;
basic_block bb;
FOR_EACH_BB_FN (bb, fun)
{
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index bf45105ba57..eb8563b5423 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4586,20 +4586,6 @@ determine_value_range_1 (value_range *vr, tree expr, gimple *stmt)
vr->set (expr);
else
{
- /* ?? The check for cfun->cfg is because the ranger_cache
- constructor needs last_basic_block_for_fn.
-
- Whereas the check for gimple_body is because
- gimple_range_global() does not pick up global ranges. */
- if (cfun->cfg && cfun->gimple_body)
- {
- gimple_ranger ranger (true);
- if (!ranger.range_of_expr (*vr, expr, stmt))
- vr->set_varying (TREE_TYPE (expr));
- return;
- }
- /* ?? Simiarly here. The following code would be unnecessary if
- the block above would get global ranges. */
value_range_kind kind;
wide_int min, max;
/* For SSA names try to extract range info computed by VRP. Otherwise
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-09-26 3:40 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-26 3:40 [gcc(refs/users/aldyh/heads/ranger-staging)] Change the loop extraction nterface to SCEV and cleanup gimple-ssa-evrp.c Andrew Macleod
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).