]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
pull range_of_ssa_nme out of range_of_expr, then combine get_tree_range with range_o...
authorAndrew Macleod <amacleod@gcc.gnu.org>
Wed, 4 Sep 2019 19:08:23 +0000 (19:08 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Wed, 4 Sep 2019 19:08:23 +0000 (19:08 +0000)
From-SVN: r275380

gcc/grange.cc
gcc/grange.h
gcc/ssa-range-cache.cc
gcc/ssa-range-gori.cc
gcc/ssa-range.cc
gcc/ssa-range.h

index 65c1f897000eb7d60c4472297568fd90abe39e8f..b7fe2dec6c1d229c0595377708d41905b1d01307 100644 (file)
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "wide-int.h"
 #include "range.h"
 #include "grange.h"
+#include "ssa-range.h"
 
 // This file implements the gimple range statement and associated data.
 // the grange_op statement kind provides access to the range-op fold machinery
@@ -60,55 +61,6 @@ along with GCC; see the file COPYING3.  If not see
 // table where a class is implemented for a given tree code, and
 // auto-registered into the table for use when it is encountered.
 
-// This function returns a range for tree node EXPR in R.  Return
-// false if ranges are not supported.
-
-irange
-get_tree_range (tree expr)
-{
-  tree type;
-  if (TYPE_P (expr))
-    type = expr;
-  else
-    type = TREE_TYPE (expr);
-
-  gcc_checking_assert (irange::supports_type_p (type));
-
-  switch (TREE_CODE (expr))
-    {
-      case INTEGER_CST:
-       // If we encounter an overflow, simply punt and drop to varying
-       // since we have no idea how it will be used.
-        if (!TREE_OVERFLOW_P (expr))
-         return irange (expr, expr);
-       break;
-
-      case SSA_NAME:
-        if (irange::supports_ssa_p (expr) && SSA_NAME_RANGE_INFO (expr)
-           && !POINTER_TYPE_P (type))
-         {
-           // Return a range from an SSA_NAME's available range.  
-           wide_int min, max;
-           enum value_range_kind kind = get_range_info (expr, &min, &max);
-           return irange (kind, type, min, max);
-         }
-       break;
-
-      case ADDR_EXPR:
-        {
-         // handle &var which can show up in phi arguments
-         bool ov;
-         if (tree_single_nonzero_warnv_p (expr, &ov))
-            return range_nonzero (type);
-         break;
-       }
-
-      default:
-        break;
-    }
-  return irange (type);
-}
-
 static gimple *
 calc_single_range (irange &r, gswitch *sw, edge e)
 {
index fa115bec10c8553e05278957e7777d999b3f5e8e..973e5a243d6194fdf20db5ae3aa2308b3902f376 100644 (file)
@@ -27,7 +27,6 @@ along with GCC; see the file COPYING3.  If not see
 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 irange get_tree_range (tree expr);
 
 static inline tree
 valid_range_ssa_p (tree exp)
@@ -37,6 +36,22 @@ valid_range_ssa_p (tree exp)
   return NULL_TREE;
 }
 
+static inline irange
+ssa_name_range (tree name)
+{
+  gcc_checking_assert (irange::supports_ssa_p (name));
+  tree type = TREE_TYPE (name);
+  if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
+    {
+      // Return a range from an SSA_NAME's available range.  
+      wide_int min, max;
+      enum value_range_kind kind = get_range_info (name, &min, &max);
+      return irange (kind, type, min, max);
+    }
+ // Otherwise return range for the type.
+ return irange (type);
+}
+
 // Gimple statement which supports range_op operations.
 // This can map to gimple assign or cond statements, so quick access to the
 // operands is provided so the user does not need to know which it is.
index 53af02bf03989c336cd56a735aa94fb4b7b5306c..72325b0090be8fb009680dafe29fcf51fd18ce87 100644 (file)
@@ -578,7 +578,7 @@ gori_cache::edge_range (irange &r, edge e, tree name)
        {
          // Try to pick up any known value first. 
          if (!m_globals.get_global_range (r, name))
-           r = get_tree_range (name);
+           r = ssa_name_range (name);
        }
     }
   else
index 8540fbab0e81b82fe7e14f183055a67a255fd6d5..a11241702db772eb22ba3bcbd153fe9a0bff9b6b 100644 (file)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "grange.h"
 #include "ssa-range-gori.h"
 #include "fold-const.h"
+#include "ssa-range.h"
 
 // Construct a range_def_chain
 
@@ -478,10 +479,14 @@ gori_map::dump(FILE *f)
 static irange
 get_tree_range (tree expr, tree name, irange *range_of_name)
 {
+  static stmt_ranger sr;
   if (expr != name || !range_of_name)
-    return get_tree_range (expr);
+    {
+      irange r;
+      gcc_assert (sr.range_of_expr (r, expr));
+      return r;
+    }
 
-  gcc_checking_assert (range_of_name != NULL);
   return *range_of_name;
 }
 
