This provides range_op_handler with a default range_operator, so you no
longer need to check if it has a valid handler or not.
The valid check now turns into a "is this something other than a default
operator" check. IT means you can now simply invoke fold without
checking.. ie instead of
range_op_handler handler(CONVERT_EXPR);
if (handler && handler.fold_range (......))
we can simply write
if (range_op_handler(CONVERT_EXPR).fold_range (....))
The new method range_op() will return the a pointer to the custom
range_operator, or NULL if its the default. THis allos use of
range_op_handler() to behave as if you were indexing a range table/ if
that happens to be needed.
Bootstraps on x86_64-pc-linux-gnu with no regressions. Pushed.
Andrew
From 3c4399657d35a0b5bf7caeb88c6ddc0461322d3f Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Sat, 10 Jun 2023 16:59:38 -0400
Subject: [PATCH 15/17] Provide a default range_operator via range_op_handler.
range_op_handler now provides a default range_operator for any opcode,
so there is no longer a need to check for a valid operator.
* gimple-range-op.cc (gimple_range_op_handler): Set m_operator
manually as there is no access to the default operator.
(cfn_copysign::fold_range): Don't check for validity.
(cfn_ubsan::fold_range): Ditto.
(gimple_range_op_handler::maybe_builtin_call): Don't set to NULL.
* range-op.cc (default_operator): New.
(range_op_handler::range_op_handler): Use default_operator
instead of NULL.
(range_op_handler::operator bool): Move from header, compare
against default operator.
(range_op_handler::range_op): New.
* range-op.h (range_op_handler::operator bool): Move.
---
gcc/gimple-range-op.cc | 28 +++++++++++++---------------
gcc/range-op.cc | 32 ++++++++++++++++++++++++++++++--
gcc/range-op.h | 3 ++-
3 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 4cbc981ee04..021a9108ecf 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -120,21 +120,22 @@ gimple_range_op_handler::supported_p (gimple *s)
// Construct a handler object for statement S.
gimple_range_op_handler::gimple_range_op_handler (gimple *s)
- : range_op_handler (get_code (s))
{
+ range_op_handler oper (get_code (s));
m_stmt = s;
m_op1 = NULL_TREE;
m_op2 = NULL_TREE;
- if (m_operator)
+ if (oper)
switch (gimple_code (m_stmt))
{
case GIMPLE_COND:
m_op1 = gimple_cond_lhs (m_stmt);
m_op2 = gimple_cond_rhs (m_stmt);
// Check that operands are supported types. One check is enough.
- if (!Value_Range::supports_type_p (TREE_TYPE (m_op1)))
- m_operator = NULL;
+ if (Value_Range::supports_type_p (TREE_TYPE (m_op1)))
+ m_operator = oper.range_op ();
+ gcc_checking_assert (m_operator);
return;
case GIMPLE_ASSIGN:
m_op1 = gimple_range_base_of_assignment (m_stmt);
@@ -153,7 +154,9 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s)
m_op2 = gimple_assign_rhs2 (m_stmt);
// Check that operands are supported types. One check is enough.
if ((m_op1 && !Value_Range::supports_type_p (TREE_TYPE (m_op1))))
- m_operator = NULL;
+ return;
+ m_operator = oper.range_op ();
+ gcc_checking_assert (m_operator);
return;
default:
gcc_unreachable ();
@@ -165,6 +168,7 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s)
maybe_builtin_call ();
else
maybe_non_standard ();
+ gcc_checking_assert (m_operator);
}
// Calculate what we can determine of the range of this unary
@@ -364,11 +368,10 @@ public:
const frange &rh, relation_trio) const override
{
frange neg;
- range_op_handler abs_op (ABS_EXPR);
- range_op_handler neg_op (NEGATE_EXPR);
- if (!abs_op || !abs_op.fold_range (r, type, lh, frange (type)))
+ if (!range_op_handler (ABS_EXPR).fold_range (r, type, lh, frange (type)))
return false;
- if (!neg_op || !neg_op.fold_range (neg, type, r, frange (type)))
+ if (!range_op_handler (NEGATE_EXPR).fold_range (neg, type, r,
+ frange (type)))
return false;
bool signbit;
@@ -1073,14 +1076,11 @@ public:
virtual bool fold_range (irange &r, tree type, const irange &lh,
const irange &rh, relation_trio rel) const
{
- range_op_handler handler (m_code);
- gcc_checking_assert (handler);
-
bool saved_flag_wrapv = flag_wrapv;
// Pretend the arithmetic is wrapping. If there is any overflow,
// we'll complain, but will actually do wrapping operation.
flag_wrapv = 1;
- bool result = handler.fold_range (r, type, lh, rh, rel);
+ bool result = range_op_handler (m_code).fold_range (r, type, lh, rh, rel);
flag_wrapv = saved_flag_wrapv;
// If for both arguments vrp_valueize returned non-NULL, this should
@@ -1230,8 +1230,6 @@ gimple_range_op_handler::maybe_builtin_call ()
m_operator = &op_cfn_constant_p;
else if (frange::supports_p (TREE_TYPE (m_op1)))
m_operator = &op_cfn_constant_float_p;
- else
- m_operator = NULL;
break;
CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 382f5d50ffa..a271e00fa07 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -121,16 +121,44 @@ range_op_table::range_op_table ()
// set (MAX_EXPR, op_max);
}
+// Instantiate a default range operator for opcodes with no entry.
+
+range_operator default_operator;
+
+// Create a default range_op_handler.
+
range_op_handler::range_op_handler ()
{
- m_operator = NULL;
+ m_operator = &default_operator;
}
-// Constructing without a type must come from the unified table.
+// Create a range_op_handler for CODE. Use a default operatoer if CODE
+// does not have an entry.
range_op_handler::range_op_handler (tree_code code)
{
m_operator = operator_table[code];
+ if (!m_operator)
+ m_operator = &default_operator;
+}
+
+// Return TRUE if this handler has a non-default operator.
+
+range_op_handler::operator bool () const
+{
+ return m_operator != &default_operator;
+}
+
+// Return a pointer to the range operator assocaited with this handler.
+// If it is a default operator, return NULL.
+// This is the equivalent of indexing the range table.
+
+range_operator *
+range_op_handler::range_op () const
+{
+ if (m_operator != &default_operator)
+ return m_operator;
+ return NULL;
}
// Create a dispatch pattern for value range discriminators LHS, OP1, and OP2.
diff --git a/gcc/range-op.h b/gcc/range-op.h
index 328910d0ec5..8243258eea5 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -186,7 +186,8 @@ class range_op_handler
public:
range_op_handler ();
range_op_handler (enum tree_code code);
- inline operator bool () const { return m_operator != NULL; }
+ operator bool () const;
+ range_operator *range_op () const;
bool fold_range (vrange &r, tree type,
const vrange &lh,
--
2.40.1