[COMMITTED] Move common code from range-op.cc to header files.

Message ID 20220429090236.718140-5-aldyh@redhat.com
State Committed
Commit 9eb38e88ce8003c0b852144da3c265b6785ede3c
Headers
Series [COMMITTED] Move common code from range-op.cc to header files. |

Commit Message

Aldy Hernandez April 29, 2022, 9:02 a.m. UTC
  In preparation for the agnostication of ranger, this patch moves
common code that can be shared with non-integer ranges (initially
pointers) into the relevant header files.

This is a relatively non-invasive change, as any changes that would
need to be ported to GCC 12, would occur in the range-op entries
themselves, not in the supporting glue which I'm moving.

Tested and benchmarked on x86-64 Linux.

gcc/ChangeLog:

	* range-op.cc (empty_range_varying): Move to range-op.h.
	(range_true): Move to range.h.
	(range_false): Same.
	(range_true_and_false): Same.
	(enum bool_range_state): Move to range-op.h.
	(relop_early_resolve): Same.
	(operator_equal::op1_op2_relation): Abstract code to...
	(equal_op1_op2_relation): ...here.
	(operator_not_equal::op1_op2_relation): Abstract code to...
	(not_equal_op1_op2_relation): ...here.
	(operator_lt::op1_op2_relation): Abstract code to...
	(lt_op1_op2_relation): ...here.
	(operator_le::op1_op2_relation): Abstract code to...
	(le_op1_op2_relation): ...here.
	(operator_gt::op1_op2_relation): Abstract code to...
	(gt_op1_op2_relation): ...here.
	(operator_ge::op1_op2_relation): Abstract code to...
	(ge_op1_op2_relation): ...here.
	(class range_op_table): Move to range-op.h.
	* range-op.h (equal_op1_op2_relation): Moved from range-op.cc.
	(not_equal_op1_op2_relation): Same.
	(lt_op1_op2_relation): Same.
	(le_op1_op2_relation): Same.
	(gt_op1_op2_relation): Same.
	(ge_op1_op2_relation): Same.
	(enum bool_range_state): Same.
	(get_bool_state): Same.
	(empty_range_varying): Same.
	(relop_early_resolve): Same.
	(class range_op_table): Same.
	* range.h (range_true): Same.
	(range_false): Same.
	(range_true_and_false): Same.
---
 gcc/range-op.cc | 140 +++++++++++++++---------------------------------
 gcc/range-op.h  |  72 +++++++++++++++++++++++++
 gcc/range.h     |  28 ++++++++++
 3 files changed, 143 insertions(+), 97 deletions(-)
  

Patch

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 464a1f839fd..fa962507b92 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -63,24 +63,6 @@  min_limit (const_tree type)
   return wi::min_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
 }
 
-// If the range of either op1 or op2 is undefined, set the result to
-// varying and return TRUE.  If the caller truely cares about a result,
-// they should pass in a varying if it has an undefined that it wants
-// treated as a varying.
-
-inline bool
-empty_range_varying (irange &r, tree type,
-		     const irange &op1, const irange & op2)
-{
-  if (op1.undefined_p () || op2.undefined_p ())
-    {
-      r.set_varying (type);
-      return true;
-    }
-  else
-    return false;
-}
-
 // Return false if shifting by OP is undefined behavior.  Otherwise, return
 // true and the range it is to be shifted by.  This allows trimming out of
 // undefined ranges, leaving only valid ranges if there are any.
@@ -432,39 +414,10 @@  create_possibly_reversed_range (irange &r, tree type,
     r.set (wide_int_to_tree (type, new_lb), wide_int_to_tree (type, new_ub));
 }
 
-// Return an irange instance that is a boolean TRUE.
-
-static inline int_range<1>
-range_true (tree type)
-{
-  unsigned prec = TYPE_PRECISION (type);
-  return int_range<1> (type, wi::one (prec), wi::one (prec));
-}
-
-// Return an irange instance that is a boolean FALSE.
-
-static inline int_range<1>
-range_false (tree type)
-{
-  unsigned prec = TYPE_PRECISION (type);
-  return int_range<1> (type, wi::zero (prec), wi::zero (prec));
-}
-
-// Return an irange that covers both true and false.
-
-static inline int_range<1>
-range_true_and_false (tree type)
-{
-  unsigned prec = TYPE_PRECISION (type);
-  return int_range<1> (type, wi::zero (prec), wi::one (prec));
-}
-
-enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL };
-
 // Return the summary information about boolean range LHS.  If EMPTY/FULL,
 // return the equivalent range for TYPE in R; if FALSE/TRUE, do nothing.
 
-static bool_range_state
+bool_range_state
 get_bool_state (irange &r, const irange &lhs, tree val_type)
 {
   // If there is no result, then this is unexecutable.
@@ -488,37 +441,6 @@  get_bool_state (irange &r, const irange &lhs, tree val_type)
   return BRS_TRUE;
 }
 