@@ -1128,7 +1133,7 @@ gori_compute::range_from_import (irange &r, tree name, irange &import_range)
        res = range_from_import (r1, op1, import_range);
     }
   else
-    r1 = get_tree_range (op1);
+    r1 = get_tree_range (op1, NULL_TREE, NULL);
 
   if (!res)
     return false;
@@ -1144,7 +1149,7 @@ gori_compute::range_from_import (irange &r, tree name, irange &import_range)
        res = range_from_import (r2, op2, import_range);
     }
   else
-    r2 = get_tree_range (op2);
+    r2 = get_tree_range (op2, NULL_TREE, NULL);
 
   if (res)
     return s->fold (r, r1, r2);
index a498329824f8aaaa854c2cada9d4fdee09ae6a5b..b0e93b182c626b168b8e18bf5cb5845a9259f12f 100644 (file)
@@ -65,14 +65,60 @@ stmt_ranger::~stmt_ranger ()
 {
 }
 
+irange
+stmt_ranger::range_of_ssa_name (tree name, gimple *s ATTRIBUTE_UNUSED)
+{
+  return ssa_name_range (name);
+}
+
 // This function returns a range for a tree node.  If optional statement S
 // is present, then the range would be if it were to appear as a use on S.
 // Return false if ranges are not supported.
 
 bool
-stmt_ranger::range_of_expr (irange &r, tree expr, gimple *s ATTRIBUTE_UNUSED)
+stmt_ranger::range_of_expr (irange &r, tree expr, gimple *s)
 {
-  r = get_tree_range (expr);
+  tree type;
+  if (TYPE_P (expr))
+    type = expr;
+  else
+    type = TREE_TYPE (expr);
+
+  if (!irange::supports_type_p (type))
+    return false;
+
+  switch (TREE_CODE (expr))
+    {
+      case INTEGER_CST:
+       // If we encounter an overflow, simply punt and drop to varying
+       // since we have no idea how it will be used.
+        if (!TREE_OVERFLOW_P (expr))
+         {
+           r = irange (expr, expr);
+           return true;
+         }
+       break;
+
+      case SSA_NAME:
+        r = range_of_ssa_name (expr, s);
+       return true;
+
+      case ADDR_EXPR:
+        {
+         // handle &var which can show up in phi arguments
+         bool ov;
+         if (tree_single_nonzero_warnv_p (expr, &ov))
+           {
+             r = range_nonzero (type);
+             return true;
+           }
+         break;
+       }
+
+      default:
+        break;
+    }
+  r = irange (type);
   return true;
 }
 
@@ -108,7 +154,7 @@ stmt_ranger::range_of_stmt (irange &r, gimple *s, tree name)
          return true;
        }
       // We don't understand the stmt, so return the global range.
-      r = get_tree_range (name);
+      r = ssa_name_range (name);
       return true;
     }
   if (res)
@@ -420,7 +466,7 @@ ssa_ranger::range_on_edge (irange &r, edge e, tree name)
   
   if (!valid_range_ssa_p (name))
     {
-      r = get_tree_range (name);
+      gcc_assert (range_of_expr (r, name));
       return;
     }
   range_on_exit (r, e->src, name);
@@ -638,7 +684,7 @@ global_ranger::range_of_stmt (irange &r, gimple *s, tree name)
     return true;
  
   // Avoid infinite recursion by initializing global cache
-  irange tmp = get_tree_range (name);
+  irange tmp = ssa_name_range (name);
   m_gori.m_globals.set_global_range (name, tmp);
 
   gcc_assert (ssa_ranger::range_of_stmt (r, s, name));
@@ -652,41 +698,37 @@ global_ranger::range_of_stmt (irange &r, gimple *s, tree name)
 // Determine a range for OP on stmt S, returning the result in R.
 // If OP is not defined in BB, find the range on entry to this block.
 
-bool
-global_ranger::range_of_expr (irange &r, tree op, gimple *s)
+irange
+global_ranger::range_of_ssa_name (tree name, gimple *s)
 {
-  if (!irange::supports_p (op))
-     return false;
+  // If there is no statement, just get the global value.
+  if (!s)
+    return ssa_name_range (name);
 
-  // If there is a statement, and a valid ssa_name, try to find a range.
-  if (s && valid_range_ssa_p (op))
-    {
-      basic_block bb = gimple_bb (s);
-      gimple *def_stmt = SSA_NAME_DEF_STMT (op);
-        
-      // if name is defined in this block, try to get an range from S.
-      if (def_stmt && gimple_bb (def_stmt) == bb)
-       gcc_assert (range_of_stmt (r, def_stmt, op));
-      else
-       // Otherwise OP comes from outside this block, use range on entry.
-       range_on_entry (r, bb, op);
-
-      // No range yet, see if there is a dereference in the block.
-      // We don't care if it's between the def and a use within a block
-      // because the entire block must be executed anyway.
-      // FIXME:?? For non-call exceptions we could have a statement throw
-      // which causes an early block exit. 
-      // in which case we may need to walk from S back to the def/top of block
-      // to make sure the deref happens between S and there before claiming 
-      // there is a deref.   Punt for now.
-      if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
-         m_gori.non_null_deref_p (op, bb))
-       r = range_nonzero (TREE_TYPE (op));
-      return true;
-    }
+  irange r;
+  basic_block bb = gimple_bb (s);
+  gimple *def_stmt = SSA_NAME_DEF_STMT (name);
+    
+  // if name is defined in this block, try to get an range from S.
+  if (def_stmt && gimple_bb (def_stmt) == bb)
+    gcc_assert (range_of_stmt (r, def_stmt, name));
+  else
+    // Otherwise OP comes from outside this block, use range on entry.
+    range_on_entry (r, bb, name);
 
