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).