public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-378] Cleanup irange::set.
@ 2023-05-01 6:34 Aldy Hernandez
0 siblings, 0 replies; only message in thread
From: Aldy Hernandez @ 2023-05-01 6:34 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:178abecaa9ca96acee6e155261d4dc50dd98fab4
commit r14-378-g178abecaa9ca96acee6e155261d4dc50dd98fab4
Author: Aldy Hernandez <aldyh@redhat.com>
Date: Thu Mar 2 23:37:20 2023 +0100
Cleanup irange::set.
Now that anti-ranges are no more and iranges contain wide_ints instead
of trees, various cleanups are possible. This is one of a handful of
patches improving the performance of irange::set() which is not on a
hot path, but quite sensitive because it is so pervasive.
gcc/ChangeLog:
* gimple-range-op.cc (cfn_ffs::fold_range): Use the correct
precision.
* gimple-ssa-warn-alloca.cc (alloca_call_type): Use <2> for
invalid_range, as it is an inverse range.
* tree-vrp.cc (find_case_label_range): Avoid trees.
* value-range.cc (irange::irange_set): Delete.
(irange::irange_set_1bit_anti_range): Delete.
(irange::irange_set_anti_range): Delete.
(irange::set): Cleanup.
* value-range.h (class irange): Remove irange_set,
irange_set_anti_range, irange_set_1bit_anti_range.
(irange::set_undefined): Remove set to m_type.
Diff:
---
gcc/gimple-range-op.cc | 4 +-
gcc/gimple-ssa-warn-alloca.cc | 2 +-
gcc/tree-vrp.cc | 8 +-
gcc/value-range.cc | 175 ++++++++++++------------------------------
gcc/value-range.h | 5 --
5 files changed, 59 insertions(+), 135 deletions(-)
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 3aef8357d8d..5d1f921ba40 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -654,7 +654,9 @@ public:
range_cast (tmp, unsigned_type_for (tmp.type ()));
wide_int max = tmp.upper_bound ();
maxi = wi::floor_log2 (max) + 1;
- r.set (type, wi::shwi (mini, prec), wi::shwi (maxi, prec));
+ r.set (type,
+ wi::shwi (mini, TYPE_PRECISION (type)),
+ wi::shwi (maxi, TYPE_PRECISION (type)));
return true;
}
} op_cfn_ffs;
diff --git a/gcc/gimple-ssa-warn-alloca.cc b/gcc/gimple-ssa-warn-alloca.cc
index c129aca16e2..2d8ab93a81d 100644
--- a/gcc/gimple-ssa-warn-alloca.cc
+++ b/gcc/gimple-ssa-warn-alloca.cc
@@ -222,7 +222,7 @@ alloca_call_type (gimple *stmt, bool is_vla)
&& !r.varying_p ())
{
// The invalid bits are anything outside of [0, MAX_SIZE].
- int_range<1> invalid_range (size_type_node,
+ int_range<2> invalid_range (size_type_node,
wi::shwi (0, TYPE_PRECISION (size_type_node)),
wi::shwi (max_size, TYPE_PRECISION (size_type_node)),
VR_ANTI_RANGE);
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index d28637b1918..0761b6896fe 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -827,6 +827,8 @@ find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
size_t i, j;
tree op = gimple_switch_index (switch_stmt);
tree type = TREE_TYPE (op);
+ unsigned prec = TYPE_PRECISION (type);
+ signop sign = TYPE_SIGN (type);
tree tmin = wide_int_to_tree (type, range_of_op->lower_bound ());
tree tmax = wide_int_to_tree (type, range_of_op->upper_bound ());
find_case_label_range (switch_stmt, tmin, tmax, &i, &j);
@@ -837,9 +839,11 @@ find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
tree label = gimple_switch_label (switch_stmt, i);
tree case_high
= CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
+ wide_int wlow = wi::to_wide (CASE_LOW (label));
+ wide_int whigh = wi::to_wide (case_high);
int_range_max label_range (type,
- wi::to_wide (CASE_LOW (label)),
- wi::to_wide (case_high));
+ wide_int::from (wlow, prec, sign),
+ wide_int::from (whigh, prec, sign));
if (!types_compatible_p (label_range.type (), range_of_op->type ()))
range_cast (label_range, range_of_op->type ());
label_range.intersect (*range_of_op);
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 2dc6b98bc63..655ffc2d6d4 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -961,98 +961,6 @@ get_legacy_range (const irange &r, tree &min, tree &max)
return VR_RANGE;
}
-void
-irange::irange_set (tree type, const wide_int &min, const wide_int &max)
-{
- m_type = type;
- m_base[0] = min;
- m_base[1] = max;
- m_num_ranges = 1;
- m_kind = VR_RANGE;
- m_nonzero_mask = wi::minus_one (TYPE_PRECISION (type));
- normalize_kind ();
-
- if (flag_checking)
- verify_range ();
-}
-
-void
-irange::irange_set_1bit_anti_range (tree type,
- const wide_int &min, const wide_int &max)
-{
- unsigned prec = TYPE_PRECISION (type);
- signop sign = TYPE_SIGN (type);
- gcc_checking_assert (prec == 1);
-
- if (min == max)
- {
- wide_int tmp;
- // Since these are 1-bit quantities, they can only be [MIN,MIN]
- // or [MAX,MAX].
- if (min == wi::min_value (prec, sign))
- tmp = wi::max_value (prec, sign);
- else
- tmp = wi::min_value (prec, sign);
- set (type, tmp, tmp);
- }
- else
- {
- // The only alternative is [MIN,MAX], which is the empty range.
- gcc_checking_assert (min == wi::min_value (prec, sign));
- gcc_checking_assert (max == wi::max_value (prec, sign));
- set_undefined ();
- }
- if (flag_checking)
- verify_range ();
-}
-
-void
-irange::irange_set_anti_range (tree type,
- const wide_int &min, const wide_int &max)
-{
- if (TYPE_PRECISION (type) == 1)
- {
- irange_set_1bit_anti_range (type, min, max);
- return;
- }
-
- // set an anti-range
- signop sign = TYPE_SIGN (type);
- int_range<2> type_range (type);
- // Calculate INVERSE([I,J]) as [-MIN, I-1][J+1, +MAX].
- m_num_ranges = 0;
- wi::overflow_type ovf;
-
- if (wi::ne_p (min, type_range.lower_bound ()))
- {
- wide_int lim1 = wi::sub (min, 1, sign, &ovf);
- gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
- m_base[0] = type_range.lower_bound (0);
- m_base[1] = lim1;
- m_num_ranges = 1;
- }
- if (wi::ne_p (max, type_range.upper_bound ()))
- {
- if (m_max_ranges == 1 && m_num_ranges)
- {
- set_varying (type);
- return;
- }
- wide_int lim2 = wi::add (max, 1, sign, &ovf);
- gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
- m_base[m_num_ranges * 2] = lim2;
- m_base[m_num_ranges * 2 + 1] = type_range.upper_bound (0);
- ++m_num_ranges;
- }
-
- m_kind = VR_RANGE;
- m_nonzero_mask = wi::minus_one (TYPE_PRECISION (type));
- normalize_kind ();
-
- if (flag_checking)
- verify_range ();
-}
-
/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}.
This means adjusting VRTYPE, MIN and MAX representing the case of a
wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
@@ -1063,48 +971,69 @@ irange::irange_set_anti_range (tree type,
extract ranges from var + CST op limit. */
void
-irange::set (tree type, const wide_int &rmin, const wide_int &rmax,
+irange::set (tree type, const wide_int &min, const wide_int &max,
value_range_kind kind)
{
- if (kind == VR_UNDEFINED)
- {
- irange::set_undefined ();
- return;
- }
-
- if (kind == VR_VARYING)
- {
- set_varying (type);
- return;
- }
+ unsigned prec = TYPE_PRECISION (type);
+ signop sign = TYPE_SIGN (type);
+ wide_int min_value = wi::min_value (prec, sign);
+ wide_int max_value = wi::max_value (prec, sign);
m_type = type;
- signop sign = TYPE_SIGN (type);
- unsigned prec = TYPE_PRECISION (type);
- wide_int min = wide_int::from (rmin, prec, sign);
- wide_int max = wide_int::from (rmax, prec, sign);
+ m_nonzero_mask = wi::minus_one (prec);
if (kind == VR_RANGE)
- irange_set (type, min, max);
+ {
+ m_base[0] = min;
+ m_base[1] = max;
+ m_num_ranges = 1;
+ if (min == min_value && max == max_value)
+ m_kind = VR_VARYING;
+ else
+ m_kind = VR_RANGE;
+ }
else
{
gcc_checking_assert (kind == VR_ANTI_RANGE);
- irange_set_anti_range (type, min, max);
+ gcc_checking_assert (m_max_ranges > 1);
+
+ m_kind = VR_UNDEFINED;
+ m_num_ranges = 0;
+ wi::overflow_type ovf;
+ wide_int lim;
+ if (sign == SIGNED)
+ lim = wi::add (min, -1, sign, &ovf);
+ else
+ lim = wi::sub (min, 1, sign, &ovf);
+
+ if (!ovf)
+ {
+ m_kind = VR_RANGE;
+ m_base[0] = min_value;
+ m_base[1] = lim;
+ ++m_num_ranges;
+ }
+ if (sign == SIGNED)
+ lim = wi::sub (max, -1, sign, &ovf);
+ else
+ lim = wi::add (max, 1, sign, &ovf);
+ if (!ovf)
+ {
+ m_kind = VR_RANGE;
+ m_base[m_num_ranges * 2] = lim;
+ m_base[m_num_ranges * 2 + 1] = max_value;
+ ++m_num_ranges;
+ }
}
+
+ if (flag_checking)
+ verify_range ();
}
void
irange::set (tree min, tree max, value_range_kind kind)
{
- if (kind == VR_UNDEFINED)
- {
- irange::set_undefined ();
- return;
- }
-
- if (kind == VR_VARYING
- || POLY_INT_CST_P (min)
- || POLY_INT_CST_P (max))
+ if (POLY_INT_CST_P (min) || POLY_INT_CST_P (max))
{
set_varying (TREE_TYPE (min));
return;
@@ -1113,13 +1042,7 @@ irange::set (tree min, tree max, value_range_kind kind)
gcc_checking_assert (TREE_CODE (min) == INTEGER_CST);
gcc_checking_assert (TREE_CODE (max) == INTEGER_CST);
- if (TREE_OVERFLOW_P (min))
- min = drop_tree_overflow (min);
- if (TREE_OVERFLOW_P (max))
- max = drop_tree_overflow (max);
-
- return set (TREE_TYPE (min),
- wi::to_wide (min), wi::to_wide (max), kind);
+ return set (TREE_TYPE (min), wi::to_wide (min), wi::to_wide (max), kind);
}
// Check the validity of the range.
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 9f82b0011c7..9a834c91b17 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -172,8 +172,6 @@ protected:
irange (wide_int *, unsigned);
// In-place operators.
- void irange_set (tree type, const wide_int &, const wide_int &);
- void irange_set_anti_range (tree type, const wide_int &, const wide_int &);
bool irange_contains_p (const irange &) const;
bool irange_single_pair_union (const irange &r);
@@ -186,8 +184,6 @@ private:
friend void gt_pch_nx (irange *);
friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
- void irange_set_1bit_anti_range (tree type,
- const wide_int &, const wide_int &);
bool varying_compatible_p () const;
bool intersect_nonzero_bits (const irange &r);
bool union_nonzero_bits (const irange &r);
@@ -831,7 +827,6 @@ inline void
irange::set_undefined ()
{
m_kind = VR_UNDEFINED;
- m_type = NULL;
m_num_ranges = 0;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-05-01 6:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-01 6:34 [gcc r14-378] Cleanup irange::set Aldy Hernandez
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).