-  // Fall back to the default.
-  return ssa_ranger::range_of_expr (r, op);
+  // No range yet, see if there is a dereference in the block.
+  // We don't care if it's between the def and a use within a block
+  // because the entire block must be executed anyway.
+  // FIXME:?? For non-call exceptions we could have a statement throw
+  // which causes an early block exit. 
+  // in which case we may need to walk from S back to the def/top of block
+  // to make sure the deref happens between S and there before claiming 
+  // there is a deref.   Punt for now.
+  if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
+      m_gori.non_null_deref_p (name, bb))
+    r = range_nonzero (TREE_TYPE (name));
+
+  return r;
 }
 
 // Calculate a range on edge E and return it in R.  Try to evaluate a range
@@ -731,7 +773,7 @@ global_ranger::export_global_ranges ()
        {
          // Make sure the new range is a subset of the old range.
          irange old_range;
-         old_range = get_tree_range (name);
+         old_range = ssa_name_range (name);
          old_range.intersect (r);
          /* Disable this while we fix tree-ssa/pr61743-2.c.  */
          //gcc_checking_assert (old_range == r);
@@ -1008,15 +1050,15 @@ trace_ranger::trailer (unsigned counter, const char *caller, bool result,
 
 // Tracing version of range_of_expr.  Call it with printing wrappers.
 
-bool
-trace_ranger::range_of_expr (irange &r, tree expr, gimple *s)
+irange
+trace_ranger::range_of_ssa_name (tree name, gimple *s)
 {
-  bool res;
+  irange r;
   unsigned idx = ++trace_count;
   if (dumping (idx))
     {
-      fprintf (dump_file, "range_of_expr (");
-      print_generic_expr (dump_file, expr, TDF_SLIM);
+      fprintf (dump_file, "range_of_ssa_name (");
+      print_generic_expr (dump_file, name, TDF_SLIM);
       fprintf (dump_file, ") at stmt ");
       if (s)
        print_gimple_stmt (dump_file, s , 0, TDF_SLIM);
@@ -1025,9 +1067,10 @@ trace_ranger::range_of_expr (irange &r, tree expr, gimple *s)
       indent += bump;
     }
 
-  res = super::range_of_expr (r, expr, s);
+  r = super::range_of_ssa_name (name, s);
 
-  return trailer (idx, "range_of_expr", res, expr, r);
+  trailer (idx, "range_of_ssa_name", true, name, r);
+  return r;
 }
 
 // Tracing version of range_on_edge.  Call it with printing wrappers.
index 38a15a7fc92f65c3156691ae5df593a1653ebc26..7209403fdf85d6d66ec263a330faa108c7794d51 100644 (file)
@@ -47,8 +47,9 @@ class stmt_ranger
   public:
   stmt_ranger ();
   ~stmt_ranger ();
-
-  virtual bool range_of_expr (irange &r, tree expr, gimple *s = NULL);
+  
+  bool range_of_expr (irange &r, tree expr, gimple *s = NULL);
+  virtual irange range_of_ssa_name (tree name, gimple *s = NULL);
   virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
   virtual bool range_of_stmt_with_range (irange &r, gimple *s, tree name,
                                         const irange &name_range);
@@ -126,7 +127,7 @@ public:
   global_ranger ();
   ~global_ranger ();
 
-  virtual bool range_of_expr (irange &r, tree op, gimple *s = NULL);
+  virtual irange range_of_ssa_name (tree name, gimple *s = NULL);
   virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
   virtual void range_on_entry (irange &r, basic_block bb, tree name);
 
@@ -167,7 +168,7 @@ class trace_ranger : public loop_ranger
 public:
   trace_ranger();
 
-  virtual bool range_of_expr (irange &r, tree expr, gimple *s = NULL);
+  virtual irange range_of_ssa_name (tree name, gimple *s = NULL);
   virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
   virtual void range_on_edge (irange &r, edge e, tree name);
   virtual void range_on_entry (irange &r, basic_block bb, tree name);