From e925119d520ac10674ed42faf14955aaf130c03b Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Wed, 31 May 2023 12:31:53 -0400
Subject: [PATCH 3/4] Unify range_operators to one class.
Range_operator and range_operator_float are 2 different classes, making
generalized dispatch difficult. The distinction between what is a float
operator and what is an integral operator also blurs when some methods
have multiple types. ie, casts : INT = FLOAT and FLOAT = INT
This patch unifies all possible invocation patterns in one class, and
switches the float table to use the general range_op_table.
* gimple-range-op.cc (cfn_constant_float_p): Change base class.
(cfn_pass_through_arg1): Adjust using statemenmt.
(cfn_signbit): Change base class, adjust using statement.
(cfn_copysign): Ditto.
(cfn_sqrt): Ditto.
(cfn_sincos): Ditto.
* range-op-float.cc (fold_range): Change class to range_operator.
(rv_fold): Ditto.
(op1_range): Ditto
(op2_range): Ditto
(lhs_op1_relation): Ditto.
(lhs_op2_relation): Ditto.
(op1_op2_relation): Ditto.
(foperator_*): Ditto.
(class float_table): New. Inherit from range_op_table.
(floating_tree_table) Change to range_op_table pointer.
(class floating_op_table): Delete.
* range-op.cc (operator_equal): Adjust using statement.
(operator_not_equal): Ditto.
(operator_lt, operator_le, operator_gt, operator_ge): Ditto.
(operator_minus, operator_cast): Ditto.
(operator_bitwise_and, pointer_plus_operator): Ditto.
(get_float_handle): Change return type.
* range-op.h (range_operator_float): Delete. Relocate all methods
into class range_operator.
(range_op_handler::m_float): Change type to range_operator.
(floating_op_table): Delete.
(floating_tree_table): Change type.
---
gcc/gimple-range-op.cc | 27 ++---
gcc/range-op-float.cc | 222 +++++++++++++++++++----------------------
gcc/range-op.cc | 12 ++-
gcc/range-op.h | 124 +++++++++++------------
4 files changed, 183 insertions(+), 202 deletions(-)
@@ -268,10 +268,10 @@ gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
// --------------------------------------------------------------------
// Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
-class cfn_constant_float_p : public range_operator_float
+class cfn_constant_float_p : public range_operator
{
public:
- using range_operator_float::fold_range;
+ using range_operator::fold_range;
virtual bool fold_range (irange &r, tree type, const frange &lh,
const irange &, relation_trio) const
{
@@ -319,6 +319,7 @@ class cfn_pass_through_arg1 : public range_operator
{
public:
using range_operator::fold_range;
+ using range_operator::op1_range;
virtual bool fold_range (irange &r, tree, const irange &lh,
const irange &, relation_trio) const
{
@@ -334,11 +335,11 @@ public:
} op_cfn_pass_through_arg1;
// Implement range operator for CFN_BUILT_IN_SIGNBIT.
-class cfn_signbit : public range_operator_float
+class cfn_signbit : public range_operator
{
public:
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
virtual bool fold_range (irange &r, tree type, const frange &lh,
const irange &, relation_trio) const override
{
@@ -373,10 +374,10 @@ public:
} op_cfn_signbit;
// Implement range operator for CFN_BUILT_IN_COPYSIGN
-class cfn_copysign : public range_operator_float
+class cfn_copysign : public range_operator
{
public:
- using range_operator_float::fold_range;
+ using range_operator::fold_range;
virtual bool fold_range (frange &r, tree type, const frange &lh,
const frange &rh, relation_trio) const override
{
@@ -464,11 +465,11 @@ frange_mpfr_arg1 (REAL_VALUE_TYPE *res_low, REAL_VALUE_TYPE *res_high,
return true;
}
-class cfn_sqrt : public range_operator_float
+class cfn_sqrt : public range_operator
{
public:
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
virtual bool fold_range (frange &r, tree type,
const frange &lh, const frange &,
relation_trio) const final override
@@ -599,11 +600,11 @@ public:
}
} op_cfn_sqrt;
-class cfn_sincos : public range_operator_float
+class cfn_sincos : public range_operator
{
public:
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
cfn_sincos (combined_fn cfn) { m_cfn = cfn; }
virtual bool fold_range (frange &r, tree type,
const frange &lh, const frange &,
@@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see
// Default definitions for floating point operators.
bool
-range_operator_float::fold_range (frange &r, tree type,
+range_operator::fold_range (frange &r, tree type,
const frange &op1, const frange &op2,
relation_trio trio) const
{
@@ -121,7 +121,7 @@ range_operator_float::fold_range (frange &r, tree type,
// MAYBE_NAN is set to TRUE if, in addition to any result in LB or
// UB, the final range has the possibility of a NAN.
void
-range_operator_float::rv_fold (REAL_VALUE_TYPE &lb,
+range_operator::rv_fold (REAL_VALUE_TYPE &lb,
REAL_VALUE_TYPE &ub,
bool &maybe_nan,
tree type ATTRIBUTE_UNUSED,
@@ -137,7 +137,7 @@ range_operator_float::rv_fold (REAL_VALUE_TYPE &lb,
}
bool
-range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
+range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lh ATTRIBUTE_UNUSED,
const irange &rh ATTRIBUTE_UNUSED,
@@ -147,7 +147,7 @@ range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
}
bool
-range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
+range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lh ATTRIBUTE_UNUSED,
const frange &rh ATTRIBUTE_UNUSED,
@@ -157,7 +157,7 @@ range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
}
bool
-range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED,
+range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lhs ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
@@ -167,7 +167,7 @@ range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED,
}
bool
-range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED,
+range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const irange &lhs ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
@@ -177,7 +177,7 @@ range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED,
}
bool
-range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED,
+range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
@@ -187,7 +187,7 @@ range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED,
}
bool
-range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED,
+range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const irange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
@@ -197,7 +197,7 @@ range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED,
}
relation_kind
-range_operator_float::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
+range_operator::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
relation_kind) const
@@ -206,7 +206,7 @@ range_operator_float::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
}
relation_kind
-range_operator_float::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
+range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
relation_kind) const
@@ -215,7 +215,7 @@ range_operator_float::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
}
relation_kind
-range_operator_float::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
+range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
relation_kind) const
@@ -224,7 +224,7 @@ range_operator_float::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
}
relation_kind
-range_operator_float::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
+range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
const frange &op1 ATTRIBUTE_UNUSED,
const frange &op2 ATTRIBUTE_UNUSED,
relation_kind) const
@@ -233,13 +233,7 @@ range_operator_float::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
}
relation_kind
-range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const
-{
- return VREL_VARYING;
-}
-
-relation_kind
-range_operator_float::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED) const
+range_operator::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED) const
{
return VREL_VARYING;
}
@@ -546,10 +540,10 @@ build_gt (frange &r, tree type, const frange &val)
}
-class foperator_identity : public range_operator_float
+class foperator_identity : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
public:
bool fold_range (frange &r, tree type ATTRIBUTE_UNUSED,
const frange &op1, const frange &op2 ATTRIBUTE_UNUSED,
@@ -568,12 +562,12 @@ public:
public:
} fop_identity;
-class foperator_equal : public range_operator_float
+class foperator_equal : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
- using range_operator_float::op1_op2_relation;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -697,11 +691,11 @@ foperator_equal::op1_range (frange &r, tree type,
return true;
}
-class foperator_not_equal : public range_operator_float
+class foperator_not_equal : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op1_op2_relation;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op1_op2_relation;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -819,12 +813,12 @@ foperator_not_equal::op1_range (frange &r, tree type,
return true;
}
-class foperator_lt : public range_operator_float
+class foperator_lt : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
- using range_operator_float::op1_op2_relation;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -935,12 +929,12 @@ foperator_lt::op2_range (frange &r,
return true;
}
-class foperator_le : public range_operator_float
+class foperator_le : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
- using range_operator_float::op1_op2_relation;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1045,12 +1039,12 @@ foperator_le::op2_range (frange &r,
return true;
}
-class foperator_gt : public range_operator_float
+class foperator_gt : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
- using range_operator_float::op1_op2_relation;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1165,12 +1159,12 @@ foperator_gt::op2_range (frange &r,
return true;
}
-class foperator_ge : public range_operator_float
+class foperator_ge : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
- using range_operator_float::op1_op2_relation;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1278,11 +1272,11 @@ foperator_ge::op2_range (frange &r, tree type,
// UNORDERED_EXPR comparison.
-class foperator_unordered : public range_operator_float
+class foperator_unordered : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1352,11 +1346,11 @@ foperator_unordered::op1_range (frange &r, tree type,
// ORDERED_EXPR comparison.
-class foperator_ordered : public range_operator_float
+class foperator_ordered : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1421,10 +1415,10 @@ foperator_ordered::op1_range (frange &r, tree type,
return true;
}
-class foperator_negate : public range_operator_float
+class foperator_negate : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
public:
bool fold_range (frange &r, tree type,
const frange &op1, const frange &op2,
@@ -1467,10 +1461,10 @@ public:
}
} fop_negate;
-class foperator_abs : public range_operator_float
+class foperator_abs : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
public:
bool fold_range (frange &r, tree type,
const frange &op1, const frange &,
@@ -1566,11 +1560,11 @@ foperator_abs::op1_range (frange &r, tree type,
return true;
}
-class foperator_unordered_lt : public range_operator_float
+class foperator_unordered_lt : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1677,11 +1671,11 @@ foperator_unordered_lt::op2_range (frange &r, tree type,
return true;
}
-class foperator_unordered_le : public range_operator_float
+class foperator_unordered_le : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1784,11 +1778,11 @@ foperator_unordered_le::op2_range (frange &r,
return true;
}
-class foperator_unordered_gt : public range_operator_float
+class foperator_unordered_gt : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1895,11 +1889,11 @@ foperator_unordered_gt::op2_range (frange &r,
return true;
}
-class foperator_unordered_ge : public range_operator_float
+class foperator_unordered_ge : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -2005,11 +1999,11 @@ foperator_unordered_ge::op2_range (frange &r, tree type,
return true;
}
-class foperator_unordered_equal : public range_operator_float
+class foperator_unordered_equal : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -2086,11 +2080,11 @@ foperator_unordered_equal::op1_range (frange &r, tree type,
return true;
}
-class foperator_ltgt : public range_operator_float
+class foperator_ltgt : public range_operator
{
- using range_operator_float::fold_range;
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
bool fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -2374,10 +2368,10 @@ float_widen_lhs_range (tree type, const frange &lhs)
return ret;
}
-class foperator_plus : public range_operator_float
+class foperator_plus : public range_operator
{
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
virtual bool op1_range (frange &r, tree type,
const frange &lhs,
@@ -2424,10 +2418,10 @@ private:
} fop_plus;
-class foperator_minus : public range_operator_float
+class foperator_minus : public range_operator
{
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
virtual bool op1_range (frange &r, tree type,
const frange &lhs,
@@ -2476,7 +2470,7 @@ private:
} fop_minus;
-class foperator_mult_div_base : public range_operator_float
+class foperator_mult_div_base : public range_operator
{
protected:
// Given CP[0] to CP[3] floating point values rounded to -INF,
@@ -2503,8 +2497,8 @@ protected:
class foperator_mult : public foperator_mult_div_base
{
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
virtual bool op1_range (frange &r, tree type,
const frange &lhs,
@@ -2659,8 +2653,8 @@ private:
class foperator_div : public foperator_mult_div_base
{
- using range_operator_float::op1_range;
- using range_operator_float::op2_range;
+ using range_operator::op1_range;
+ using range_operator::op2_range;
public:
virtual bool op1_range (frange &r, tree type,
const frange &lhs,
@@ -2814,12 +2808,16 @@ private:
} fop_div;
// Instantiate a range_op_table for floating point operations.
-static floating_op_table global_floating_table;
+class float_table : public range_op_table
+{
+ public:
+ float_table ();
+} global_floating_table;
// Pointer to the float table so the dispatch code can access it.
-floating_op_table *floating_tree_table = &global_floating_table;
+range_op_table *floating_tree_table = &global_floating_table;
-floating_op_table::floating_op_table ()
+float_table::float_table ()
{
set (SSA_NAME, fop_identity);
set (PAREN_EXPR, fop_identity);
@@ -2852,24 +2850,6 @@ floating_op_table::floating_op_table ()
set (RDIV_EXPR, fop_div);
}
-// Return a pointer to the range_operator_float instance, if there is
-// one associated with tree_code CODE.
-
-range_operator_float *
-floating_op_table::operator[] (enum tree_code code)
-{
- return m_range_tree[code];
-}
-
-// Add OP to the handler table for CODE.
-
-void
-floating_op_table::set (enum tree_code code, range_operator_float &op)
-{
- gcc_checking_assert (m_range_tree[code] == NULL);
- m_range_tree[code] = &op;
-}
-
#if CHECKING_P
#include "selftest.h"
@@ -556,6 +556,7 @@ class operator_equal : public range_operator
using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
@@ -678,6 +679,7 @@ class operator_not_equal : public range_operator
using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
@@ -860,6 +862,7 @@ class operator_lt : public range_operator
using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
@@ -982,6 +985,7 @@ class operator_le : public range_operator
using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
@@ -1101,6 +1105,7 @@ class operator_gt : public range_operator
using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
@@ -1219,6 +1224,7 @@ class operator_ge : public range_operator
using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::op1_op2_relation;
public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
@@ -1647,6 +1653,7 @@ class operator_minus : public range_operator
using range_operator::fold_range;
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::lhs_op1_relation;
public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
@@ -2710,6 +2717,7 @@ class operator_cast: public range_operator
{
using range_operator::fold_range;
using range_operator::op1_range;
+ using range_operator::lhs_op1_relation;
public:
virtual bool fold_range (irange &r, tree type,
const irange &op1,
@@ -3055,6 +3063,7 @@ class operator_bitwise_and : public range_operator
{
using range_operator::op1_range;
using range_operator::op2_range;
+ using range_operator::lhs_op1_relation;
public:
virtual bool op1_range (irange &r, tree type,
const irange &lhs,
@@ -4410,6 +4419,7 @@ operator_addr_expr::op1_range (irange &r, tree type,
class pointer_plus_operator : public range_operator
{
+ using range_operator::op2_range;
public:
virtual void wi_fold (irange &r, tree type,
const wide_int &lh_lb,
@@ -4719,7 +4729,7 @@ get_handler (enum tree_code code, tree type)
// Return the floating point operator for CODE or NULL if none available.
-static inline range_operator_float *
+static inline range_operator *
get_float_handler (enum tree_code code, tree)
{
return (*floating_tree_table)[code];
@@ -45,6 +45,11 @@ along with GCC; see the file COPYING3. If not see
// non-zero. This is mostly for logical true false, but can serve other
// purposes.
// ie 0 = op1 - op2 implies op2 has the same range as op1.
+//
+// 4 - All supported range combinations are explicitly specified.
+// Any desired combinations should be implemented for each operator.
+// When new range classes are added, new matching prototypes should be
+// added.
class range_operator
{
@@ -55,6 +60,18 @@ public:
const irange &lh,
const irange &rh,
relation_trio = TRIO_VARYING) const;
+ virtual bool fold_range (frange &r, tree type,
+ const frange &lh,
+ const frange &rh,
+ relation_trio = TRIO_VARYING) const;
+ virtual bool fold_range (irange &r, tree type,
+ const frange &lh,
+ const irange &rh,
+ relation_trio = TRIO_VARYING) const;
+ virtual bool fold_range (irange &r, tree type,
+ const frange &lh,
+ const frange &rh,
+ relation_trio = TRIO_VARYING) const;
// Return the range for op[12] in the general case. LHS is the range for
// the LHS of the expression, OP[12]is the range for the other
@@ -71,10 +88,28 @@ public:
const irange &lhs,
const irange &op2,
relation_trio = TRIO_VARYING) const;
+ virtual bool op1_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op2,
+ relation_trio = TRIO_VARYING) const;
+ virtual bool op1_range (frange &r, tree type,
+ const irange &lhs,
+ const frange &op2,
+ relation_trio = TRIO_VARYING) const;
+
+
virtual bool op2_range (irange &r, tree type,
const irange &lhs,
const irange &op1,
relation_trio = TRIO_VARYING) const;
+ virtual bool op2_range (frange &r, tree type,
+ const frange &lhs,
+ const frange &op1,
+ relation_trio = TRIO_VARYING) const;
+ virtual bool op2_range (frange &r, tree type,
+ const irange &lhs,
+ const frange &op1,
+ relation_trio = TRIO_VARYING) const;
// The following routines are used to represent relations between the
// various operations. If the caller knows where the symbolics are,
@@ -84,11 +119,30 @@ public:
const irange &op1,
const irange &op2,
relation_kind = VREL_VARYING) const;
+ virtual relation_kind lhs_op1_relation (const frange &lhs,
+ const frange &op1,
+ const frange &op2,
+ relation_kind = VREL_VARYING) const;
+ virtual relation_kind lhs_op1_relation (const irange &lhs,
+ const frange &op1,
+ const frange &op2,
+ relation_kind = VREL_VARYING) const;
+
virtual relation_kind lhs_op2_relation (const irange &lhs,
const irange &op1,
const irange &op2,
relation_kind = VREL_VARYING) const;
+ virtual relation_kind lhs_op2_relation (const frange &lhs,
+ const frange &op1,
+ const frange &op2,
+ relation_kind = VREL_VARYING) const;
+ virtual relation_kind lhs_op2_relation (const irange &lhs,
+ const frange &op1,
+ const frange &op2,
+ relation_kind = VREL_VARYING) const;
+
virtual relation_kind op1_op2_relation (const irange &lhs) const;
+ virtual relation_kind op1_op2_relation (const frange &lhs) const;
protected:
// Perform an integral operation between 2 sub-ranges and return it.
virtual void wi_fold (irange &r, tree type,
@@ -115,17 +169,8 @@ protected:
unsigned limit) const;
// Apply any bitmasks implied by these ranges.
virtual void update_bitmask (irange &, const irange &, const irange &) const;
-};
-
-// Like range_operator above, but for floating point operators.
-class range_operator_float
-{
-public:
- virtual bool fold_range (frange &r, tree type,
- const frange &lh,
- const frange &rh,
- relation_trio = TRIO_VARYING) const;
+ // Perform an float operation between 2 ranges and return it.
virtual void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
bool &maybe_nan,
tree type,
@@ -134,50 +179,6 @@ public:
const REAL_VALUE_TYPE &rh_lb,
const REAL_VALUE_TYPE &rh_ub,
relation_kind) const;
- // Unary operations have the range of the LHS as op2.
- virtual bool fold_range (irange &r, tree type,
- const frange &lh,
- const irange &rh,
- relation_trio = TRIO_VARYING) const;
- virtual bool fold_range (irange &r, tree type,
- const frange &lh,
- const frange &rh,
- relation_trio = TRIO_VARYING) const;
- virtual bool op1_range (frange &r, tree type,
- const frange &lhs,
- const frange &op2,
- relation_trio = TRIO_VARYING) const;
- virtual bool op1_range (frange &r, tree type,
- const irange &lhs,
- const frange &op2,
- relation_trio = TRIO_VARYING) const;
- virtual bool op2_range (frange &r, tree type,
- const frange &lhs,
- const frange &op1,
- relation_trio = TRIO_VARYING) const;
- virtual bool op2_range (frange &r, tree type,
- const irange &lhs,
- const frange &op1,
- relation_trio = TRIO_VARYING) const;
-
- virtual relation_kind lhs_op1_relation (const frange &lhs,
- const frange &op1,
- const frange &op2,
- relation_kind = VREL_VARYING) const;
- virtual relation_kind lhs_op1_relation (const irange &lhs,
- const frange &op1,
- const frange &op2,
- relation_kind = VREL_VARYING) const;
- virtual relation_kind lhs_op2_relation (const frange &lhs,
- const frange &op1,
- const frange &op2,
- relation_kind = VREL_VARYING) const;
- virtual relation_kind lhs_op2_relation (const irange &lhs,
- const frange &op1,
- const frange &op2,
- relation_kind = VREL_VARYING) const;
- virtual relation_kind op1_op2_relation (const irange &lhs) const;
- virtual relation_kind op1_op2_relation (const frange &lhs) const;
};
class range_op_handler
@@ -212,7 +213,7 @@ protected:
void set_op_handler (enum tree_code code, tree type);
bool m_valid;
range_operator *m_int;
- range_operator_float *m_float;
+ range_operator *m_float;
};
extern bool range_cast (vrange &, tree type);
@@ -294,20 +295,9 @@ private:
range_operator *m_range_tree[MAX_TREE_CODES];
};
-// Like above, but for floating point operators.
-
-class floating_op_table
-{
-public:
- floating_op_table ();
- range_operator_float *operator[] (enum tree_code code);
-private:
- void set (enum tree_code code, range_operator_float &op);
- range_operator_float *m_range_tree[MAX_TREE_CODES];
-};
// This holds the range op table for floating point operations.
-extern floating_op_table *floating_tree_table;
+extern range_op_table *floating_tree_table;
extern range_operator *ptr_op_widen_mult_signed;
extern range_operator *ptr_op_widen_mult_unsigned;
--
2.40.1