-// For relation opcodes, first try to see if the supplied relation
-// forces a true or false result, and return that.
-// Then check for undefined operands.  If none of this applies,
-// return false.
-
-static inline bool
-relop_early_resolve (irange &r, tree type, const irange &op1,
-		     const irange &op2, relation_kind rel,
-		     relation_kind my_rel)
-{
-  // If known relation is a complete subset of this relation, always true.
-  if (relation_union (rel, my_rel) == my_rel)
-    {
-      r = range_true (type);
-      return true;
-    }
-
-  // If known relation has no subset of this relation, always false.
-  if (relation_intersect (rel, my_rel) == VREL_EMPTY)
-    {
-      r = range_false (type);
-      return true;
-    }
-
-  // If either operand is undefined, return VARYING.
-  if (empty_range_varying (r, type, op1, op2))
-    return true;
-
-  return false;
-}
-
 
 class operator_equal : public range_operator
 {
@@ -541,7 +463,7 @@  public:
 // Check if the LHS range indicates a relation between OP1 and OP2.
 
 enum tree_code
-operator_equal::op1_op2_relation (const irange &lhs) const
+equal_op1_op2_relation (const irange &lhs)
 {
   if (lhs.undefined_p ())
     return VREL_EMPTY;
@@ -556,6 +478,12 @@  operator_equal::op1_op2_relation (const irange &lhs) const
   return VREL_NONE;
 }
 
+enum tree_code
+operator_equal::op1_op2_relation (const irange &lhs) const
+{
+  return equal_op1_op2_relation (lhs);
+}
+
 
 bool
 operator_equal::fold_range (irange &r, tree type,
@@ -651,7 +579,7 @@  public:
 // Check if the LHS range indicates a relation between OP1 and OP2.
 
 enum tree_code
-operator_not_equal::op1_op2_relation (const irange &lhs) const
+not_equal_op1_op2_relation (const irange &lhs)
 {
   if (lhs.undefined_p ())
     return VREL_EMPTY;
@@ -666,6 +594,12 @@  operator_not_equal::op1_op2_relation (const irange &lhs) const
   return VREL_NONE;
 }
 
+enum tree_code
+operator_not_equal::op1_op2_relation (const irange &lhs) const
+{
+  return not_equal_op1_op2_relation (lhs);
+}
+
 bool
 operator_not_equal::fold_range (irange &r, tree type,
 				const irange &op1,
@@ -821,7 +755,7 @@  public:
 // Check if the LHS range indicates a relation between OP1 and OP2.
 
 enum tree_code
-operator_lt::op1_op2_relation (const irange &lhs) const
+lt_op1_op2_relation (const irange &lhs)
 {
   if (lhs.undefined_p ())
     return VREL_EMPTY;
@@ -836,6 +770,12 @@  operator_lt::op1_op2_relation (const irange &lhs) const
   return VREL_NONE;
 }
 
+enum tree_code
+operator_lt::op1_op2_relation (const irange &lhs) const
+{
+  return lt_op1_op2_relation (lhs);
+}
+
 bool
 operator_lt::fold_range (irange &r, tree type,
 			 const irange &op1,
@@ -923,7 +863,7 @@  public:
 // Check if the LHS range indicates a relation between OP1 and OP2.
 
 enum tree_code
-operator_le::op1_op2_relation (const irange &lhs) const
+le_op1_op2_relation (const irange &lhs)
 {
   if (lhs.undefined_p ())
     return VREL_EMPTY;
@@ -938,6 +878,12 @@  operator_le::op1_op2_relation (const irange &lhs) const
   return VREL_NONE;
 }
 
+enum tree_code
+operator_le::op1_op2_relation (const irange &lhs) const
+{
+  return le_op1_op2_relation (lhs);
+}
+
 bool
 operator_le::fold_range (irange &r, tree type,
 			 const irange &op1,
@@ -1025,7 +971,7 @@  public:
 // Check if the LHS range indicates a relation between OP1 and OP2.
 
 enum tree_code
-operator_gt::op1_op2_relation (const irange &lhs) const
+gt_op1_op2_relation (const irange &lhs)
 {
   if (lhs.undefined_p ())
     return VREL_EMPTY;
@@ -1040,6 +986,12 @@  operator_gt::op1_op2_relation (const irange &lhs) const
   return VREL_NONE;
 }
 
+enum tree_code
+operator_gt::op1_op2_relation (const irange &lhs) const
+{
+  return gt_op1_op2_relation (lhs);
+}
+
 
 bool
 operator_gt::fold_range (irange &r, tree type,
@@ -1126,7 +1078,7 @@  public:
 // Check if the LHS range indicates a relation between OP1 and OP2.
 
 enum tree_code
-operator_ge::op1_op2_relation (const irange &lhs) const
+ge_op1_op2_relation (const irange &lhs)
 {
   if (lhs.undefined_p ())
     return VREL_EMPTY;
@@ -1141,6 +1093,12 @@  operator_ge::op1_op2_relation (const irange &lhs) const
   return VREL_NONE;
 }
 
+enum tree_code
+operator_ge::op1_op2_relation (const irange &lhs) const
+{
+  return ge_op1_op2_relation (lhs);
+}
+
 bool
 operator_ge::fold_range (irange &r, tree type,
 			 const irange &op1,
@@ -3993,18 +3951,6 @@  pointer_or_operator::wi_fold (irange &r, tree type,
     r.set_varying (type);
 }
 
-// This implements the range operator tables as local objects in this file.
-
-class range_op_table
-{
-public:
-  inline range_operator *operator[] (enum tree_code code);
-protected:
-  void set (enum tree_code code, range_operator &op);
-private:
-  range_operator *m_range_tree[MAX_TREE_CODES];
-};
-
 // Return a pointer to the range_operator instance, if there is one
 // associated with tree_code CODE.
 
diff --git a/gcc/range-op.h b/gcc/range-op.h
index a51969c2211..c93eb844547 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -112,4 +112,76 @@  extern void wi_set_zero_nonzero_bits (tree type,
 				      wide_int &maybe_nonzero,
 				      wide_int &mustbe_nonzero);
 
+// op1_op2_relation methods that are the same across irange and frange.
+enum tree_code equal_op1_op2_relation (const irange &lhs);
+enum tree_code not_equal_op1_op2_relation (const irange &lhs);
+enum tree_code lt_op1_op2_relation (const irange &lhs);
+enum tree_code le_op1_op2_relation (const irange &lhs);
+enum tree_code gt_op1_op2_relation (const irange &lhs);
+enum tree_code ge_op1_op2_relation (const irange &lhs);
+
+enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL };
+bool_range_state get_bool_state (irange &r, const irange &lhs, tree val_type);
+
+// If the range of either op1 or op2 is undefined, set the result to
+// varying and return TRUE.  If the caller truely cares about a result,
+// they should pass in a varying if it has an undefined that it wants
+// treated as a varying.
+
+inline bool
+empty_range_varying (irange &r, tree type,
+		     const irange &op1, const irange & op2)
+{
+  if (op1.undefined_p () || op2.undefined_p ())
+    {
+      r.set_varying (type);
+      return true;
+    }
+  else
+    return false;
+}
+
+// For relation opcodes, first try to see if the supplied relation
+// forces a true or false result, and return that.
+// Then check for undefined operands.  If none of this applies,
+// return false.
+
+inline bool
+relop_early_resolve (irange &r, tree type, const irange &op1,
+		     const irange &op2, relation_kind rel,
+		     relation_kind my_rel)
+{
+  // If known relation is a complete subset of this relation, always true.
+  if (relation_union (rel, my_rel) == my_rel)
+    {
+      r = range_true (type);
+      return true;
+    }
+
+  // If known relation has no subset of this relation, always false.
+  if (relation_intersect (rel, my_rel) == VREL_EMPTY)
+    {
+      r = range_false (type);
+      return true;
+    }
+
+  // If either operand is undefined, return VARYING.
+  if (empty_range_varying (r, type, op1, op2))
+    return true;
+
+  return false;
+}
+
+// This implements the range operator tables as local objects.
+
+class range_op_table
+{
+public:
+  range_operator *operator[] (enum tree_code code);
+protected:
+  void set (enum tree_code code, range_operator &op);
+private:
+  range_operator *m_range_tree[MAX_TREE_CODES];
+};
+
 #endif // GCC_RANGE_OP_H
diff --git a/gcc/range.h b/gcc/range.h
index 5eb784b2d54..5c70c66566c 100644
--- a/gcc/range.h
+++ b/gcc/range.h
@@ -25,4 +25,32 @@  value_range range_zero (tree type);
 value_range range_nonzero (tree type);
 value_range range_positives (tree type);
 value_range range_negatives (tree type);
+
+// Return an irange instance that is a boolean TRUE.
+
+static inline int_range<1>
+range_true (tree type)
+{
+  unsigned prec = TYPE_PRECISION (type);
+  return int_range<1> (type, wi::one (prec), wi::one (prec));
+}
+
+// Return an irange instance that is a boolean FALSE.
+
+static inline int_range<1>
+range_false (tree type)
+{
+  unsigned prec = TYPE_PRECISION (type);
+  return int_range<1> (type, wi::zero (prec), wi::zero (prec));
+}
+
+// Return an irange that covers both true and false.
+
+static inline int_range<1>
+range_true_and_false (tree type)
+{
+  unsigned prec = TYPE_PRECISION (type);
+  return int_range<1> (type, wi::zero (prec), wi::one (prec));
+}
+
 #endif // GCC_RANGE_H