From: Aldy Hernandez <aldyh@redhat.com>
To: GCC patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH 5/5] Convert ranger and clients to vrange.
Date: Wed, 1 Jun 2022 11:04:52 +0200 [thread overview]
Message-ID: <CAGm3qMXkb8YnG1SU0Xwh_a5cBa2kB3Aa6nKck9OrsVtOhmYCKQ@mail.gmail.com> (raw)
In-Reply-To: <20220530132751.1752112-5-aldyh@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 117785 bytes --]
Final patch committed.
All users but one of Value_Range::set_type() have been removed in
favor of using a constructor taking a type. We still need to delay
initialization for one use in gimple_infer_range, as it has an array
of temporaries for which the type is not known until later.
Re-tested on x86-64 Linux.
On Mon, May 30, 2022 at 3:28 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>
> Finally, the meat of the work. Convert ranger and associated clients
> to vrange.
>
> Everything's relatively mechanical given the previous patches. I did
> include a minor cleanup in the edge code. There's no need to check
> that the type of the switch is an integer as non-integer switches are
> invalid. I verified this with an appropriately coded assert.
>
> Tested on x86-64 & ppc64le Linux.
>
> gcc/ChangeLog:
>
> * gimple-range-cache.cc (ssa_block_ranges::dump): Convert to vrange.
> (sbr_vector::sbr_vector): Same.
> (sbr_vector::grow): Same.
> (sbr_vector::set_bb_range): Same.
> (sbr_vector::get_bb_range): Same.
> (sbr_sparse_bitmap::sbr_sparse_bitmap): Same.
> (sbr_sparse_bitmap::set_bb_range): Same.
> (sbr_sparse_bitmap::get_bb_range): Same.
> (block_range_cache::set_bb_range): Same.
> (block_range_cache::get_bb_range): Same.
> (block_range_cache::dump): Same.
> (ssa_global_cache::get_global_range): Same.
> (ssa_global_cache::set_global_range): Same.
> (ssa_global_cache::clear): Same.
> (ssa_global_cache::dump): Same.
> (ranger_cache::get_global_range): Same.
> (ranger_cache::set_global_range): Same.
> (ranger_cache::range_of_def): Same.
> (ranger_cache::entry_range): Same.
> (ranger_cache::exit_range): Same.
> (ranger_cache::edge_range): Same.
> (ranger_cache::range_of_expr): Same.
> (ranger_cache::range_on_edge): Same.
> (ranger_cache::block_range): Same.
> (ranger_cache::propagate_cache): Same.
> (ranger_cache::fill_block_cache): Same.
> (ranger_cache::range_from_dom): Same.
> * gimple-range-cache.h: Same.
> * gimple-range-edge.cc (gimple_outgoing_range::get_edge_range):
> Same.
> (gimple_outgoing_range::switch_edge_range): Same.
> (gimple_outgoing_range::edge_range_p): Same.
> * gimple-range-edge.h: Same.
> * gimple-range-fold.cc (fur_source::get_operand): Same.
> (fur_source::get_phi_operand): Same.
> (fur_edge::get_operand): Same.
> (fur_edge::get_phi_operand): Same.
> (fur_stmt::get_operand): Same.
> (fur_stmt::get_phi_operand): Same.
> (fur_list::fur_list): Same.
> (fur_list::get_operand): Same.
> (fur_list::get_phi_operand): Same.
> (fold_range): Same.
> (adjust_imagpart_expr): Same.
> (adjust_realpart_expr): Same.
> (gimple_range_adjustment): Same.
> (fold_using_range::fold_stmt): Same.
> (fold_using_range::range_of_range_op): Same.
> (fold_using_range::range_of_address): Same.
> (fold_using_range::range_of_phi): Same.
> (fold_using_range::range_of_call): Same.
> (fold_using_range::range_of_builtin_call): Same.
> (fold_using_range::range_of_builtin_int_call): Same.
> (fold_using_range::range_of_cond_expr): Same.
> (fur_source::register_outgoing_edges): Same.
> * gimple-range-fold.h (fold_range): Same.
> (gimple_range_type): Same.
> (gimple_range_ssa_p): Same.
> * gimple-range-gori.cc (gimple_range_calc_op1): Same.
> (gimple_range_calc_op2): Same.
> (gori_compute::compute_operand_range_switch): Same.
> (gori_compute::compute_operand_range): Same.
> (gori_compute::logical_combine): Same.
> (gori_compute::compute_logical_operands): Same.
> (gori_compute::compute_operand1_range): Same.
> (gori_compute::compute_operand2_range): Same.
> (gori_compute::compute_operand1_and_operand2_range): Same.
> (gori_compute::outgoing_edge_range_p): Same.
> (gori_compute::condexpr_adjust): Same.
> * gimple-range-gori.h (gimple_range_calc_op1): Same.
> (gimple_range_calc_op2): Same.
> * gimple-range-path.cc (path_range_query::get_cache): Same.
> (path_range_query::set_cache): Same.
> (path_range_query::range_on_path_entry): Same.
> (path_range_query::internal_range_of_expr): Same.
> (path_range_query::range_of_expr): Same.
> (path_range_query::ssa_range_in_phi): Same.
> (path_range_query::range_defined_in_block): Same.
> (path_range_query::compute_ranges_in_phis): Same.
> (path_range_query::compute_ranges_in_block): Same.
> (path_range_query::add_to_imports): Same.
> (path_range_query::range_of_stmt): Same.
> * gimple-range-path.h: Same.
> * gimple-range-side-effect.cc (stmt_side_effects::add_range): Same.
> (side_effect_manager::~side_effect_manager): Same.
> (side_effect_manager::get_nonzero): Same.
> (side_effect_manager::maybe_adjust_range): Same.
> (side_effect_manager::add_range): Same.
> * gimple-range-side-effect.h: Same.
> * gimple-range-tests.cc: Same.
> * gimple-range-trace.cc (range_tracer::trailer): Same.
> (debug_seed_ranger): Same.
> * gimple-range-trace.h: Same.
> * gimple-range.cc (gimple_ranger::range_of_expr): Same.
> (gimple_ranger::range_on_entry): Same.
> (gimple_ranger::range_on_exit): Same.
> (gimple_ranger::range_on_edge): Same.
> (gimple_ranger::fold_range_internal): Same.
> (gimple_ranger::range_of_stmt): Same.
> (gimple_ranger::prefill_name): Same.
> (gimple_ranger::prefill_stmt_dependencies): Same.
> (gimple_ranger::export_global_ranges): Same.
> (gimple_ranger::dump_bb): Same.
> * gimple-range.h: Same.
> * gimple-ssa-warn-access.cc (check_nul_terminated_array): Same.
> (memmodel_to_uhwi): Same.
> * tree-ssa-loop-niter.cc (refine_value_range_using_guard): Same.
> (determine_value_range): Same.
> (record_nonwrapping_iv): Same.
> (infer_loop_bounds_from_signedness): Same.
> (scev_var_range_cant_overflow): Same.
> * tree-ssa-threadedge.cc (hybrid_jt_simplifier::simplify): Same.
> * value-query.cc (range_query::range_on_edge): Same.
> (range_query::range_of_stmt): Same.
> (range_query::value_of_expr): Same.
> (range_query::value_on_edge): Same.
> (range_query::value_of_stmt): Same.
> (range_query::get_tree_range): Same.
> (update_global_range): Same.
> (get_range_global): Same.
> (gimple_range_global): Same.
> (global_range_query::range_of_expr): Same.
> (range_query::query_relation): Same.
> * value-query.h (gimple_range_global): Same.
> (update_global_range): Same.
> * vr-values.cc (vr_values::range_of_expr): Same.
> (bounds_of_var_in_loop): Same.
> (simplify_using_ranges::vrp_visit_cond_stmt): Same.
> * vr-values.h (class vr_values): Same.
> ---
> gcc/gimple-range-cache.cc | 136 ++++++++++++++++--------------
> gcc/gimple-range-cache.h | 32 +++----
> gcc/gimple-range-edge.cc | 12 +--
> gcc/gimple-range-edge.h | 2 +-
> gcc/gimple-range-fold.cc | 144 +++++++++++++++++++-------------
> gcc/gimple-range-fold.h | 37 ++++----
> gcc/gimple-range-gori.cc | 116 ++++++++++++++-----------
> gcc/gimple-range-gori.h | 42 +++++-----
> gcc/gimple-range-path.cc | 47 ++++++-----
> gcc/gimple-range-path.h | 16 ++--
> gcc/gimple-range-side-effect.cc | 20 ++---
> gcc/gimple-range-side-effect.h | 14 ++--
> gcc/gimple-range-tests.cc | 3 +-
> gcc/gimple-range-trace.cc | 9 +-
> gcc/gimple-range-trace.h | 2 +-
> gcc/gimple-range.cc | 44 ++++++----
> gcc/gimple-range.h | 14 ++--
> gcc/gimple-ssa-warn-access.cc | 7 +-
> gcc/tree-ssa-loop-niter.cc | 16 ++--
> gcc/tree-ssa-threadedge.cc | 4 +-
> gcc/value-query.cc | 73 ++++++++--------
> gcc/value-query.h | 16 ++--
> gcc/vr-values.cc | 29 ++++---
> gcc/vr-values.h | 2 +-
> 24 files changed, 457 insertions(+), 380 deletions(-)
>
> diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
> index 9c541993fb6..4983e4d3aa7 100644
> --- a/gcc/gimple-range-cache.cc
> +++ b/gcc/gimple-range-cache.cc
> @@ -44,11 +44,14 @@ along with GCC; see the file COPYING3. If not see
> class ssa_block_ranges
> {
> public:
> - virtual bool set_bb_range (const_basic_block bb, const irange &r) = 0;
> - virtual bool get_bb_range (irange &r, const_basic_block bb) = 0;
> + ssa_block_ranges (tree t) : m_type (t) { }
> + virtual bool set_bb_range (const_basic_block bb, const vrange &r) = 0;
> + virtual bool get_bb_range (vrange &r, const_basic_block bb) = 0;
> virtual bool bb_range_p (const_basic_block bb) = 0;
>
> void dump(FILE *f);
> +private:
> + tree m_type;
> };
>
> // Print the list of known ranges for file F in a nice format.
> @@ -57,7 +60,7 @@ void
> ssa_block_ranges::dump (FILE *f)
> {
> basic_block bb;
> - int_range_max r;
> + tmp_range r (m_type);
>
> FOR_EACH_BB_FN (bb, cfun)
> if (get_bb_range (r, bb))
> @@ -77,14 +80,14 @@ class sbr_vector : public ssa_block_ranges
> public:
> sbr_vector (tree t, vrange_allocator *allocator);
>
> - virtual bool set_bb_range (const_basic_block bb, const irange &r) override;
> - virtual bool get_bb_range (irange &r, const_basic_block bb) override;
> + virtual bool set_bb_range (const_basic_block bb, const vrange &r) override;
> + virtual bool get_bb_range (vrange &r, const_basic_block bb) override;
> virtual bool bb_range_p (const_basic_block bb) override;
> protected:
> - irange **m_tab; // Non growing vector.
> + vrange **m_tab; // Non growing vector.
> int m_tab_size;
> - int_range<2> m_varying;
> - int_range<2> m_undefined;
> + vrange *m_varying;
> + vrange *m_undefined;
> tree m_type;
> vrange_allocator *m_range_allocator;
> void grow ();
> @@ -94,18 +97,21 @@ protected:
> // Initialize a block cache for an ssa_name of type T.
>
> sbr_vector::sbr_vector (tree t, vrange_allocator *allocator)
> + : ssa_block_ranges (t)
> {
> gcc_checking_assert (TYPE_P (t));
> m_type = t;
> m_range_allocator = allocator;
> m_tab_size = last_basic_block_for_fn (cfun) + 1;
> - m_tab = static_cast <irange **>
> - (allocator->alloc (m_tab_size * sizeof (irange *)));
> - memset (m_tab, 0, m_tab_size * sizeof (irange *));
> + m_tab = static_cast <vrange **>
> + (allocator->alloc (m_tab_size * sizeof (vrange *)));
> + memset (m_tab, 0, m_tab_size * sizeof (vrange *));
>
> // Create the cached type range.
> - m_varying.set_varying (t);
> - m_undefined.set_undefined ();
> + m_varying = m_range_allocator->alloc_vrange (t);
> + m_undefined = m_range_allocator->alloc_vrange (t);
> + m_varying->set_varying (t);
> + m_undefined->set_undefined ();
> }
>
> // Grow the vector when the CFG has increased in size.
> @@ -122,10 +128,10 @@ sbr_vector::grow ()
> int new_size = inc + curr_bb_size;
>
> // Allocate new memory, copy the old vector and clear the new space.
> - irange **t = static_cast <irange **>
> - (m_range_allocator->alloc (new_size * sizeof (irange *)));
> - memcpy (t, m_tab, m_tab_size * sizeof (irange *));
> - memset (t + m_tab_size, 0, (new_size - m_tab_size) * sizeof (irange *));
> + vrange **t = static_cast <vrange **>
> + (m_range_allocator->alloc (new_size * sizeof (vrange *)));
> + memcpy (t, m_tab, m_tab_size * sizeof (vrange *));
> + memset (t + m_tab_size, 0, (new_size - m_tab_size) * sizeof (vrange *));
>
> m_tab = t;
> m_tab_size = new_size;
> @@ -134,15 +140,15 @@ sbr_vector::grow ()
> // Set the range for block BB to be R.
>
> bool
> -sbr_vector::set_bb_range (const_basic_block bb, const irange &r)
> +sbr_vector::set_bb_range (const_basic_block bb, const vrange &r)
> {
> - irange *m;
> + vrange *m;
> if (bb->index >= m_tab_size)
> grow ();
> if (r.varying_p ())
> - m = &m_varying;
> + m = m_varying;
> else if (r.undefined_p ())
> - m = &m_undefined;
> + m = m_undefined;
> else
> m = m_range_allocator->clone (r);
> m_tab[bb->index] = m;
> @@ -153,11 +159,11 @@ sbr_vector::set_bb_range (const_basic_block bb, const irange &r)
> // there is no range.
>
> bool
> -sbr_vector::get_bb_range (irange &r, const_basic_block bb)
> +sbr_vector::get_bb_range (vrange &r, const_basic_block bb)
> {
> if (bb->index >= m_tab_size)
> return false;
> - irange *m = m_tab[bb->index];
> + vrange *m = m_tab[bb->index];
> if (m)
> {
> r = *m;
> @@ -193,14 +199,14 @@ class sbr_sparse_bitmap : public ssa_block_ranges
> {
> public:
> sbr_sparse_bitmap (tree t, vrange_allocator *allocator, bitmap_obstack *bm);
> - virtual bool set_bb_range (const_basic_block bb, const irange &r) override;
> - virtual bool get_bb_range (irange &r, const_basic_block bb) override;
> + virtual bool set_bb_range (const_basic_block bb, const vrange &r) override;
> + virtual bool get_bb_range (vrange &r, const_basic_block bb) override;
> virtual bool bb_range_p (const_basic_block bb) override;
> private:
> void bitmap_set_quad (bitmap head, int quad, int quad_value);
> int bitmap_get_quad (const_bitmap head, int quad);
> vrange_allocator *m_range_allocator;
> - irange *m_range[SBR_NUM];
> + vrange *m_range[SBR_NUM];
> bitmap_head bitvec;
> tree m_type;
> };
> @@ -209,6 +215,7 @@ private:
>
> sbr_sparse_bitmap::sbr_sparse_bitmap (tree t, vrange_allocator *allocator,
> bitmap_obstack *bm)
> + : ssa_block_ranges (t)
> {
> gcc_checking_assert (TYPE_P (t));
> m_type = t;
> @@ -216,16 +223,14 @@ sbr_sparse_bitmap::sbr_sparse_bitmap (tree t, vrange_allocator *allocator,
> bitmap_tree_view (&bitvec);
> m_range_allocator = allocator;
> // Pre-cache varying.
> - m_range[0] = static_cast <irange *> (m_range_allocator->alloc_vrange (t));
> + m_range[0] = m_range_allocator->alloc_vrange (t);
> m_range[0]->set_varying (t);
> // Pre-cache zero and non-zero values for pointers.
> if (POINTER_TYPE_P (t))
> {
> - m_range[1]
> - = static_cast <irange *> (m_range_allocator->alloc_vrange (t));
> + m_range[1] = m_range_allocator->alloc_vrange (t);
> m_range[1]->set_nonzero (t);
> - m_range[2]
> - = static_cast <irange *> (m_range_allocator->alloc_vrange (t));
> + m_range[2] = m_range_allocator->alloc_vrange (t);
> m_range[2]->set_zero (t);
> }
> else
> @@ -257,7 +262,7 @@ sbr_sparse_bitmap::bitmap_get_quad (const_bitmap head, int quad)
> // Set the range on entry to basic block BB to R.
>
> bool
> -sbr_sparse_bitmap::set_bb_range (const_basic_block bb, const irange &r)
> +sbr_sparse_bitmap::set_bb_range (const_basic_block bb, const vrange &r)
> {
> if (r.undefined_p ())
> {
> @@ -283,7 +288,7 @@ sbr_sparse_bitmap::set_bb_range (const_basic_block bb, const irange &r)
> // there is no range.
>
> bool
> -sbr_sparse_bitmap::get_bb_range (irange &r, const_basic_block bb)
> +sbr_sparse_bitmap::get_bb_range (vrange &r, const_basic_block bb)
> {
> int value = bitmap_get_quad (&bitvec, bb->index);
>
> @@ -333,7 +338,7 @@ block_range_cache::~block_range_cache ()
>
> bool
> block_range_cache::set_bb_range (tree name, const_basic_block bb,
> - const irange &r)
> + const vrange &r)
> {
> unsigned v = SSA_NAME_VERSION (name);
> if (v >= m_ssa_ranges.length ())
> @@ -379,7 +384,7 @@ block_range_cache::query_block_ranges (tree name)
> // is one.
>
> bool
> -block_range_cache::get_bb_range (irange &r, tree name, const_basic_block bb)
> +block_range_cache::get_bb_range (vrange &r, tree name, const_basic_block bb)
> {
> ssa_block_ranges *ptr = query_block_ranges (name);
> if (ptr)
> @@ -423,12 +428,13 @@ void
> block_range_cache::dump (FILE *f, basic_block bb, bool print_varying)
> {
> unsigned x;
> - int_range_max r;
> bool summarize_varying = false;
> for (x = 1; x < m_ssa_ranges.length (); ++x)
> {
> if (!gimple_range_ssa_p (ssa_name (x)))
> continue;
> +
> + tmp_range r (TREE_TYPE (ssa_name (x)));
> if (m_ssa_ranges[x] && m_ssa_ranges[x]->get_bb_range (r, bb))
> {
> if (!print_varying && r.varying_p ())
> @@ -450,6 +456,8 @@ block_range_cache::dump (FILE *f, basic_block bb, bool print_varying)
> {
> if (!gimple_range_ssa_p (ssa_name (x)))
> continue;
> +
> + tmp_range r (TREE_TYPE (ssa_name (x)));
> if (m_ssa_ranges[x] && m_ssa_ranges[x]->get_bb_range (r, bb))
> {
> if (r.varying_p ())
> @@ -485,13 +493,13 @@ ssa_global_cache::~ssa_global_cache ()
> // Return the value in R.
>
> bool
> -ssa_global_cache::get_global_range (irange &r, tree name) const
> +ssa_global_cache::get_global_range (vrange &r, tree name) const
> {
> unsigned v = SSA_NAME_VERSION (name);
> if (v >= m_tab.length ())
> return false;
>
> - irange *stow = m_tab[v];
> + vrange *stow = m_tab[v];
> if (!stow)
> return false;
> r = *stow;
> @@ -502,13 +510,13 @@ ssa_global_cache::get_global_range (irange &r, tree name) const
> // Return TRUE if there was already a range set, otherwise false.
>
> bool
> -ssa_global_cache::set_global_range (tree name, const irange &r)
> +ssa_global_cache::set_global_range (tree name, const vrange &r)
> {
> unsigned v = SSA_NAME_VERSION (name);
> if (v >= m_tab.length ())
> m_tab.safe_grow_cleared (num_ssa_names + 1);
>
> - irange *m = m_tab[v];
> + vrange *m = m_tab[v];
> if (m && m->fits_p (r))
> *m = r;
> else
> @@ -533,7 +541,7 @@ void
> ssa_global_cache::clear ()
> {
> if (m_tab.address ())
> - memset (m_tab.address(), 0, m_tab.length () * sizeof (irange *));
> + memset (m_tab.address(), 0, m_tab.length () * sizeof (vrange *));
> }
>
> // Dump the contents of the global cache to F.
> @@ -545,8 +553,9 @@ ssa_global_cache::dump (FILE *f)
> bool print_header = true;
> for (unsigned x = 1; x < num_ssa_names; x++)
> {
> - int_range_max r;
> + tmp_range r;
> if (gimple_range_ssa_p (ssa_name (x)) &&
> + r.init (TREE_TYPE (ssa_name (x))) &&
> get_global_range (r, ssa_name (x)) && !r.varying_p ())
> {
> if (print_header)
> @@ -809,11 +818,11 @@ ranger_cache::dump_bb (FILE *f, basic_block bb)
> // global range is not set, and return the legacy global value in R.
>
> bool
> -ranger_cache::get_global_range (irange &r, tree name) const
> +ranger_cache::get_global_range (vrange &r, tree name) const
> {
> if (m_globals.get_global_range (r, name))
> return true;
> - r = gimple_range_global (name);
> + gimple_range_global (r, name);
> return false;
> }
>
> @@ -825,7 +834,7 @@ ranger_cache::get_global_range (irange &r, tree name) const
> // After this call, the global cache will have a value.
>
> bool
> -ranger_cache::get_global_range (irange &r, tree name, bool ¤t_p)
> +ranger_cache::get_global_range (vrange &r, tree name, bool ¤t_p)
> {
> bool had_global = get_global_range (r, name);
>
> @@ -847,7 +856,7 @@ ranger_cache::get_global_range (irange &r, tree name, bool ¤t_p)
> // Set the global range of NAME to R and give it a timestamp.
>
> void
> -ranger_cache::set_global_range (tree name, const irange &r)
> +ranger_cache::set_global_range (tree name, const vrange &r)
> {
> if (m_globals.set_global_range (name, r))
> {
> @@ -882,7 +891,7 @@ ranger_cache::set_global_range (tree name, const irange &r)
> // get the best global value available.
>
> void
> -ranger_cache::range_of_def (irange &r, tree name, basic_block bb)
> +ranger_cache::range_of_def (vrange &r, tree name, basic_block bb)
> {
> gcc_checking_assert (gimple_range_ssa_p (name));
> gcc_checking_assert (!bb || bb == gimple_bb (SSA_NAME_DEF_STMT (name)));
> @@ -895,7 +904,7 @@ ranger_cache::range_of_def (irange &r, tree name, basic_block bb)
> if (gimple_get_lhs (s) == name)
> fold_range (r, s, get_global_range_query ());
> else
> - r = gimple_range_global (name);
> + gimple_range_global (r, name);
> }
> }
>
> @@ -903,12 +912,12 @@ ranger_cache::range_of_def (irange &r, tree name, basic_block bb)
> // lookups.
>
> void
> -ranger_cache::entry_range (irange &r, tree name, basic_block bb,
> +ranger_cache::entry_range (vrange &r, tree name, basic_block bb,
> enum rfd_mode mode)
> {
> if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
> {
> - r = gimple_range_global (name);
> + gimple_range_global (r, name);
> return;
> }
>
> @@ -923,12 +932,12 @@ ranger_cache::entry_range (irange &r, tree name, basic_block bb,
> // lookups.
>
> void
> -ranger_cache::exit_range (irange &r, tree name, basic_block bb,
> +ranger_cache::exit_range (vrange &r, tree name, basic_block bb,
> enum rfd_mode mode)
> {
> if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
> {
> - r = gimple_range_global (name);
> + gimple_range_global (r, name);
> return;
> }
>
> @@ -944,7 +953,7 @@ ranger_cache::exit_range (irange &r, tree name, basic_block bb,
> // Always returns a range and true.
>
> bool
> -ranger_cache::edge_range (irange &r, edge e, tree name, enum rfd_mode mode)
> +ranger_cache::edge_range (vrange &r, edge e, tree name, enum rfd_mode mode)
> {
> exit_range (r, name, e->src, mode);
> // If this is not an abnormal edge, check for side effects on exit.
> @@ -961,7 +970,7 @@ ranger_cache::edge_range (irange &r, edge e, tree name, enum rfd_mode mode)
> // Implement range_of_expr.
>
> bool
> -ranger_cache::range_of_expr (irange &r, tree name, gimple *stmt)
> +ranger_cache::range_of_expr (vrange &r, tree name, gimple *stmt)
> {
> if (!gimple_range_ssa_p (name))
> {
> @@ -985,7 +994,7 @@ ranger_cache::range_of_expr (irange &r, tree name, gimple *stmt)
> // the current cache values.
>
> bool
> -ranger_cache::range_on_edge (irange &r, edge e, tree expr)
> +ranger_cache::range_on_edge (vrange &r, edge e, tree expr)
> {
> if (gimple_range_ssa_p (expr))
> return edge_range (r, e, expr, RFD_NONE);
> @@ -997,7 +1006,7 @@ ranger_cache::range_on_edge (irange &r, edge e, tree expr)
> // def block for NAME. Otherwise, return false if the cache is empty.
>
> bool
> -ranger_cache::block_range (irange &r, basic_block bb, tree name, bool calc)
> +ranger_cache::block_range (vrange &r, basic_block bb, tree name, bool calc)
> {
> gcc_checking_assert (gimple_range_ssa_p (name));
>
> @@ -1041,9 +1050,10 @@ ranger_cache::propagate_cache (tree name)
> basic_block bb;
> edge_iterator ei;
> edge e;
> - int_range_max new_range;
> - int_range_max current_range;
> - int_range_max e_range;
> + tree type = TREE_TYPE (name);
> + tmp_range new_range (type);
> + tmp_range current_range (type);
> + tmp_range e_range (type);
>
> // Process each block by seeing if its calculated range on entry is
> // the same as its cached value. If there is a difference, update
> @@ -1178,8 +1188,8 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
> {
> edge_iterator ei;
> edge e;
> - int_range_max block_result;
> - int_range_max undefined;
> + tmp_range block_result (TREE_TYPE (name));
> + tmp_range undefined (TREE_TYPE (name));
>
> // At this point we shouldn't be looking at the def, entry or exit block.
> gcc_checking_assert (bb != def_bb && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
> @@ -1232,7 +1242,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
> FOR_EACH_EDGE (e, ei, node->preds)
> {
> basic_block pred = e->src;
> - int_range_max r;
> + tmp_range r (TREE_TYPE (name));
>
> if (DEBUG_RANGE_CACHE)
> fprintf (dump_file, " %d->%d ",e->src->index, e->dest->index);
> @@ -1306,7 +1316,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
> // dominator tree based on MODE.
>
> bool
> -ranger_cache::range_from_dom (irange &r, tree name, basic_block start_bb,
> +ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
> enum rfd_mode mode)
> {
> if (mode == RFD_NONE || !dom_info_available_p (CDI_DOMINATORS))
> diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
> index 2472cd04f47..d17950c7154 100644
> --- a/gcc/gimple-range-cache.h
> +++ b/gcc/gimple-range-cache.h
> @@ -34,8 +34,8 @@ public:
> block_range_cache ();
> ~block_range_cache ();
>
> - bool set_bb_range (tree name, const_basic_block bb, const irange &r);
> - bool get_bb_range (irange &r, tree name, const_basic_block bb);
> + bool set_bb_range (tree name, const_basic_block bb, const vrange &v);
> + bool get_bb_range (vrange &v, tree name, const_basic_block bb);
> bool bb_range_p (tree name, const_basic_block bb);
>
> void dump (FILE *f);
> @@ -57,13 +57,13 @@ class ssa_global_cache
> public:
> ssa_global_cache ();
> ~ssa_global_cache ();
> - bool get_global_range (irange &r, tree name) const;
> - bool set_global_range (tree name, const irange &r);
> + bool get_global_range (vrange &r, tree name) const;
> + bool set_global_range (tree name, const vrange &r);
> void clear_global_range (tree name);
> void clear ();
> void dump (FILE *f = stderr);
> private:
> - vec<irange *> m_tab;
> + vec<vrange *> m_tab;
> vrange_allocator *m_range_allocator;
> };
>
> @@ -77,13 +77,13 @@ public:
> ranger_cache (int not_executable_flag, bool use_imm_uses);
> ~ranger_cache ();
>
> - virtual bool range_of_expr (irange &r, tree name, gimple *stmt);
> - virtual bool range_on_edge (irange &r, edge e, tree expr);
> - bool block_range (irange &r, basic_block bb, tree name, bool calc = true);
> + virtual bool range_of_expr (vrange &r, tree name, gimple *stmt);
> + virtual bool range_on_edge (vrange &r, edge e, tree expr);
> + bool block_range (vrange &r, basic_block bb, tree name, bool calc = true);
>
> - bool get_global_range (irange &r, tree name) const;
> - bool get_global_range (irange &r, tree name, bool ¤t_p);
> - void set_global_range (tree name, const irange &r);
> + bool get_global_range (vrange &r, tree name) const;
> + bool get_global_range (vrange &r, tree name, bool ¤t_p);
> + void set_global_range (tree name, const vrange &r);
>
> void propagate_updated_value (tree name, basic_block bb);
>
> @@ -106,11 +106,11 @@ private:
> RFD_READ_ONLY, // Scan DOM tree, do not write to cache.
> RFD_FILL // Scan DOM tree, updating important nodes.
> };
> - bool range_from_dom (irange &r, tree name, basic_block bb, enum rfd_mode);
> - void range_of_def (irange &r, tree name, basic_block bb = NULL);
> - void entry_range (irange &r, tree expr, basic_block bb, enum rfd_mode);
> - void exit_range (irange &r, tree expr, basic_block bb, enum rfd_mode);
> - bool edge_range (irange &r, edge e, tree name, enum rfd_mode);
> + bool range_from_dom (vrange &r, tree name, basic_block bb, enum rfd_mode);
> + void range_of_def (vrange &r, tree name, basic_block bb = NULL);
> + void entry_range (vrange &r, tree expr, basic_block bb, enum rfd_mode);
> + void exit_range (vrange &r, tree expr, basic_block bb, enum rfd_mode);
> + bool edge_range (vrange &r, edge e, tree name, enum rfd_mode);
>
> vec<basic_block> m_workback;
> class update_list *m_update;
> diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
> index 5264e627c9a..6fe33408f7e 100644
> --- a/gcc/gimple-range-edge.cc
> +++ b/gcc/gimple-range-edge.cc
> @@ -83,11 +83,8 @@ gimple_outgoing_range::~gimple_outgoing_range ()
> // Use a cached value if it exists, or calculate it if not.
>
> bool
> -gimple_outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
> +gimple_outgoing_range::switch_edge_range (irange &r, gswitch *sw, edge e)
> {
> - gcc_checking_assert (is_a<gswitch *> (s));
> - gswitch *sw = as_a<gswitch *> (s);
> -
> // ADA currently has cases where the index is 64 bits and the case
> // arguments are 32 bit, causing a trap when we create a case_range.
> // Until this is resolved (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87798)
> @@ -204,12 +201,9 @@ gimple_outgoing_range::edge_range_p (irange &r, edge e)
>
> gcc_checking_assert (is_a<gswitch *> (s));
> gswitch *sw = as_a<gswitch *> (s);
> - tree type = TREE_TYPE (gimple_switch_index (sw));
> -
> - if (!irange::supports_type_p (type))
> - return NULL;
>
> - if (get_edge_range (r, sw, e))
> + // Switches can only be integers.
> + if (switch_edge_range (as_a <irange> (r), sw, e))
> return s;
>
> return NULL;
> diff --git a/gcc/gimple-range-edge.h b/gcc/gimple-range-edge.h
> index ce383b0aa6f..a9c4af8715b 100644
> --- a/gcc/gimple-range-edge.h
> +++ b/gcc/gimple-range-edge.h
> @@ -43,7 +43,7 @@ public:
> gimple *edge_range_p (irange &r, edge e);
> private:
> void calc_switch_ranges (gswitch *sw);
> - bool get_edge_range (irange &r, gimple *s, edge e);
> + bool switch_edge_range (irange &r, gswitch *sw, edge e);
>
> int m_max_edges;
> hash_map<edge, irange *> *m_edge_table;
> diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> index c53d2863d5e..7fed5a99513 100644
> --- a/gcc/gimple-range-fold.cc
> +++ b/gcc/gimple-range-fold.cc
> @@ -60,7 +60,7 @@ fur_source::fur_source (range_query *q)
> // Invoke range_of_expr on EXPR.
>
> bool
> -fur_source::get_operand (irange &r, tree expr)
> +fur_source::get_operand (vrange &r, tree expr)
> {
> return m_query->range_of_expr (r, expr);
> }
> @@ -69,7 +69,7 @@ fur_source::get_operand (irange &r, tree expr)
> // range_query to get the range on the edge.
>
> bool
> -fur_source::get_phi_operand (irange &r, tree expr, edge e)
> +fur_source::get_phi_operand (vrange &r, tree expr, edge e)
> {
> return m_query->range_on_edge (r, e, expr);
> }
> @@ -109,8 +109,8 @@ class fur_edge : public fur_source
> {
> public:
> fur_edge (edge e, range_query *q = NULL);
> - virtual bool get_operand (irange &r, tree expr) override;
> - virtual bool get_phi_operand (irange &r, tree expr, edge e) override;
> + virtual bool get_operand (vrange &r, tree expr) override;
> + virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
> private:
> edge m_edge;
> };
> @@ -126,7 +126,7 @@ fur_edge::fur_edge (edge e, range_query *q) : fur_source (q)
> // Get the value of EXPR on edge m_edge.
>
> bool
> -fur_edge::get_operand (irange &r, tree expr)
> +fur_edge::get_operand (vrange &r, tree expr)
> {
> return m_query->range_on_edge (r, m_edge, expr);
> }
> @@ -135,7 +135,7 @@ fur_edge::get_operand (irange &r, tree expr)
> // range_query to get the range on the edge.
>
> bool
> -fur_edge::get_phi_operand (irange &r, tree expr, edge e)
> +fur_edge::get_phi_operand (vrange &r, tree expr, edge e)
> {
> // Edge to edge recalculations not supoprted yet, until we sort it out.
> gcc_checking_assert (e == m_edge);
> @@ -152,7 +152,7 @@ fur_stmt::fur_stmt (gimple *s, range_query *q) : fur_source (q)
> // Retreive range of EXPR as it occurs as a use on stmt M_STMT.
>
> bool
> -fur_stmt::get_operand (irange &r, tree expr)
> +fur_stmt::get_operand (vrange &r, tree expr)
> {
> return m_query->range_of_expr (r, expr, m_stmt);
> }
> @@ -161,7 +161,7 @@ fur_stmt::get_operand (irange &r, tree expr)
> // range_query to get the range on the edge.
>
> bool
> -fur_stmt::get_phi_operand (irange &r, tree expr, edge e)
> +fur_stmt::get_phi_operand (vrange &r, tree expr, edge e)
> {
> // Pick up the range of expr from edge E.
> fur_edge e_src (e, m_query);
> @@ -214,42 +214,42 @@ fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
> class fur_list : public fur_source
> {
> public:
> - fur_list (irange &r1);
> - fur_list (irange &r1, irange &r2);
> - fur_list (unsigned num, irange *list);
> - virtual bool get_operand (irange &r, tree expr) override;
> - virtual bool get_phi_operand (irange &r, tree expr, edge e) override;
> + fur_list (vrange &r1);
> + fur_list (vrange &r1, vrange &r2);
> + fur_list (unsigned num, vrange **list);
> + virtual bool get_operand (vrange &r, tree expr) override;
> + virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
> private:
> - int_range_max m_local[2];
> - irange *m_list;
> + vrange *m_local[2];
> + vrange **m_list;
> unsigned m_index;
> unsigned m_limit;
> };
>
> // One range supplied for unary operations.
>
> -fur_list::fur_list (irange &r1) : fur_source (NULL)
> +fur_list::fur_list (vrange &r1) : fur_source (NULL)
> {
> m_list = m_local;
> m_index = 0;
> m_limit = 1;
> - m_local[0] = r1;
> + m_local[0] = &r1;
> }
>
> // Two ranges supplied for binary operations.
>
> -fur_list::fur_list (irange &r1, irange &r2) : fur_source (NULL)
> +fur_list::fur_list (vrange &r1, vrange &r2) : fur_source (NULL)
> {
> m_list = m_local;
> m_index = 0;
> m_limit = 2;
> - m_local[0] = r1;
> - m_local[1] = r2;
> + m_local[0] = &r1;
> + m_local[1] = &r2;
> }
>
> // Arbitrary number of ranges in a vector.
>
> -fur_list::fur_list (unsigned num, irange *list) : fur_source (NULL)
> +fur_list::fur_list (unsigned num, vrange **list) : fur_source (NULL)
> {
> m_list = list;
> m_index = 0;
> @@ -259,18 +259,18 @@ fur_list::fur_list (unsigned num, irange *list) : fur_source (NULL)
> // Get the next operand from the vector, ensure types are compatible.
>
> bool
> -fur_list::get_operand (irange &r, tree expr)
> +fur_list::get_operand (vrange &r, tree expr)
> {
> if (m_index >= m_limit)
> return m_query->range_of_expr (r, expr);
> - r = m_list[m_index++];
> + r = *m_list[m_index++];
> gcc_checking_assert (range_compatible_p (TREE_TYPE (expr), r.type ()));
> return true;
> }
>
> // This will simply pick the next operand from the vector.
> bool
> -fur_list::get_phi_operand (irange &r, tree expr, edge e ATTRIBUTE_UNUSED)
> +fur_list::get_phi_operand (vrange &r, tree expr, edge e ATTRIBUTE_UNUSED)
> {
> return get_operand (r, expr);
> }
> @@ -278,7 +278,7 @@ fur_list::get_phi_operand (irange &r, tree expr, edge e ATTRIBUTE_UNUSED)
> // Fold stmt S into range R using R1 as the first operand.
>
> bool
> -fold_range (irange &r, gimple *s, irange &r1)
> +fold_range (vrange &r, gimple *s, vrange &r1)
> {
> fold_using_range f;
> fur_list src (r1);
> @@ -288,7 +288,7 @@ fold_range (irange &r, gimple *s, irange &r1)
> // Fold stmt S into range R using R1 and R2 as the first two operands.
>
> bool
> -fold_range (irange &r, gimple *s, irange &r1, irange &r2)
> +fold_range (vrange &r, gimple *s, vrange &r1, vrange &r2)
> {
> fold_using_range f;
> fur_list src (r1, r2);
> @@ -299,7 +299,7 @@ fold_range (irange &r, gimple *s, irange &r1, irange &r2)
> // operands encountered.
>
> bool
> -fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector)
> +fold_range (vrange &r, gimple *s, unsigned num_elements, vrange **vector)
> {
> fold_using_range f;
> fur_list src (num_elements, vector);
> @@ -309,7 +309,7 @@ fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector)
> // Fold stmt S into range R using range query Q.
>
> bool
> -fold_range (irange &r, gimple *s, range_query *q)
> +fold_range (vrange &r, gimple *s, range_query *q)
> {
> fold_using_range f;
> fur_stmt src (s, q);
> @@ -319,7 +319,7 @@ fold_range (irange &r, gimple *s, range_query *q)
> // Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE.
>
> bool
> -fold_range (irange &r, gimple *s, edge on_edge, range_query *q)
> +fold_range (vrange &r, gimple *s, edge on_edge, range_query *q)
> {
> fold_using_range f;
> fur_edge src (on_edge, q);
> @@ -370,7 +370,7 @@ adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt)
> // Adjust the range for an IMAGPART_EXPR.
>
> static void
> -adjust_imagpart_expr (irange &res, const gimple *stmt)
> +adjust_imagpart_expr (vrange &res, const gimple *stmt)
> {
> tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
>
> @@ -413,7 +413,7 @@ adjust_imagpart_expr (irange &res, const gimple *stmt)
> // Adjust the range for a REALPART_EXPR.
>
> static void
> -adjust_realpart_expr (irange &res, const gimple *stmt)
> +adjust_realpart_expr (vrange &res, const gimple *stmt)
> {
> tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
>
> @@ -442,12 +442,12 @@ adjust_realpart_expr (irange &res, const gimple *stmt)
> // this statement.
>
> static void
> -gimple_range_adjustment (irange &res, const gimple *stmt)
> +gimple_range_adjustment (vrange &res, const gimple *stmt)
> {
> switch (gimple_expr_code (stmt))
> {
> case POINTER_DIFF_EXPR:
> - adjust_pointer_diff_expr (res, stmt);
> + adjust_pointer_diff_expr (as_a <irange> (res), stmt);
> return;
>
> case IMAGPART_EXPR:
> @@ -536,7 +536,7 @@ gimple_range_operand2 (const gimple *stmt)
> // be calculated, return false.
>
> bool
> -fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
> +fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
> {
> bool res = false;
> // If name and S are specified, make sure it is an LHS of S.
> @@ -549,7 +549,7 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
> // Process addresses.
> if (gimple_code (s) == GIMPLE_ASSIGN
> && gimple_assign_rhs_code (s) == ADDR_EXPR)
> - return range_of_address (r, s, src);
> + return range_of_address (as_a <irange> (r), s, src);
>
> if (range_op_handler (s))
> res = range_of_range_op (r, s, src);
> @@ -566,7 +566,7 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
> if (!name || !gimple_range_ssa_p (name))
> return false;
> // We don't understand the stmt, so return the global range.
> - r = gimple_range_global (name);
> + gimple_range_global (r, name);
> return true;
> }
>
> @@ -587,9 +587,8 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
> // If a range cannot be calculated, return false.
>
> bool
> -fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
> +fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
> {
> - int_range_max range1, range2;
> tree type = gimple_range_type (s);
> if (!type)
> return false;
> @@ -599,13 +598,16 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
> tree lhs = gimple_get_lhs (s);
> tree op1 = gimple_range_operand1 (s);
> tree op2 = gimple_range_operand2 (s);
> + tmp_range range1 (TREE_TYPE (op1));
> + tmp_range range2;
>
> if (src.get_operand (range1, op1))
> {
> if (!op2)
> {
> // Fold range, and register any dependency if available.
> - int_range<2> r2 (type);
> + tmp_range r2 (type);
> + r2.set_varying (type);
> handler.fold_range (r, type, range1, r2);
> if (lhs && gimple_range_ssa_p (op1))
> {
> @@ -617,7 +619,8 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
> src.register_relation (s, rel, lhs, op1);
> }
> }
> - else if (src.get_operand (range2, op2))
> + else if (range2.init (TREE_TYPE (op2))
> + && src.get_operand (range2, op2))
> {
> relation_kind rel = src.query_relation (op1, op2);
> if (dump_file && (dump_flags & TDF_DETAILS) && rel != VREL_VARYING)
> @@ -630,7 +633,8 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
> }
> // Fold range, and register any dependency if available.
> handler.fold_range (r, type, range1, range2, rel);
> - relation_fold_and_or (r, s, src);
> + if (irange::supports_type_p (type))
> + relation_fold_and_or (as_a <irange> (r), s, src);
> if (lhs)
> {
> if (src.gori ())
> @@ -663,7 +667,8 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
> e0 = NULL;
> if (!single_pred_p (e1->dest))
> e1 = NULL;
> - src.register_outgoing_edges (as_a<gcond *> (s), r, e0, e1);
> + src.register_outgoing_edges (as_a<gcond *> (s),
> + as_a <irange> (r), e0, e1);
> }
> }
> else
> @@ -729,12 +734,12 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
> {
> /* For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
> allow going from non-NULL pointer to NULL. */
> - if (!range_includes_zero_p (&r))
> + if (r.undefined_p () || !r.contains_p (build_zero_cst (r.type ())))
> {
> /* We could here instead adjust r by off >> LOG2_BITS_PER_UNIT
> using POINTER_PLUS_EXPR if off_cst and just fall back to
> this. */
> - r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> + r.set_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> return true;
> }
> }
> @@ -746,22 +751,22 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
> && known_ne (off, 0)
> && (flag_delete_null_pointer_checks || known_gt (off, 0)))
> {
> - r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> + r.set_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> return true;
> }
> - r = int_range<2> (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> + r.set_varying (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> return true;
> }
>
> // Handle "= &a".
> if (tree_single_nonzero_warnv_p (expr, &strict_overflow_p))
> {
> - r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> + r.set_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> return true;
> }
>
> // Otherwise return varying.
> - r = int_range<2> (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> + r.set_varying (TREE_TYPE (gimple_assign_rhs1 (stmt)));
> return true;
> }
>
> @@ -769,12 +774,12 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
> // If a range cannot be calculated, return false.
>
> bool
> -fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
> +fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src)
> {
> tree phi_def = gimple_phi_result (phi);
> tree type = gimple_range_type (phi);
> - int_range_max arg_range;
> - int_range_max equiv_range;
> + tmp_range arg_range (type);
> + tmp_range equiv_range (type);
> unsigned x;
>
> if (!type)
> @@ -881,7 +886,7 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
> // If a range cannot be calculated, return false.
>
> bool
> -fold_using_range::range_of_call (irange &r, gcall *call, fur_source &src)
> +fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &src)
> {
> tree type = gimple_range_type (call);
> if (!type)
> @@ -893,18 +898,18 @@ fold_using_range::range_of_call (irange &r, gcall *call, fur_source &src)
> if (range_of_builtin_call (r, call, src))
> ;
> else if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p))
> - r.set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
> + r.set_nonnegative (type);
> else if (gimple_call_nonnull_result_p (call)
> || gimple_call_nonnull_arg (call))
> - r = range_nonzero (type);
> + r.set_nonzero (type);
> else
> r.set_varying (type);
>
> // If there is an LHS, intersect that with what is known.
> if (lhs)
> {
> - value_range def;
> - def = gimple_range_global (lhs);
> + tmp_range def (TREE_TYPE (lhs));
> + gimple_range_global (def, lhs);
> r.intersect (def);
> }
> return true;
> @@ -971,13 +976,30 @@ get_letter_range (tree type, irange &lowers, irange &uppers)
> // TRUE. Otherwise return FALSE.
>
> bool
> -fold_using_range::range_of_builtin_call (irange &r, gcall *call,
> +fold_using_range::range_of_builtin_call (vrange &r, gcall *call,
> fur_source &src)
> {
> combined_fn func = gimple_call_combined_fn (call);
> if (func == CFN_LAST)
> return false;
>
> + tree type = gimple_range_type (call);
> + gcc_checking_assert (type);
> +
> + if (irange::supports_type_p (type))
> + return range_of_builtin_int_call (as_a <irange> (r), call, src);
> +
> + return false;
> +}
> +
> +bool
> +fold_using_range::range_of_builtin_int_call (irange &r, gcall *call,
> + fur_source &src)
> +{
> + combined_fn func = gimple_call_combined_fn (call);
> + if (func == CFN_LAST)
> + return false;
> +
> tree type = gimple_range_type (call);
> tree arg;
> int mini, maxi, zerov = 0, prec;
> @@ -1256,9 +1278,8 @@ fold_using_range::range_of_builtin_call (irange &r, gcall *call,
> // If a range cannot be calculated, return false.
>
> bool
> -fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src)
> +fold_using_range::range_of_cond_expr (vrange &r, gassign *s, fur_source &src)
> {
> - int_range_max cond_range, range1, range2;
> tree cond = gimple_assign_rhs1 (s);
> tree op1 = gimple_assign_rhs2 (s);
> tree op2 = gimple_assign_rhs3 (s);
> @@ -1267,6 +1288,9 @@ fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src)
> if (!type)
> return false;
>
> + tmp_range range1 (TREE_TYPE (op1));
> + tmp_range range2 (TREE_TYPE (op2));
> + tmp_range cond_range (TREE_TYPE (cond));
> gcc_checking_assert (gimple_assign_rhs_code (s) == COND_EXPR);
> gcc_checking_assert (range_compatible_p (TREE_TYPE (op1), TREE_TYPE (op2)));
> src.get_operand (cond_range, cond);
> @@ -1438,7 +1462,6 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
> void
> fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge e1)
> {
> - int_range_max r;
> int_range<2> e0_range, e1_range;
> tree name;
> basic_block bb = gimple_bb (s);
> @@ -1505,6 +1528,7 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
> continue;
> tree ssa1 = gimple_range_ssa_p (gimple_range_operand1 (stmt));
> tree ssa2 = gimple_range_ssa_p (gimple_range_operand2 (stmt));
> + tmp_range r (TREE_TYPE (name));
> if (ssa1 && ssa2)
> {
> if (e0 && gori ()->outgoing_edge_range_p (r, e0, name, *m_query)
> diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
> index 4b5d4b6e0b8..df24280ee40 100644
> --- a/gcc/gimple-range-fold.h
> +++ b/gcc/gimple-range-fold.h
> @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
> #define GCC_GIMPLE_RANGE_FOLD_H
>
> // This file is the main include point for gimple range folding.
> -// These routines will fold stmt S into the result irange R.
> +// These routines will fold stmt S into the result range R.
> // Any ssa_names on the stmt will be calculated using the range_query
> // parameter via a call to range_of_expr.
> // If no range_query is provided, current global range info will be used.
> @@ -31,15 +31,15 @@ along with GCC; see the file COPYING3. If not see
> // it appeared on that edge.
>
> // Fold stmt S into range R using range query Q.
> -bool fold_range (irange &r, gimple *s, range_query *q = NULL);
> +bool fold_range (vrange &r, gimple *s, range_query *q = NULL);
> // Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE.
> -bool fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL);
> +bool fold_range (vrange &v, gimple *s, edge on_edge, range_query *q = NULL);
>
> // These routines the operands to be specified when manually folding.
> // Any excess queries will be drawn from the current range_query.
> -bool fold_range (irange &r, gimple *s, irange &r1);
> -bool fold_range (irange &r, gimple *s, irange &r1, irange &r2);
> -bool fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector);
> +bool fold_range (vrange &r, gimple *s, vrange &r1);
> +bool fold_range (vrange &r, gimple *s, vrange &r1, vrange &r2);
> +bool fold_range (vrange &r, gimple *s, unsigned num_elements, vrange **vector);
>
> // Return the type of range which statement S calculates. If the type is
> // unsupported or no type can be determined, return NULL_TREE.
> @@ -66,7 +66,7 @@ gimple_range_type (const gimple *s)
> type = TREE_TYPE (type);
> }
> }
> - if (type && irange::supports_type_p (type))
> + if (type && vrange::supports_type_p (type))
> return type;
> return NULL_TREE;
> }
> @@ -79,7 +79,7 @@ gimple_range_ssa_p (tree exp)
> if (exp && TREE_CODE (exp) == SSA_NAME &&
> !SSA_NAME_IS_VIRTUAL_OPERAND (exp) &&
> !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) &&
> - irange::supports_type_p (TREE_TYPE (exp)))
> + vrange::supports_type_p (TREE_TYPE (exp)))
> return exp;
> return NULL_TREE;
> }
> @@ -108,8 +108,8 @@ public:
> fur_source (range_query *q = NULL);
> inline range_query *query () { return m_query; }
> inline class gori_compute *gori () { return m_gori; };
> - virtual bool get_operand (irange &r, tree expr);
> - virtual bool get_phi_operand (irange &r, tree expr, edge e);
> + virtual bool get_operand (vrange &r, tree expr);
> + virtual bool get_phi_operand (vrange &r, tree expr, edge e);
> virtual relation_kind query_relation (tree op1, tree op2);
> virtual void register_relation (gimple *stmt, relation_kind k, tree op1,
> tree op2);
> @@ -128,8 +128,8 @@ class fur_stmt : public fur_source
> {
> public:
> fur_stmt (gimple *s, range_query *q = NULL);
> - virtual bool get_operand (irange &r, tree expr) override;
> - virtual bool get_phi_operand (irange &r, tree expr, edge e) override;
> + virtual bool get_operand (vrange &r, tree expr) override;
> + virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
> virtual relation_kind query_relation (tree op1, tree op2) override;
> private:
> gimple *m_stmt;
> @@ -161,17 +161,18 @@ extern tree gimple_range_operand2 (const gimple *s);
> class fold_using_range
> {
> public:
> - bool fold_stmt (irange &r, gimple *s, class fur_source &src,
> + bool fold_stmt (vrange &r, gimple *s, class fur_source &src,
> tree name = NULL_TREE);
> protected:
> - bool range_of_range_op (irange &r, gimple *s, fur_source &src);
> - bool range_of_call (irange &r, gcall *call, fur_source &src);
> - bool range_of_cond_expr (irange &r, gassign* cond, fur_source &src);
> + bool range_of_range_op (vrange &r, gimple *s, fur_source &src);
> + bool range_of_call (vrange &r, gcall *call, fur_source &src);
> + bool range_of_cond_expr (vrange &r, gassign* cond, fur_source &src);
> bool range_of_address (irange &r, gimple *s, fur_source &src);
> - bool range_of_builtin_call (irange &r, gcall *call, fur_source &src);
> + bool range_of_builtin_call (vrange &r, gcall *call, fur_source &src);
> + bool range_of_builtin_int_call (irange &r, gcall *call, fur_source &src);
> void range_of_builtin_ubsan_call (irange &r, gcall *call, tree_code code,
> fur_source &src);
> - bool range_of_phi (irange &r, gphi *phi, fur_source &src);
> + bool range_of_phi (vrange &r, gphi *phi, fur_source &src);
> void range_of_ssa_name_with_loop_info (irange &, tree, class loop *, gphi *,
> fur_source &src);
> void relation_fold_and_or (irange& lhs_range, gimple *s, fur_source &src);
> diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
> index 0e0cf2128e7..47d0dab8cb9 100644
> --- a/gcc/gimple-range-gori.cc
> +++ b/gcc/gimple-range-gori.cc
> @@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
> // LHS_RANGE. Return false if nothing can be determined.
>
> bool
> -gimple_range_calc_op1 (irange &r, const gimple *stmt, const irange &lhs_range)
> +gimple_range_calc_op1 (vrange &r, const gimple *stmt, const vrange &lhs_range)
> {
> gcc_checking_assert (gimple_num_ops (stmt) < 3);
> // Give up on empty ranges.
> @@ -55,8 +55,8 @@ gimple_range_calc_op1 (irange &r, const gimple *stmt, const irange &lhs_range)
> // nothing can be determined.
>
> bool
> -gimple_range_calc_op1 (irange &r, const gimple *stmt,
> - const irange &lhs_range, const irange &op2_range)
> +gimple_range_calc_op1 (vrange &r, const gimple *stmt,
> + const vrange &lhs_range, const vrange &op2_range)
> {
> // Give up on empty ranges.
> if (lhs_range.undefined_p ())
> @@ -86,8 +86,8 @@ gimple_range_calc_op1 (irange &r, const gimple *stmt,
> // nothing can be determined.
>
> bool
> -gimple_range_calc_op2 (irange &r, const gimple *stmt,
> - const irange &lhs_range, const irange &op1_range)
> +gimple_range_calc_op2 (vrange &r, const gimple *stmt,
> + const vrange &lhs_range, const vrange &op1_range)
> {
> // Give up on empty ranges.
> if (lhs_range.undefined_p ())
> @@ -663,8 +663,8 @@ gori_compute::gori_compute (int not_executable_flag)
> // was not resolvable.
>
> bool
> -gori_compute::compute_operand_range_switch (irange &r, gswitch *s,
> - const irange &lhs,
> +gori_compute::compute_operand_range_switch (vrange &r, gswitch *s,
> + const vrange &lhs,
> tree name, fur_source &src)
> {
> tree op1 = gimple_switch_index (s);
> @@ -691,8 +691,8 @@ gori_compute::compute_operand_range_switch (irange &r, gswitch *s,
> // store the evaluation in R, otherwise return FALSE.
>
> bool
> -gori_compute::compute_operand_range (irange &r, gimple *stmt,
> - const irange &lhs, tree name,
> +gori_compute::compute_operand_range (vrange &r, gimple *stmt,
> + const vrange &lhs, tree name,
> fur_source &src)
> {
> // If the lhs doesn't tell us anything, neither will unwinding further.
> @@ -743,13 +743,18 @@ gori_compute::compute_operand_range (irange &r, gimple *stmt,
> print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
> }
>
> - int_range_max op1_trange, op1_frange;
> - int_range_max op2_trange, op2_frange;
> - compute_logical_operands (op1_trange, op1_frange, stmt, lhs,
> + tree type = TREE_TYPE (name);
> + tmp_range op1_trange (type), op1_frange (type);
> + tmp_range op2_trange (type), op2_frange (type);
> + compute_logical_operands (op1_trange, op1_frange, stmt,
> + as_a <irange> (lhs),
> name, src, op1, op1_in_chain);
> - compute_logical_operands (op2_trange, op2_frange, stmt, lhs,
> + compute_logical_operands (op2_trange, op2_frange, stmt,
> + as_a <irange> (lhs),
> name, src, op2, op2_in_chain);
> - res = logical_combine (r, gimple_expr_code (stmt), lhs,
> + res = logical_combine (r,
> + gimple_expr_code (stmt),
> + as_a <irange> (lhs),
> op1_trange, op1_frange, op2_trange, op2_frange);
> if (idx)
> tracer.trailer (idx, "compute_operand", res, name, r);
> @@ -789,10 +794,10 @@ range_is_either_true_or_false (const irange &r)
> // the LHS.
>
> bool
> -gori_compute::logical_combine (irange &r, enum tree_code code,
> +gori_compute::logical_combine (vrange &r, enum tree_code code,
> const irange &lhs,
> - const irange &op1_true, const irange &op1_false,
> - const irange &op2_true, const irange &op2_false)
> + const vrange &op1_true, const vrange &op1_false,
> + const vrange &op2_true, const vrange &op2_false)
> {
> if (op1_true.varying_p () && op1_false.varying_p ()
> && op2_true.varying_p () && op2_false.varying_p ())
> @@ -868,7 +873,7 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
> if (!range_is_either_true_or_false (lhs))
> {
> bool res;
> - int_range_max r1;
> + tmp_range r1 (r);
> if (logical_combine (r1, code, m_bool_zero, op1_true, op1_false,
> op2_true, op2_false)
> && logical_combine (r, code, m_bool_one, op1_true, op1_false,
> @@ -898,11 +903,11 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
> else
> {
> // The FALSE side is the union of the other 3 cases.
> - int_range_max ff (op1_false);
> + tmp_range ff (op1_false);
> ff.intersect (op2_false);
> - int_range_max tf (op1_true);
> + tmp_range tf (op1_true);
> tf.intersect (op2_false);
> - int_range_max ft (op1_false);
> + tmp_range ft (op1_false);
> ft.intersect (op2_true);
> r = ff;
> r.union_ (tf);
> @@ -925,11 +930,11 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
> {
> // The TRUE side of an OR operation will be the union of
> // the other three combinations.
> - int_range_max tt (op1_true);
> + tmp_range tt (op1_true);
> tt.intersect (op2_true);
> - int_range_max tf (op1_true);
> + tmp_range tf (op1_true);
> tf.intersect (op2_false);
> - int_range_max ft (op1_false);
> + tmp_range ft (op1_false);
> ft.intersect (op2_true);
> r = tt;
> r.union_ (tf);
> @@ -951,7 +956,7 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
> // OP_IN_CHAIN is true.
>
> void
> -gori_compute::compute_logical_operands (irange &true_range, irange &false_range,
> +gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range,
> gimple *stmt,
> const irange &lhs,
> tree name, fur_source &src,
> @@ -1007,13 +1012,15 @@ gori_compute::compute_logical_operands (irange &true_range, irange &false_range,
> // R, or false if no range could be calculated.
>
> bool
> -gori_compute::compute_operand1_range (irange &r, gimple *stmt,
> - const irange &lhs, tree name,
> +gori_compute::compute_operand1_range (vrange &r, gimple *stmt,
> + const vrange &lhs, tree name,
> fur_source &src)
> {
> - int_range_max op1_range, op2_range;
> tree op1 = gimple_range_operand1 (stmt);
> tree op2 = gimple_range_operand2 (stmt);
> + tmp_range op1_range (TREE_TYPE (op1));
> + tmp_range tmp (TREE_TYPE (op1));
> + tmp_range op2_range;
>
> // Fetch the known range for op1 in this block.
> src.get_operand (op1_range, op1);
> @@ -1021,8 +1028,9 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
> // Now range-op calcuate and put that result in r.
> if (op2)
> {
> + op2_range.init (TREE_TYPE (op2));
> src.get_operand (op2_range, op2);
> - if (!gimple_range_calc_op1 (r, stmt, lhs, op2_range))
> + if (!gimple_range_calc_op1 (tmp, stmt, lhs, op2_range))
> return false;
> }
> else
> @@ -1030,7 +1038,7 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
> // We pass op1_range to the unary operation. Nomally it's a
> // hidden range_for_type parameter, but sometimes having the
> // actual range can result in better information.
> - if (!gimple_range_calc_op1 (r, stmt, lhs, op1_range))
> + if (!gimple_range_calc_op1 (tmp, stmt, lhs, op1_range))
> return false;
> }
>
> @@ -1053,7 +1061,7 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
> tracer.print (idx, "Computes ");
> print_generic_expr (dump_file, op1, TDF_SLIM);
> fprintf (dump_file, " = ");
> - r.dump (dump_file);
> + tmp.dump (dump_file);
> fprintf (dump_file, " intersect Known range : ");
> op1_range.dump (dump_file);
> fputc ('\n', dump_file);
> @@ -1061,13 +1069,14 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
> // Intersect the calculated result with the known result and return if done.
> if (op1 == name)
> {
> - r.intersect (op1_range);
> + tmp.intersect (op1_range);
> + r = tmp;
> if (idx)
> tracer.trailer (idx, "produces ", true, name, r);
> return true;
> }
> // If the calculation continues, we're using op1_range as the new LHS.
> - op1_range.intersect (r);
> + op1_range.intersect (tmp);
>
> if (idx)
> tracer.trailer (idx, "produces ", true, op1, op1_range);
> @@ -1084,19 +1093,21 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
> // R, or false if no range could be calculated.
>
> bool
> -gori_compute::compute_operand2_range (irange &r, gimple *stmt,
> - const irange &lhs, tree name,
> +gori_compute::compute_operand2_range (vrange &r, gimple *stmt,
> + const vrange &lhs, tree name,
> fur_source &src)
> {
> - int_range_max op1_range, op2_range;
> tree op1 = gimple_range_operand1 (stmt);
> tree op2 = gimple_range_operand2 (stmt);
> + tmp_range op1_range (TREE_TYPE (op1));
> + tmp_range op2_range (TREE_TYPE (op2));
> + tmp_range tmp (TREE_TYPE (op2));
>
> src.get_operand (op1_range, op1);
> src.get_operand (op2_range, op2);
>
> // Intersect with range for op2 based on lhs and op1.
> - if (!gimple_range_calc_op2 (r, stmt, lhs, op1_range))
> + if (!gimple_range_calc_op2 (tmp, stmt, lhs, op1_range))
> return false;
>
> unsigned idx;
> @@ -1118,7 +1129,7 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt,
> tracer.print (idx, "Computes ");
> print_generic_expr (dump_file, op2, TDF_SLIM);
> fprintf (dump_file, " = ");
> - r.dump (dump_file);
> + tmp.dump (dump_file);
> fprintf (dump_file, " intersect Known range : ");
> op2_range.dump (dump_file);
> fputc ('\n', dump_file);
> @@ -1126,13 +1137,14 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt,
> // Intersect the calculated result with the known result and return if done.
> if (op2 == name)
> {
> - r.intersect (op2_range);
> + tmp.intersect (op2_range);
> + r = tmp;
> if (idx)
> tracer.trailer (idx, " produces ", true, NULL_TREE, r);
> return true;
> }
> // If the calculation continues, we're using op2_range as the new LHS.
> - op2_range.intersect (r);
> + op2_range.intersect (tmp);
>
> if (idx)
> tracer.trailer (idx, " produces ", true, op2, op2_range);
> @@ -1149,13 +1161,13 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt,
> // R, or false if no range could be calculated.
>
> bool
> -gori_compute::compute_operand1_and_operand2_range (irange &r,
> +gori_compute::compute_operand1_and_operand2_range (vrange &r,
> gimple *stmt,
> - const irange &lhs,
> + const vrange &lhs,
> tree name,
> fur_source &src)
> {
> - int_range_max op_range;
> + tmp_range op_range (TREE_TYPE (name));
>
> // Calculate a good a range for op2. Since op1 == op2, this will
> // have already included whatever the actual range of name is.
> @@ -1236,10 +1248,9 @@ gori_compute::has_edge_range_p (tree name, edge e)
> // control edge or NAME is not defined by this edge.
>
> bool
> -gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
> +gori_compute::outgoing_edge_range_p (vrange &r, edge e, tree name,
> range_query &q)
> {
> - int_range_max lhs;
> unsigned idx;
>
> if ((e->flags & m_not_executable_flag))
> @@ -1252,6 +1263,7 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
> }
>
> gcc_checking_assert (gimple_range_ssa_p (name));
> + int_range_max lhs;
> // Determine if there is an outgoing edge.
> gimple *stmt = outgoing.edge_range_p (lhs, e);
> if (!stmt)
> @@ -1312,10 +1324,9 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
> // edge and OP2 on the false edge.
>
> bool
> -gori_compute::condexpr_adjust (irange &r1, irange &r2, gimple *, tree cond,
> +gori_compute::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond,
> tree op1, tree op2, fur_source &src)
> {
> - int_range_max tmp, cond_true, cond_false;
> tree ssa1 = gimple_range_ssa_p (op1);
> tree ssa2 = gimple_range_ssa_p (op2);
> if (!ssa1 && !ssa2)
> @@ -1341,15 +1352,19 @@ gori_compute::condexpr_adjust (irange &r1, irange &r2, gimple *, tree cond,
> return false;
>
> // Pick up the current values of each part of the condition.
> - int_range_max cl, cr;
> - src.get_operand (cl, gimple_assign_rhs1 (cond_def));
> - src.get_operand (cr, gimple_assign_rhs2 (cond_def));
> + tree rhs1 = gimple_assign_rhs1 (cond_def);
> + tree rhs2 = gimple_assign_rhs2 (cond_def);
> + tmp_range cl (TREE_TYPE (rhs1));
> + tmp_range cr (TREE_TYPE (rhs2));
> + src.get_operand (cl, rhs1);
> + src.get_operand (cr, rhs2);
>
> tree cond_name = c1 ? c1 : c2;
> gimple *def_stmt = SSA_NAME_DEF_STMT (cond_name);
>
> // Evaluate the value of COND_NAME on the true and false edges, using either
> // the op1 or op2 routines based on its location.
> + tmp_range cond_true (type), cond_false (type);
> if (c1)
> {
> if (!hand.op1_range (cond_false, type, m_bool_zero, cr))
> @@ -1380,6 +1395,7 @@ gori_compute::condexpr_adjust (irange &r1, irange &r2, gimple *, tree cond,
> }
>
> // Now solve for SSA1 or SSA2 if they are in the dependency chain.
> + tmp_range tmp (type);
> if (ssa1 && in_chain_p (ssa1, cond_name))
> {
> if (compute_operand_range (tmp, def_stmt, cond_true, ssa1, src))
> diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
> index 605884e2e53..f5f691fe424 100644
> --- a/gcc/gimple-range-gori.h
> +++ b/gcc/gimple-range-gori.h
> @@ -121,7 +121,7 @@ private:
> // on *ANY* edge that has been seen. FALSE indicates that the global value
> // is applicable everywhere that has been processed.
> //
> -// outgoing_edge_range_p (irange &range, edge e, tree name)
> +// outgoing_edge_range_p (vrange &range, edge e, tree name)
> // Actually does the calculation of RANGE for name on E
> // This represents application of whatever static range effect edge E
> // may have on NAME, not any cumulative effect.
> @@ -157,8 +157,8 @@ class gori_compute : public gori_map
> {
> public:
> gori_compute (int not_executable_flag = 0);
> - bool outgoing_edge_range_p (irange &r, edge e, tree name, range_query &q);
> - bool condexpr_adjust (irange &r1, irange &r2, gimple *s, tree cond, tree op1,
> + bool outgoing_edge_range_p (vrange &r, edge e, tree name, range_query &q);
> + bool condexpr_adjust (vrange &r1, vrange &r2, gimple *s, tree cond, tree op1,
> tree op2, fur_source &src);
> bool has_edge_range_p (tree name, basic_block bb = NULL);
> bool has_edge_range_p (tree name, edge e);
> @@ -166,24 +166,24 @@ public:
> private:
> bool may_recompute_p (tree name, edge e);
> bool may_recompute_p (tree name, basic_block bb = NULL);
> - bool compute_operand_range (irange &r, gimple *stmt, const irange &lhs,
> + bool compute_operand_range (vrange &r, gimple *stmt, const vrange &lhs,
> tree name, class fur_source &src);
> - bool compute_operand_range_switch (irange &r, gswitch *s, const irange &lhs,
> + bool compute_operand_range_switch (vrange &r, gswitch *s, const vrange &lhs,
> tree name, fur_source &src);
> - bool compute_operand1_range (irange &r, gimple *stmt, const irange &lhs,
> + bool compute_operand1_range (vrange &r, gimple *stmt, const vrange &lhs,
> tree name, fur_source &src);
> - bool compute_operand2_range (irange &r, gimple *stmt, const irange &lhs,
> + bool compute_operand2_range (vrange &r, gimple *stmt, const vrange &lhs,
> tree name, fur_source &src);
> - bool compute_operand1_and_operand2_range (irange &r, gimple *stmt,
> - const irange &lhs, tree name,
> + bool compute_operand1_and_operand2_range (vrange &r, gimple *stmt,
> + const vrange &lhs, tree name,
> fur_source &src);
> - void compute_logical_operands (irange &true_range, irange &false_range,
> + void compute_logical_operands (vrange &true_range, vrange &false_range,
> gimple *stmt, const irange &lhs,
> tree name, fur_source &src, tree op,
> bool op_in_chain);
> - bool logical_combine (irange &r, enum tree_code code, const irange &lhs,
> - const irange &op1_true, const irange &op1_false,
> - const irange &op2_true, const irange &op2_false);
> + bool logical_combine (vrange &r, enum tree_code code, const irange &lhs,
> + const vrange &op1_true, const vrange &op1_false,
> + const vrange &op2_true, const vrange &op2_false);
> int_range<2> m_bool_zero; // Boolean false cached.
> int_range<2> m_bool_one; // Boolean true cached.
>
> @@ -193,14 +193,14 @@ private:
> };
>
> // These routines provide a GIMPLE interface to the range-ops code.
> -extern bool gimple_range_calc_op1 (irange &r, const gimple *s,
> - const irange &lhs_range);
> -extern bool gimple_range_calc_op1 (irange &r, const gimple *s,
> - const irange &lhs_range,
> - const irange &op2_range);
> -extern bool gimple_range_calc_op2 (irange &r, const gimple *s,
> - const irange &lhs_range,
> - const irange &op1_range);
> +extern bool gimple_range_calc_op1 (vrange &r, const gimple *s,
> + const vrange &lhs_range);
> +extern bool gimple_range_calc_op1 (vrange &r, const gimple *s,
> + const vrange &lhs_range,
> + const vrange &op2_range);
> +extern bool gimple_range_calc_op2 (vrange &r, const gimple *s,
> + const vrange &lhs_range,
> + const vrange &op1_range);
>
> // For each name that is an import into BB's exports..
> #define FOR_EACH_GORI_IMPORT_NAME(gori, bb, name) \
> diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
> index 66f433dd1d5..4819332f358 100644
> --- a/gcc/gimple-range-path.cc
> +++ b/gcc/gimple-range-path.cc
> @@ -83,7 +83,7 @@ path_range_query::clear_cache (tree name)
> // If NAME has a cache entry, return it in R, and return TRUE.
>
> inline bool
> -path_range_query::get_cache (irange &r, tree name)
> +path_range_query::get_cache (vrange &r, tree name)
> {
> if (!gimple_range_ssa_p (name))
> return get_global_range_query ()->range_of_expr (r, name);
> @@ -98,7 +98,7 @@ path_range_query::get_cache (irange &r, tree name)
> // Set the cache entry for NAME to R.
>
> void
> -path_range_query::set_cache (const irange &r, tree name)
> +path_range_query::set_cache (const vrange &r, tree name)
> {
> unsigned v = SSA_NAME_VERSION (name);
> bitmap_set_bit (m_has_cache_entry, v);
> @@ -149,7 +149,7 @@ path_range_query::defined_outside_path (tree name)
> // Return the range of NAME on entry to the path.
>
> void
> -path_range_query::range_on_path_entry (irange &r, tree name)
> +path_range_query::range_on_path_entry (vrange &r, tree name)
> {
> gcc_checking_assert (defined_outside_path (name));
> basic_block entry = entry_bb ();
> @@ -168,7 +168,7 @@ path_range_query::range_on_path_entry (irange &r, tree name)
> // block. This can happen when we're querying a block with only an
> // outgoing edge (no statement but the fall through edge), but for
> // which we can determine a range on entry to the block.
> - int_range_max tmp;
> + tmp_range tmp (TREE_TYPE (name));
> bool changed = false;
> r.set_undefined ();
> for (unsigned i = 0; i < EDGE_COUNT (entry->preds); ++i)
> @@ -190,9 +190,9 @@ path_range_query::range_on_path_entry (irange &r, tree name)
> // Return the range of NAME at the end of the path being analyzed.
>
> bool
> -path_range_query::internal_range_of_expr (irange &r, tree name, gimple *stmt)
> +path_range_query::internal_range_of_expr (vrange &r, tree name, gimple *stmt)
> {
> - if (!irange::supports_type_p (TREE_TYPE (name)))
> + if (!vrange::supports_type_p (TREE_TYPE (name)))
> return false;
>
> if (get_cache (r, name))
> @@ -209,18 +209,22 @@ path_range_query::internal_range_of_expr (irange &r, tree name, gimple *stmt)
> && range_defined_in_block (r, name, gimple_bb (stmt)))
> {
> if (TREE_CODE (name) == SSA_NAME)
> - r.intersect (gimple_range_global (name));
> + {
> + tmp_range glob (TREE_TYPE (name));
> + gimple_range_global (glob, name);
> + r.intersect (glob);
> + }
>
> set_cache (r, name);
> return true;
> }
>
> - r = gimple_range_global (name);
> + gimple_range_global (r, name);
> return true;
> }
>
> bool
> -path_range_query::range_of_expr (irange &r, tree name, gimple *stmt)
> +path_range_query::range_of_expr (vrange &r, tree name, gimple *stmt)
> {
> if (internal_range_of_expr (r, name, stmt))
> {
> @@ -269,7 +273,7 @@ path_range_query::ssa_defined_in_bb (tree name, basic_block bb)
> // calculating the PHI's range must not trigger additional lookups.
>
> void
> -path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
> +path_range_query::ssa_range_in_phi (vrange &r, gphi *phi)
> {
> tree name = gimple_phi_result (phi);
> basic_block bb = gimple_bb (phi);
> @@ -283,7 +287,7 @@ path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
> // Try to fold the phi exclusively with global or cached values.
> // This will get things like PHI <5(99), 6(88)>. We do this by
> // calling range_of_expr with no context.
> - int_range_max arg_range;
> + tmp_range arg_range (TREE_TYPE (name));
> r.set_undefined ();
> for (size_t i = 0; i < nargs; ++i)
> {
> @@ -312,7 +316,7 @@ path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
> {
> if (m_resolve)
> {
> - int_range_max tmp;
> + tmp_range tmp (TREE_TYPE (name));
> // Using both the range on entry to the path, and the
> // range on this edge yields significantly better
> // results.
> @@ -335,7 +339,7 @@ path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
> // TRUE. Otherwise, return FALSE.
>
> bool
> -path_range_query::range_defined_in_block (irange &r, tree name, basic_block bb)
> +path_range_query::range_defined_in_block (vrange &r, tree name, basic_block bb)
> {
> gimple *def_stmt = SSA_NAME_DEF_STMT (name);
> basic_block def_bb = gimple_bb (def_stmt);
> @@ -377,7 +381,6 @@ path_range_query::range_defined_in_block (irange &r, tree name, basic_block bb)
> void
> path_range_query::compute_ranges_in_phis (basic_block bb)
> {
> - int_range_max r;
> auto_bitmap phi_set;
>
> // PHIs must be resolved simultaneously on entry to the block
> @@ -390,7 +393,11 @@ path_range_query::compute_ranges_in_phis (basic_block bb)
> gphi *phi = iter.phi ();
> tree name = gimple_phi_result (phi);
>
> - if (import_p (name) && range_defined_in_block (r, name, bb))
> + if (!import_p (name))
> + continue;
> +
> + tmp_range r (TREE_TYPE (name));
> + if (range_defined_in_block (r, name, bb))
> {
> unsigned v = SSA_NAME_VERSION (name);
> set_cache (r, name);
> @@ -423,7 +430,6 @@ void
> path_range_query::compute_ranges_in_block (basic_block bb)
> {
> bitmap_iterator bi;
> - int_range_max r, cached_range;
> unsigned i;
>
> if (m_resolve && !at_entry ())
> @@ -444,6 +450,7 @@ path_range_query::compute_ranges_in_block (basic_block bb)
> EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
> {
> tree name = ssa_name (i);
> + tmp_range r (TREE_TYPE (name));
>
> if (gimple_code (SSA_NAME_DEF_STMT (name)) != GIMPLE_PHI
> && range_defined_in_block (r, name, bb))
> @@ -480,8 +487,10 @@ path_range_query::compute_ranges_in_block (basic_block bb)
>
> if (bitmap_bit_p (exports, i))
> {
> + tmp_range r (TREE_TYPE (name));
> if (g.outgoing_edge_range_p (r, e, name, *this))
> {
> + tmp_range cached_range (TREE_TYPE (name));
> if (get_cache (cached_range, name))
> r.intersect (cached_range);
>
> @@ -539,7 +548,7 @@ bool
> path_range_query::add_to_imports (tree name, bitmap imports)
> {
> if (TREE_CODE (name) == SSA_NAME
> - && irange::supports_type_p (TREE_TYPE (name)))
> + && vrange::supports_type_p (TREE_TYPE (name)))
> return bitmap_set_bit (imports, SSA_NAME_VERSION (name));
> return false;
> }
> @@ -751,11 +760,11 @@ jt_fur_source::query_relation (tree op1, tree op2)
> // Return the range of STMT at the end of the path being analyzed.
>
> bool
> -path_range_query::range_of_stmt (irange &r, gimple *stmt, tree)
> +path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree)
> {
> tree type = gimple_range_type (stmt);
>
> - if (!type || !irange::supports_type_p (type))
> + if (!type || !vrange::supports_type_p (type))
> return false;
>
> // If resolving unknowns, fold the statement making use of any
> diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h
> index 914983bb0aa..2c4624e4cef 100644
> --- a/gcc/gimple-range-path.h
> +++ b/gcc/gimple-range-path.h
> @@ -38,29 +38,29 @@ public:
> const bitmap_head *imports = NULL);
> void compute_ranges (edge e);
> void compute_imports (bitmap imports, basic_block exit);
> - bool range_of_expr (irange &r, tree name, gimple * = NULL) override;
> - bool range_of_stmt (irange &r, gimple *, tree name = NULL) override;
> + bool range_of_expr (vrange &r, tree name, gimple * = NULL) override;
> + bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override;
> bool unreachable_path_p ();
> void dump (FILE *) override;
> void debug ();
>
> private:
> - bool internal_range_of_expr (irange &r, tree name, gimple *);
> + bool internal_range_of_expr (vrange &r, tree name, gimple *);
> bool defined_outside_path (tree name);
> - void range_on_path_entry (irange &r, tree name);
> + void range_on_path_entry (vrange &r, tree name);
> path_oracle *get_path_oracle () { return (path_oracle *)m_oracle; }
>
> // Cache manipulation.
> - void set_cache (const irange &r, tree name);
> - bool get_cache (irange &r, tree name);
> + void set_cache (const vrange &r, tree name);
> + bool get_cache (vrange &r, tree name);
> void clear_cache (tree name);
>
> // Methods to compute ranges for the given path.
> - bool range_defined_in_block (irange &, tree name, basic_block bb);
> + bool range_defined_in_block (vrange &, tree name, basic_block bb);
> void compute_ranges_in_block (basic_block bb);
> void compute_ranges_in_phis (basic_block bb);
> void adjust_for_non_null_uses (basic_block bb);
> - void ssa_range_in_phi (irange &r, gphi *phi);
> + void ssa_range_in_phi (vrange &r, gphi *phi);
> void compute_outgoing_relations (basic_block bb, basic_block next);
> void compute_phi_relations (basic_block bb, basic_block prev);
> void maybe_register_phi_relation (gphi *, edge e);
> diff --git a/gcc/gimple-range-side-effect.cc b/gcc/gimple-range-side-effect.cc
> index 8d2ac35bc8d..aae087b7227 100644
> --- a/gcc/gimple-range-side-effect.cc
> +++ b/gcc/gimple-range-side-effect.cc
> @@ -58,7 +58,7 @@ non_null_loadstore (gimple *, tree op, tree, void *data)
> // Add NAME and RANGE to the the side effect summary.
>
> void
> -stmt_side_effects::add_range (tree name, irange &range)
> +stmt_side_effects::add_range (tree name, vrange &range)
> {
> m_names[num_args] = name;
> m_ranges[num_args] = range;
> @@ -126,7 +126,7 @@ class exit_range
> {
> public:
> tree name;
> - irange *range;
> + vrange *range;
> exit_range *next;
> };
>
> @@ -181,7 +181,7 @@ side_effect_manager::~side_effect_manager ()
> // Return a non-zero range value of the appropriate type for NAME from
> // the cache, creating it if necessary.
>
> -const irange&
> +const vrange&
> side_effect_manager::get_nonzero (tree name)
> {
> unsigned v = SSA_NAME_VERSION (name);
> @@ -189,10 +189,8 @@ side_effect_manager::get_nonzero (tree name)
> m_nonzero.safe_grow_cleared (num_ssa_names + 20);
> if (!m_nonzero[v])
> {
> - tree type = TREE_TYPE (name);
> - m_nonzero[v]
> - = static_cast <irange *> (m_range_allocator.alloc_vrange (type));
> - m_nonzero[v]->set_nonzero (type);
> + m_nonzero[v] = m_range_allocator.alloc_vrange (TREE_TYPE (name));
> + m_nonzero[v]->set_nonzero (TREE_TYPE (name));
> }
> return *(m_nonzero[v]);
> }
> @@ -219,7 +217,7 @@ side_effect_manager::has_range_p (tree name, basic_block bb)
> // to include it.
>
> bool
> -side_effect_manager::maybe_adjust_range (irange &r, tree name, basic_block bb)
> +side_effect_manager::maybe_adjust_range (vrange &r, tree name, basic_block bb)
> {
> if (!has_range_p (name, bb))
> return false;
> @@ -232,7 +230,7 @@ side_effect_manager::maybe_adjust_range (irange &r, tree name, basic_block bb)
> // Add range R as a side effect for NAME in block BB.
>
> void
> -side_effect_manager::add_range (tree name, basic_block bb, const irange &r)
> +side_effect_manager::add_range (tree name, basic_block bb, const vrange &r)
> {
> if (bb->index >= (int)m_on_exit.length ())
> m_on_exit.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1);
> @@ -254,7 +252,7 @@ side_effect_manager::add_range (tree name, basic_block bb, const irange &r)
> exit_range *ptr = m_on_exit[bb->index].find_ptr (name);
> if (ptr)
> {
> - int_range_max cur = r;
> + tmp_range cur (r);
> // If no new info is added, just return.
> if (!cur.intersect (*(ptr->range)))
> return;
> @@ -263,7 +261,7 @@ side_effect_manager::add_range (tree name, basic_block bb, const irange &r)
> else
> {
> vrange &v = cur;
> - ptr->range = static_cast <irange *> (m_range_allocator.clone (v));
> + ptr->range = m_range_allocator.clone (v);
> }
> return;
> }
> diff --git a/gcc/gimple-range-side-effect.h b/gcc/gimple-range-side-effect.h
> index d76d6eb34f2..a7625646ed1 100644
> --- a/gcc/gimple-range-side-effect.h
> +++ b/gcc/gimple-range-side-effect.h
> @@ -33,15 +33,15 @@ public:
> inline unsigned num () const { return num_args; }
> inline tree name (unsigned index) const
> { gcc_checking_assert (index < num_args); return m_names[index]; }
> - inline const irange& range (unsigned index) const
> + inline const vrange& range (unsigned index) const
> { gcc_checking_assert (index < num_args); return m_ranges[index]; }
> - void add_range (tree name, irange &range);
> + void add_range (tree name, vrange &range);
> void add_nonzero (tree name);
> private:
> unsigned num_args;
> static const int size_limit = 10;
> tree m_names[size_limit];
> - int_range<3> m_ranges[size_limit];
> + tmp_range m_ranges[size_limit];
> inline void bump_index () { if (num_args < size_limit - 1) num_args++; }
> };
>
> @@ -56,10 +56,10 @@ class side_effect_manager
> public:
> side_effect_manager (bool do_search);
> ~side_effect_manager ();
> - void add_range (tree name, basic_block bb, const irange &r);
> + void add_range (tree name, basic_block bb, const vrange &r);
> void add_nonzero (tree name, basic_block bb);
> bool has_range_p (tree name, basic_block bb);
> - bool maybe_adjust_range (irange &r, tree name, basic_block bb);
> + bool maybe_adjust_range (vrange &r, tree name, basic_block bb);
> private:
> class exit_range_head
> {
> @@ -71,8 +71,8 @@ private:
> };
> void register_all_uses (tree name);
> vec <exit_range_head> m_on_exit;
> - const irange &get_nonzero (tree name);
> - vec <irange *> m_nonzero;
> + const vrange &get_nonzero (tree name);
> + vec <vrange *> m_nonzero;
> bitmap m_seen;
> bitmap_obstack m_bitmaps;
> struct obstack m_list_obstack;
> diff --git a/gcc/gimple-range-tests.cc b/gcc/gimple-range-tests.cc
> index 572acd33d7f..84ecc486889 100644
> --- a/gcc/gimple-range-tests.cc
> +++ b/gcc/gimple-range-tests.cc
> @@ -42,8 +42,9 @@ public:
> ASSERT_TRUE (r == expect);
> }
>
> - virtual bool range_of_expr (irange &r, tree expr, gimple * = NULL) override
> + virtual bool range_of_expr (vrange &v, tree expr, gimple * = NULL) override
> {
> + irange &r = as_a <irange> (v);
> if (expr == op0)
> {
> r.set (build_int_cst (type, 5), build_int_cst (type, 10));
> diff --git a/gcc/gimple-range-trace.cc b/gcc/gimple-range-trace.cc
> index 39971093e6d..37cf37ca885 100644
> --- a/gcc/gimple-range-trace.cc
> +++ b/gcc/gimple-range-trace.cc
> @@ -102,7 +102,7 @@ range_tracer::print (unsigned counter, const char *str)
>
> void
> range_tracer::trailer (unsigned counter, const char *caller, bool result,
> - tree name, const irange &r)
> + tree name, const vrange &r)
> {
> gcc_checking_assert (tracing && counter != 0);
>
> @@ -141,7 +141,6 @@ debug_seed_ranger (gimple_ranger &ranger)
> }
>
> basic_block bb;
> - int_range_max r;
> gimple_stmt_iterator gsi;
> FOR_EACH_BB_FN (bb, cfun)
> for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
> @@ -151,7 +150,11 @@ debug_seed_ranger (gimple_ranger &ranger)
> if (is_gimple_debug (stmt))
> continue;
>
> - ranger.range_of_stmt (r, stmt);
> + if (tree type = gimple_range_type (stmt))
> + {
> + tmp_range r (type);
> + ranger.range_of_stmt (r, stmt);
> + }
> }
> }
>
> diff --git a/gcc/gimple-range-trace.h b/gcc/gimple-range-trace.h
> index 302afda3104..3f92e51803b 100644
> --- a/gcc/gimple-range-trace.h
> +++ b/gcc/gimple-range-trace.h
> @@ -32,7 +32,7 @@ public:
> range_tracer (const char *name = "");
> unsigned header (const char *str);
> void trailer (unsigned counter, const char *caller, bool result, tree name,
> - const irange &r);
> + const vrange &r);
> void print (unsigned counter, const char *str);
> inline void enable_trace () { tracing = true; }
> inline void disable_trace () { tracing = false; }
> diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
> index 32d57c9e3db..1118feb41a5 100644
> --- a/gcc/gimple-range.cc
> +++ b/gcc/gimple-range.cc
> @@ -71,7 +71,7 @@ gimple_ranger::~gimple_ranger ()
> }
>
> bool
> -gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
> +gimple_ranger::range_of_expr (vrange &r, tree expr, gimple *stmt)
> {
> unsigned idx;
> if (!gimple_range_ssa_p (expr))
> @@ -93,7 +93,7 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
> // If there is no statement, just get the global value.
> if (!stmt)
> {
> - int_range_max tmp;
> + tmp_range tmp (TREE_TYPE (expr));
> m_cache.get_global_range (r, expr);
> // Pick up implied context information from the on-entry cache
> // if current_bb is set. Do not attempt any new calculations.
> @@ -137,9 +137,9 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
> // Return the range of NAME on entry to block BB in R.
>
> void
> -gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name)
> +gimple_ranger::range_on_entry (vrange &r, basic_block bb, tree name)
> {
> - int_range_max entry_range;
> + tmp_range entry_range (TREE_TYPE (name));
> gcc_checking_assert (gimple_range_ssa_p (name));
>
> unsigned idx;
> @@ -164,7 +164,7 @@ gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name)
> // Return false if no range can be calculated.
>
> void
> -gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name)
> +gimple_ranger::range_on_exit (vrange &r, basic_block bb, tree name)
> {
> // on-exit from the exit block?
> gcc_checking_assert (bb != EXIT_BLOCK_PTR_FOR_FN (cfun));
> @@ -198,10 +198,10 @@ gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name)
> // Calculate a range for NAME on edge E and return it in R.
>
> bool
> -gimple_ranger::range_on_edge (irange &r, edge e, tree name)
> +gimple_ranger::range_on_edge (vrange &r, edge e, tree name)
> {
> - int_range_max edge_range;
> - gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
> + tmp_range edge_range (TREE_TYPE (name));
> + gcc_checking_assert (vrange::supports_type_p (TREE_TYPE (name)));
>
> // Do not process values along abnormal edges.
> if (e->flags & EDGE_ABNORMAL)
> @@ -249,7 +249,7 @@ gimple_ranger::range_on_edge (irange &r, edge e, tree name)
> // fold_range wrapper for range_of_stmt to use as an internal client.
>
> bool
> -gimple_ranger::fold_range_internal (irange &r, gimple *s, tree name)
> +gimple_ranger::fold_range_internal (vrange &r, gimple *s, tree name)
> {
> fold_using_range f;
> fur_depend src (s, &(gori ()), this);
> @@ -263,7 +263,7 @@ gimple_ranger::fold_range_internal (irange &r, gimple *s, tree name)
> // avoided. If a range cannot be calculated, return false and UNDEFINED.
>
> bool
> -gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
> +gimple_ranger::range_of_stmt (vrange &r, gimple *s, tree name)
> {
> bool res;
> r.set_undefined ();
> @@ -313,7 +313,7 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
> prefill_stmt_dependencies (name);
>
> // Calculate a new value.
> - int_range_max tmp;
> + tmp_range tmp (TREE_TYPE (name));
> fold_range_internal (tmp, s, name);
>
> // Combine the new value with the old value. This is required because
> @@ -334,7 +334,7 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
> // stack if so. R is a scratch range.
>
> inline void
> -gimple_ranger::prefill_name (irange &r, tree name)
> +gimple_ranger::prefill_name (tmp_range &r, tree name)
> {
> if (!gimple_range_ssa_p (name))
> return;
> @@ -343,6 +343,7 @@ gimple_ranger::prefill_name (irange &r, tree name)
> return;
>
> bool current;
> + r.init (TREE_TYPE (name));
> // If this op has not been processed yet, then push it on the stack
> if (!m_cache.get_global_range (r, name, current))
> m_stmt_list.safe_push (name);
> @@ -357,7 +358,7 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
> if (SSA_NAME_IS_DEFAULT_DEF (ssa))
> return;
>
> - int_range_max r;
> + tmp_range r;
> unsigned idx;
> gimple *stmt = SSA_NAME_DEF_STMT (ssa);
> gcc_checking_assert (stmt && gimple_bb (stmt));
> @@ -388,6 +389,7 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
> {
> // Fold and save the value for NAME.
> stmt = SSA_NAME_DEF_STMT (name);
> + r.init (TREE_TYPE (name));
> fold_range_internal (r, stmt, name);
> // Make sure we don't lose any current global info.
> int_range_max tmp;
> @@ -488,10 +490,11 @@ gimple_ranger::export_global_ranges ()
> bool print_header = true;
> for (unsigned x = 1; x < num_ssa_names; x++)
> {
> - int_range_max r;
> + tmp_range r;
> tree name = ssa_name (x);
> if (name && !SSA_NAME_IN_FREE_LIST (name)
> && gimple_range_ssa_p (name)
> + && r.init (TREE_TYPE (name))
> && m_cache.get_global_range (r, name)
> && !r.varying_p())
> {
> @@ -508,13 +511,17 @@ gimple_ranger::export_global_ranges ()
> print_header = false;
> }
>
> - value_range vr = r;
> + if (!irange::supports_type_p (TREE_TYPE (name)))
> + continue;
> +
> + vrange &v = r;
> + value_range vr = as_a <irange> (v);
> print_generic_expr (dump_file, name , TDF_SLIM);
> fprintf (dump_file, " : ");
> vr.dump (dump_file);
> fprintf (dump_file, "\n");
> int_range_max same = vr;
> - if (same != r)
> + if (same != as_a <irange> (v))
> {
> fprintf (dump_file, " irange : ");
> r.dump (dump_file);
> @@ -532,7 +539,7 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb)
> unsigned x;
> edge_iterator ei;
> edge e;
> - int_range_max range, tmp_range;
> + tmp_range range, tmp_range;
> fprintf (f, "\n=========== BB %d ============\n", bb->index);
> m_cache.dump_bb (f, bb);
>
> @@ -543,6 +550,7 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb)
> {
> tree name = ssa_name (x);
> if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) &&
> + range.init (TREE_TYPE (name)) &&
> gimple_bb (SSA_NAME_DEF_STMT (name)) == bb &&
> m_cache.get_global_range (range, name))
> {
> @@ -564,9 +572,11 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb)
> {
> tree name = gimple_range_ssa_p (ssa_name (x));
> if (name && gori ().has_edge_range_p (name, e)
> + && range.init (TREE_TYPE (name))
> && m_cache.range_on_edge (range, e, name))
> {
> gimple *s = SSA_NAME_DEF_STMT (name);
> + tmp_range.init (TREE_TYPE (name));
> // Only print the range if this is the def block, or
> // the on entry cache for either end of the edge is
> // set.
> diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
> index 13d4c77883e..ca5a33e65c6 100644
> --- a/gcc/gimple-range.h
> +++ b/gcc/gimple-range.h
> @@ -48,11 +48,11 @@ class gimple_ranger : public range_query
> public:
> gimple_ranger (bool use_imm_uses = true);
> ~gimple_ranger ();
> - virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL) override;
> - virtual bool range_of_expr (irange &r, tree name, gimple * = NULL) override;
> - virtual bool range_on_edge (irange &r, edge e, tree name) override;
> - void range_on_entry (irange &r, basic_block bb, tree name);
> - void range_on_exit (irange &r, basic_block bb, tree name);
> + virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override;
> + virtual bool range_of_expr (vrange &r, tree name, gimple * = NULL) override;
> + virtual bool range_on_edge (vrange &r, edge e, tree name) override;
> + void range_on_entry (vrange &r, basic_block bb, tree name);
> + void range_on_exit (vrange &r, basic_block bb, tree name);
> void export_global_ranges ();
> inline gori_compute &gori () { return m_cache.m_gori; }
> virtual void dump (FILE *f) override;
> @@ -62,8 +62,8 @@ public:
> bool fold_stmt (gimple_stmt_iterator *gsi, tree (*) (tree));
> void register_side_effects (gimple *s);
> protected:
> - bool fold_range_internal (irange &r, gimple *s, tree name);
> - void prefill_name (irange &r, tree name);
> + bool fold_range_internal (vrange &r, gimple *s, tree name);
> + void prefill_name (tmp_range &r, tree name);
> void prefill_stmt_dependencies (tree ssa);
> ranger_cache m_cache;
> range_tracer tracer;
> diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
> index 9357a4e576a..132d82a5240 100644
> --- a/gcc/gimple-ssa-warn-access.cc
> +++ b/gcc/gimple-ssa-warn-access.cc
> @@ -328,11 +328,11 @@ check_nul_terminated_array (GimpleOrTree expr, tree src, tree bound)
> wide_int bndrng[2];
> if (bound)
> {
> - value_range r;
> + tmp_range r (TREE_TYPE (bound));
>
> get_global_range_query ()->range_of_expr (r, bound);
>
> - if (r.kind () != VR_RANGE)
> + if (r.undefined_p () || r.varying_p ())
> return true;
>
> bndrng[0] = r.lower_bound ();
> @@ -2790,9 +2790,8 @@ memmodel_to_uhwi (tree ord, gimple *stmt, unsigned HOST_WIDE_INT *cstval)
> {
> /* Use the range query to determine constant values in the absence
> of constant propagation (such as at -O0). */
> - value_range rng;
> + tmp_range rng (TREE_TYPE (ord));
> if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt)
> - || !rng.constant_p ()
> || !rng.singleton_p (&ord))
> return false;
>
> diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
> index afa51064953..8907e310c19 100644
> --- a/gcc/tree-ssa-loop-niter.cc
> +++ b/gcc/tree-ssa-loop-niter.cc
> @@ -221,7 +221,7 @@ refine_value_range_using_guard (tree type, tree var,
> get_type_static_bounds (type, mint, maxt);
> mpz_init (minc1);
> mpz_init (maxc1);
> - value_range r;
> + tmp_range r (TREE_TYPE (varc1));
> /* Setup range information for varc1. */
> if (integer_zerop (varc1))
> {
> @@ -374,7 +374,7 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
> gphi_iterator gsi;
>
> /* Either for VAR itself... */
> - value_range var_range;
> + tmp_range var_range (TREE_TYPE (var));
> get_range_query (cfun)->range_of_expr (var_range, var);
> rtype = var_range.kind ();
> if (!var_range.undefined_p ())
> @@ -385,10 +385,10 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
>
> /* Or for PHI results in loop->header where VAR is used as
> PHI argument from the loop preheader edge. */
> + tmp_range phi_range (TREE_TYPE (var));
> for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
> {
> gphi *phi = gsi.phi ();
> - value_range phi_range;
> if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var
> && get_range_query (cfun)->range_of_expr (phi_range,
> gimple_phi_result (phi))
> @@ -410,7 +410,7 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
> involved. */
> if (wi::gt_p (minv, maxv, sgn))
> {
> - value_range vr;
> + tmp_range vr (TREE_TYPE (var));
> get_range_query (cfun)->range_of_expr (vr, var);
> rtype = vr.kind ();
> if (!vr.undefined_p ())
> @@ -3650,7 +3650,7 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt,
> if (tree_int_cst_sign_bit (step))
> {
> wide_int max;
> - value_range base_range;
> + tmp_range base_range (TREE_TYPE (orig_base));
> if (get_range_query (cfun)->range_of_expr (base_range, orig_base)
> && !base_range.undefined_p ())
> max = base_range.upper_bound ();
> @@ -3672,7 +3672,7 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt,
> else
> {
> wide_int min;
> - value_range base_range;
> + tmp_range base_range (TREE_TYPE (orig_base));
> if (get_range_query (cfun)->range_of_expr (base_range, orig_base)
> && !base_range.undefined_p ())
> min = base_range.lower_bound ();
> @@ -3947,7 +3947,7 @@ infer_loop_bounds_from_signedness (class loop *loop, gimple *stmt)
>
> low = lower_bound_in_type (type, type);
> high = upper_bound_in_type (type, type);
> - value_range r;
> + tmp_range r (TREE_TYPE (def));
> get_range_query (cfun)->range_of_expr (r, def);
> if (r.kind () == VR_RANGE)
> {
> @@ -4997,7 +4997,7 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop)
> if (!def_bb || !dominated_by_p (CDI_DOMINATORS, loop->latch, def_bb))
> return false;
>
> - value_range r;
> + tmp_range r (TREE_TYPE (var));
> get_range_query (cfun)->range_of_expr (r, var);
> if (r.kind () != VR_RANGE)
> return false;
> diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
> index 4eb65ca7cac..d5e285d5d4d 100644
> --- a/gcc/tree-ssa-threadedge.cc
> +++ b/gcc/tree-ssa-threadedge.cc
> @@ -1409,19 +1409,19 @@ tree
> hybrid_jt_simplifier::simplify (gimple *stmt, gimple *, basic_block,
> jt_state *state)
> {
> - int_range_max r;
> -
> compute_ranges_from_state (stmt, state);
>
> if (gimple_code (stmt) == GIMPLE_COND
> || gimple_code (stmt) == GIMPLE_ASSIGN)
> {
> + tmp_range r (gimple_range_type (stmt));
> tree ret;
> if (m_query->range_of_stmt (r, stmt) && r.singleton_p (&ret))
> return ret;
> }
> else if (gimple_code (stmt) == GIMPLE_SWITCH)
> {
> + int_range_max r;
> gswitch *switch_stmt = dyn_cast <gswitch *> (stmt);
> tree index = gimple_switch_index (switch_stmt);
> if (m_query->range_of_expr (r, index, stmt))
> diff --git a/gcc/value-query.cc b/gcc/value-query.cc
> index 31e56eeae53..463ac179a00 100644
> --- a/gcc/value-query.cc
> +++ b/gcc/value-query.cc
> @@ -57,13 +57,13 @@ value_query::value_of_stmt (gimple *stmt, tree name)
> // range_query default methods.
>
> bool
> -range_query::range_on_edge (irange &r, edge, tree expr)
> +range_query::range_on_edge (vrange &r, edge, tree expr)
> {
> return range_of_expr (r, expr);
> }
>
> bool
> -range_query::range_of_stmt (irange &r, gimple *stmt, tree name)
> +range_query::range_of_stmt (vrange &r, gimple *stmt, tree name)
> {
> if (!name)
> name = gimple_get_lhs (stmt);
> @@ -79,11 +79,12 @@ tree
> range_query::value_of_expr (tree expr, gimple *stmt)
> {
> tree t;
> - int_range_max r;
>
> - if (!irange::supports_type_p (TREE_TYPE (expr)))
> + if (!vrange::supports_type_p (TREE_TYPE (expr)))
> return NULL_TREE;
>
> + tmp_range r (TREE_TYPE (expr));
> +
> if (range_of_expr (r, expr, stmt))
> {
> // A constant used in an unreachable block oftens returns as UNDEFINED.
> @@ -100,10 +101,10 @@ tree
> range_query::value_on_edge (edge e, tree expr)
> {
> tree t;
> - int_range_max r;
>
> - if (!irange::supports_type_p (TREE_TYPE (expr)))
> + if (!vrange::supports_type_p (TREE_TYPE (expr)))
> return NULL_TREE;
> + tmp_range r (TREE_TYPE (expr));
> if (range_on_edge (r, e, expr))
> {
> // A constant used in an unreachable block oftens returns as UNDEFINED.
> @@ -121,15 +122,15 @@ tree
> range_query::value_of_stmt (gimple *stmt, tree name)
> {
> tree t;
> - int_range_max r;
>
> if (!name)
> name = gimple_get_lhs (stmt);
>
> gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
>
> - if (!name || !irange::supports_type_p (TREE_TYPE (name)))
> + if (!name || !vrange::supports_type_p (TREE_TYPE (name)))
> return NULL_TREE;
> + tmp_range r (TREE_TYPE (name));
> if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
> return t;
> return NULL_TREE;
> @@ -187,7 +188,7 @@ range_query::~range_query ()
> // representable, and UNDEFINED/false if not.
>
> bool
> -range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
> +range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
> {
> tree type;
> if (TYPE_P (expr))
> @@ -195,7 +196,7 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
> else
> type = TREE_TYPE (expr);
>
> - if (!irange::supports_type_p (type))
> + if (!vrange::supports_type_p (type))
> {
> r.set_undefined ();
> return false;
> @@ -214,7 +215,7 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
> return true;
>
> case SSA_NAME:
> - r = gimple_range_global (expr);
> + gimple_range_global (r, expr);
> return true;
>
> case ADDR_EXPR:
> @@ -223,7 +224,7 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
> bool ov;
> if (tree_single_nonzero_warnv_p (expr, &ov))
> {
> - r = range_nonzero (type);
> + r.set_nonzero (type);
> return true;
> }
> break;
> @@ -237,7 +238,8 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
> range_op_handler op (TREE_CODE (expr), type);
> if (op)
> {
> - int_range_max r0, r1;
> + tmp_range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
> + tmp_range r1 (TREE_TYPE (TREE_OPERAND (expr, 1)));
> range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
> range_of_expr (r1, TREE_OPERAND (expr, 1), stmt);
> op.fold_range (r, type, r0, r1);
> @@ -250,11 +252,13 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
> {
> range_op_handler op (TREE_CODE (expr), type);
> tree op0_type = TREE_TYPE (TREE_OPERAND (expr, 0));
> - if (op && irange::supports_type_p (op0_type))
> + if (op && vrange::supports_type_p (op0_type))
> {
> - int_range_max r0;
> + tmp_range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
> + tmp_range r1 (type);
> + r1.set_varying (type);
> range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
> - op.fold_range (r, type, r0, int_range<1> (type));
> + op.fold_range (r, type, r0, r1);
> }
> else
> r.set_varying (type);
> @@ -311,7 +315,7 @@ get_ssa_name_ptr_info_nonnull (const_tree name)
> // updated.
>
> bool
> -update_global_range (irange &r, tree name)
> +update_global_range (vrange &r, tree name)
> {
> tree type = TREE_TYPE (name);
>
> @@ -330,8 +334,7 @@ update_global_range (irange &r, tree name)
> if (r.undefined_p ())
> return false;
>
> - value_range vr = r;
> - set_range_info (name, vr);
> + set_range_info (name, as_a <irange> (r));
> return true;
> }
> else if (POINTER_TYPE_P (type))
> @@ -349,7 +352,7 @@ update_global_range (irange &r, tree name)
> // return VARYING.
>
> static void
> -get_range_global (irange &r, tree name)
> +get_range_global (vrange &r, tree name)
> {
> tree type = TREE_TYPE (name);
>
> @@ -369,7 +372,7 @@ get_range_global (irange &r, tree name)
> r.set_nonzero (type);
> else if (INTEGRAL_TYPE_P (type))
> {
> - get_ssa_name_range_info (r, name);
> + get_ssa_name_range_info (as_a <irange> (r), name);
> if (r.undefined_p ())
> r.set_varying (type);
> }
> @@ -384,7 +387,8 @@ get_range_global (irange &r, tree name)
> }
> else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
> {
> - get_ssa_name_range_info (r, name);
> + gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
> + get_ssa_name_range_info (as_a <irange> (r), name);
> if (r.undefined_p ())
> r.set_varying (type);
> }
> @@ -414,21 +418,19 @@ get_range_global (irange &r, tree name)
> // See discussion here:
> // https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html
>
> -value_range
> -gimple_range_global (tree name)
> +void
> +gimple_range_global (vrange &r, tree name)
> {
> tree type = TREE_TYPE (name);
> - gcc_checking_assert (TREE_CODE (name) == SSA_NAME
> - && irange::supports_type_p (type));
> + gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
>
> if (SSA_NAME_IS_DEFAULT_DEF (name) || (cfun && cfun->after_inlining)
> || is_a<gphi *> (SSA_NAME_DEF_STMT (name)))
> {
> - value_range vr;
> - get_range_global (vr, name);
> - return vr;
> + get_range_global (r, name);
> + return;
> }
> - return value_range (type);
> + r.set_varying (type);
> }
>
> // ----------------------------------------------
> @@ -437,7 +439,7 @@ gimple_range_global (tree name)
> global_range_query global_ranges;
>
> bool
> -global_range_query::range_of_expr (irange &r, tree expr, gimple *stmt)
> +global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
> {
> tree type = TREE_TYPE (expr);
>
> @@ -456,15 +458,16 @@ global_range_query::range_of_expr (irange &r, tree expr, gimple *stmt)
> relation_kind
> range_query::query_relation (gimple *s, tree ssa1, tree ssa2, bool get_range)
> {
> - int_range_max tmp;
> if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME)
> return VREL_VARYING;
>
> // Ensure ssa1 and ssa2 have both been evaluated.
> if (get_range)
> {
> - range_of_expr (tmp, ssa1, s);
> - range_of_expr (tmp, ssa2, s);
> + tmp_range tmp1 (TREE_TYPE (ssa1));
> + tmp_range tmp2 (TREE_TYPE (ssa2));
> + range_of_expr (tmp1, ssa1, s);
> + range_of_expr (tmp2, ssa2, s);
> }
> return m_oracle->query_relation (gimple_bb (s), ssa1, ssa2);
> }
> @@ -477,7 +480,6 @@ relation_kind
> range_query::query_relation (edge e, tree ssa1, tree ssa2, bool get_range)
> {
> basic_block bb;
> - int_range_max tmp;
> if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME)
> return VREL_VARYING;
>
> @@ -492,6 +494,7 @@ range_query::query_relation (edge e, tree ssa1, tree ssa2, bool get_range)
> // Ensure ssa1 and ssa2 have both been evaluated.
> if (get_range)
> {
> + tmp_range tmp (TREE_TYPE (ssa1));
> range_on_edge (tmp, e, ssa1);
> range_on_edge (tmp, e, ssa2);
> }
> diff --git a/gcc/value-query.h b/gcc/value-query.h
> index cf1a1d74de3..280e47e3f6b 100644
> --- a/gcc/value-query.h
> +++ b/gcc/value-query.h
> @@ -89,9 +89,9 @@ public:
> //
> // Note that range_of_expr must always return TRUE unless ranges are
> // unsupported for EXPR's type (supports_type_p is false).
> - virtual bool range_of_expr (irange &r, tree expr, gimple * = NULL) = 0;
> - virtual bool range_on_edge (irange &r, edge, tree expr);
> - virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL);
> + virtual bool range_of_expr (vrange &r, tree expr, gimple * = NULL) = 0;
> + virtual bool range_on_edge (vrange &r, edge, tree expr);
> + virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL);
>
> // Query if there is any relation between SSA1 and SSA2.
> relation_kind query_relation (gimple *s, tree ssa1, tree ssa2,
> @@ -110,8 +110,8 @@ public:
> protected:
> class value_range_equiv *allocate_value_range_equiv ();
> void free_value_range_equiv (class value_range_equiv *);
> - bool get_tree_range (irange &r, tree expr, gimple *stmt);
> - bool get_arith_expr_range (irange &r, tree expr, gimple *stmt);
> + bool get_tree_range (vrange &v, tree expr, gimple *stmt);
> + bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt);
> relation_oracle *m_oracle;
>
> private:
> @@ -123,7 +123,7 @@ private:
> class global_range_query : public range_query
> {
> public:
> - bool range_of_expr (irange &r, tree expr, gimple * = NULL) override;
> + bool range_of_expr (vrange &r, tree expr, gimple * = NULL) override;
> };
>
> extern global_range_query global_ranges;
> @@ -143,7 +143,7 @@ get_range_query (const struct function *fun)
> return fun->x_range_query ? fun->x_range_query : &global_ranges;
> }
>
> -extern value_range gimple_range_global (tree name);
> -extern bool update_global_range (irange &r, tree name);
> +extern void gimple_range_global (vrange &v, tree name);
> +extern bool update_global_range (vrange &v, tree name);
>
> #endif // GCC_QUERY_H
> diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
> index 6f8583c8d01..9b681a46905 100644
> --- a/gcc/vr-values.cc
> +++ b/gcc/vr-values.cc
> @@ -177,7 +177,7 @@ vr_values::get_value_range (const_tree var,
> }
>
> bool
> -vr_values::range_of_expr (irange &r, tree expr, gimple *stmt)
> +vr_values::range_of_expr (vrange &r, tree expr, gimple *stmt)
> {
> if (!gimple_range_ssa_p (expr))
> return get_tree_range (r, expr, stmt);
> @@ -1640,6 +1640,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
> {
> tree init, step, chrec, tmin, tmax, type = TREE_TYPE (var);
> enum ev_direction dir;
> + tmp_range trange;
> + int_range<2> r;
>
> chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
>
> @@ -1661,11 +1663,15 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
>
> /* If INIT is an SSA with a singleton range, set INIT to said
> singleton, otherwise leave INIT alone. */
> - if (TREE_CODE (init) == SSA_NAME)
> - query->get_value_range (init, stmt)->singleton_p (&init);
> + if (TREE_CODE (init) == SSA_NAME
> + && trange.init (TREE_TYPE (init))
> + && query->range_of_expr (trange, init, stmt))
> + trange.singleton_p (&init);
> /* Likewise for step. */
> - if (TREE_CODE (step) == SSA_NAME)
> - query->get_value_range (step, stmt)->singleton_p (&step);
> + if (TREE_CODE (step) == SSA_NAME
> + && trange.init (TREE_TYPE (step))
> + && query->range_of_expr (trange, step, stmt))
> + trange.singleton_p (&step);
>
> /* If STEP is symbolic, we can't know whether INIT will be the
> minimum or maximum value in the range. Also, unless INIT is
> @@ -1699,7 +1705,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
> if (TREE_CODE (step) == INTEGER_CST
> && is_gimple_val (init)
> && (TREE_CODE (init) != SSA_NAME
> - || query->get_value_range (init, stmt)->kind () == VR_RANGE))
> + || (query->range_of_expr (r, init, stmt)
> + && r.kind () == VR_RANGE)))
> {
> widest_int nit;
>
> @@ -1724,7 +1731,7 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
> {
> value_range maxvr, vr0, vr1;
> if (TREE_CODE (init) == SSA_NAME)
> - vr0 = *(query->get_value_range (init, stmt));
> + query->range_of_expr (vr0, init, stmt);
> else if (is_gimple_min_invariant (init))
> vr0.set (init);
> else
> @@ -1737,10 +1744,10 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
> /* Likewise if the addition did. */
> if (maxvr.kind () == VR_RANGE)
> {
> - value_range initvr;
> + int_range<2> initvr;
>
> if (TREE_CODE (init) == SSA_NAME)
> - initvr = *(query->get_value_range (init, stmt));
> + query->range_of_expr (initvr, init, stmt);
> else if (is_gimple_min_invariant (init))
> initvr.set (init);
> else
> @@ -2446,7 +2453,9 @@ simplify_using_ranges::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
> fprintf (dump_file, "\t");
> print_generic_expr (dump_file, use);
> fprintf (dump_file, ": ");
> - dump_value_range (dump_file, query->get_value_range (use, stmt));
> + tmp_range r (TREE_TYPE (use));
> + query->range_of_expr (r, use, stmt);
> + r.dump (dump_file);
> }
>
> fprintf (dump_file, "\n");
> diff --git a/gcc/vr-values.h b/gcc/vr-values.h
> index 7a377cebd01..f018d0dfc4b 100644
> --- a/gcc/vr-values.h
> +++ b/gcc/vr-values.h
> @@ -109,7 +109,7 @@ class vr_values : public range_query
> vr_values (void);
> ~vr_values (void);
>
> - virtual bool range_of_expr (irange &r, tree expr, gimple *stmt) override;
> + virtual bool range_of_expr (vrange &r, tree expr, gimple *stmt) override;
> virtual tree value_of_expr (tree, gimple * = NULL) override;
> virtual tree value_on_edge (edge, tree) override;
> virtual tree value_of_stmt (gimple *, tree = NULL_TREE) override;
> --
> 2.36.1
>
[-- Attachment #2: 0005-Convert-ranger-and-clients-to-vrange.patch --]
[-- Type: text/x-patch, Size: 110765 bytes --]
From 61a1c8622a1bc65bc31d454c926428cb201e4352 Mon Sep 17 00:00:00 2001
From: Aldy Hernandez <aldyh@redhat.com>
Date: Sun, 22 May 2022 20:17:40 +0200
Subject: [PATCH] Convert ranger and clients to vrange.
Finally, the meat of the work. Convert ranger and associated clients
to vrange.
Everything's relatively mechanical given the previous patches. I did
include a minor cleanup in the edge code. There's no need to check
that the type of the switch is an integer as non-integer switches are
invalid. I verified this with an appropriately coded assert.
Tested on x86-64 & ppc64le Linux.
gcc/ChangeLog:
* gimple-range-cache.cc (ssa_block_ranges::dump): Convert to vrange.
(sbr_vector::sbr_vector): Same.
(sbr_vector::grow): Same.
(sbr_vector::set_bb_range): Same.
(sbr_vector::get_bb_range): Same.
(sbr_sparse_bitmap::sbr_sparse_bitmap): Same.
(sbr_sparse_bitmap::set_bb_range): Same.
(sbr_sparse_bitmap::get_bb_range): Same.
(block_range_cache::set_bb_range): Same.
(block_range_cache::get_bb_range): Same.
(block_range_cache::dump): Same.
(ssa_global_cache::get_global_range): Same.
(ssa_global_cache::set_global_range): Same.
(ssa_global_cache::clear): Same.
(ssa_global_cache::dump): Same.
(ranger_cache::get_global_range): Same.
(ranger_cache::set_global_range): Same.
(ranger_cache::range_of_def): Same.
(ranger_cache::entry_range): Same.
(ranger_cache::exit_range): Same.
(ranger_cache::edge_range): Same.
(ranger_cache::range_of_expr): Same.
(ranger_cache::range_on_edge): Same.
(ranger_cache::block_range): Same.
(ranger_cache::propagate_cache): Same.
(ranger_cache::fill_block_cache): Same.
(ranger_cache::range_from_dom): Same.
* gimple-range-cache.h: Same.
* gimple-range-edge.cc (gimple_outgoing_range::get_edge_range):
Same.
(gimple_outgoing_range::switch_edge_range): Same.
(gimple_outgoing_range::edge_range_p): Same.
* gimple-range-edge.h: Same.
* gimple-range-fold.cc (fur_source::get_operand): Same.
(fur_source::get_phi_operand): Same.
(fur_edge::get_operand): Same.
(fur_edge::get_phi_operand): Same.
(fur_stmt::get_operand): Same.
(fur_stmt::get_phi_operand): Same.
(fur_list::fur_list): Same.
(fur_list::get_operand): Same.
(fur_list::get_phi_operand): Same.
(fold_range): Same.
(adjust_imagpart_expr): Same.
(adjust_realpart_expr): Same.
(gimple_range_adjustment): Same.
(fold_using_range::fold_stmt): Same.
(fold_using_range::range_of_range_op): Same.
(fold_using_range::range_of_address): Same.
(fold_using_range::range_of_phi): Same.
(fold_using_range::range_of_call): Same.
(fold_using_range::range_of_builtin_call): Same.
(fold_using_range::range_of_builtin_int_call): Same.
(fold_using_range::range_of_cond_expr): Same.
(fur_source::register_outgoing_edges): Same.
* gimple-range-fold.h (fold_range): Same.
(gimple_range_type): Same.
(gimple_range_ssa_p): Same.
* gimple-range-gori.cc (gimple_range_calc_op1): Same.
(gimple_range_calc_op2): Same.
(gori_compute::compute_operand_range_switch): Same.
(gori_compute::compute_operand_range): Same.
(gori_compute::logical_combine): Same.
(gori_compute::compute_logical_operands): Same.
(gori_compute::compute_operand1_range): Same.
(gori_compute::compute_operand2_range): Same.
(gori_compute::compute_operand1_and_operand2_range): Same.
(gori_compute::outgoing_edge_range_p): Same.
(gori_compute::condexpr_adjust): Same.
* gimple-range-gori.h (gimple_range_calc_op1): Same.
(gimple_range_calc_op2): Same.
* gimple-range-path.cc (path_range_query::get_cache): Same.
(path_range_query::set_cache): Same.
(path_range_query::range_on_path_entry): Same.
(path_range_query::internal_range_of_expr): Same.
(path_range_query::range_of_expr): Same.
(path_range_query::ssa_range_in_phi): Same.
(path_range_query::range_defined_in_block): Same.
(path_range_query::compute_ranges_in_phis): Same.
(path_range_query::compute_ranges_in_block): Same.
(path_range_query::add_to_imports): Same.
(path_range_query::range_of_stmt): Same.
* gimple-range-path.h: Same.
* gimple-range-side-effect.cc (gimple_infer_range::add_range): Same.
(gimple_infer_range::~side_effect_manager): Same.
(gimple_infer_range::get_nonzero): Same.
(gimple_infer_range::maybe_adjust_range): Same.
(gimple_infer_range::add_range): Same.
* gimple-range-infer.h: Same.
* gimple-range-tests.cc: Same.
* gimple-range-trace.cc (range_tracer::trailer): Same.
(debug_seed_ranger): Same.
* gimple-range-trace.h: Same.
* gimple-range.cc (gimple_ranger::range_of_expr): Same.
(gimple_ranger::range_on_entry): Same.
(gimple_ranger::range_on_exit): Same.
(gimple_ranger::range_on_edge): Same.
(gimple_ranger::fold_range_internal): Same.
(gimple_ranger::range_of_stmt): Same.
(gimple_ranger::prefill_name): Same.
(gimple_ranger::prefill_stmt_dependencies): Same.
(gimple_ranger::export_global_ranges): Same.
(gimple_ranger::dump_bb): Same.
* gimple-range.h: Same.
* gimple-ssa-warn-access.cc (check_nul_terminated_array): Same.
(memmodel_to_uhwi): Same.
* tree-ssa-loop-niter.cc (refine_value_range_using_guard): Same.
(determine_value_range): Same.
(record_nonwrapping_iv): Same.
(infer_loop_bounds_from_signedness): Same.
(scev_var_range_cant_overflow): Same.
* tree-ssa-threadedge.cc (hybrid_jt_simplifier::simplify): Same.
* value-query.cc (range_query::range_on_edge): Same.
(range_query::range_of_stmt): Same.
(range_query::value_of_expr): Same.
(range_query::value_on_edge): Same.
(range_query::value_of_stmt): Same.
(range_query::get_tree_range): Same.
(update_global_range): Same.
(get_range_global): Same.
(gimple_range_global): Same.
(global_range_query::range_of_expr): Same.
(range_query::query_relation): Same.
* value-query.h (gimple_range_global): Same.
(update_global_range): Same.
* vr-values.cc (vr_values::range_of_expr): Same.
(bounds_of_var_in_loop): Same.
(simplify_using_ranges::vrp_visit_cond_stmt): Same.
* vr-values.h (class vr_values): Same.
* tree-ssa-loop-unswitch.cc (unswitch_predicate): Same.
---
gcc/gimple-range-cache.cc | 140 +++++++++++++++++----------------
gcc/gimple-range-cache.h | 32 ++++----
gcc/gimple-range-edge.cc | 12 +--
gcc/gimple-range-edge.h | 2 +-
gcc/gimple-range-fold.cc | 141 ++++++++++++++++++++--------------
gcc/gimple-range-fold.h | 37 ++++-----
gcc/gimple-range-gori.cc | 115 +++++++++++++++------------
gcc/gimple-range-gori.h | 42 +++++-----
gcc/gimple-range-infer.cc | 20 +++--
gcc/gimple-range-infer.h | 14 ++--
gcc/gimple-range-path.cc | 47 +++++++-----
gcc/gimple-range-path.h | 16 ++--
gcc/gimple-range-tests.cc | 3 +-
gcc/gimple-range-trace.cc | 9 ++-
gcc/gimple-range-trace.h | 2 +-
gcc/gimple-range.cc | 64 +++++++++------
gcc/gimple-range.h | 14 ++--
gcc/gimple-ssa-warn-access.cc | 7 +-
gcc/tree-ssa-loop-niter.cc | 16 ++--
gcc/tree-ssa-loop-unswitch.cc | 14 ++--
gcc/tree-ssa-threadedge.cc | 4 +-
gcc/value-query.cc | 73 +++++++++---------
gcc/value-query.h | 16 ++--
gcc/vr-values.cc | 56 +++++++++-----
gcc/vr-values.h | 2 +-
25 files changed, 492 insertions(+), 406 deletions(-)
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 25ade1300af..85eed4421f4 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -44,11 +44,14 @@ along with GCC; see the file COPYING3. If not see
class ssa_block_ranges
{
public:
- virtual bool set_bb_range (const_basic_block bb, const irange &r) = 0;
- virtual bool get_bb_range (irange &r, const_basic_block bb) = 0;
+ ssa_block_ranges (tree t) : m_type (t) { }
+ virtual bool set_bb_range (const_basic_block bb, const vrange &r) = 0;
+ virtual bool get_bb_range (vrange &r, const_basic_block bb) = 0;
virtual bool bb_range_p (const_basic_block bb) = 0;
void dump(FILE *f);
+private:
+ tree m_type;
};
// Print the list of known ranges for file F in a nice format.
@@ -57,7 +60,7 @@ void
ssa_block_ranges::dump (FILE *f)
{
basic_block bb;
- int_range_max r;
+ Value_Range r (m_type);
FOR_EACH_BB_FN (bb, cfun)
if (get_bb_range (r, bb))
@@ -77,14 +80,14 @@ class sbr_vector : public ssa_block_ranges
public:
sbr_vector (tree t, vrange_allocator *allocator);
- virtual bool set_bb_range (const_basic_block bb, const irange &r) override;
- virtual bool get_bb_range (irange &r, const_basic_block bb) override;
+ virtual bool set_bb_range (const_basic_block bb, const vrange &r) override;
+ virtual bool get_bb_range (vrange &r, const_basic_block bb) override;
virtual bool bb_range_p (const_basic_block bb) override;
protected:
- irange **m_tab; // Non growing vector.
+ vrange **m_tab; // Non growing vector.
int m_tab_size;
- int_range<2> m_varying;
- int_range<2> m_undefined;
+ vrange *m_varying;
+ vrange *m_undefined;
tree m_type;
vrange_allocator *m_range_allocator;
void grow ();
@@ -94,18 +97,21 @@ protected:
// Initialize a block cache for an ssa_name of type T.
sbr_vector::sbr_vector (tree t, vrange_allocator *allocator)
+ : ssa_block_ranges (t)
{
gcc_checking_assert (TYPE_P (t));
m_type = t;
m_range_allocator = allocator;
m_tab_size = last_basic_block_for_fn (cfun) + 1;
- m_tab = static_cast <irange **>
- (allocator->alloc (m_tab_size * sizeof (irange *)));
- memset (m_tab, 0, m_tab_size * sizeof (irange *));
+ m_tab = static_cast <vrange **>
+ (allocator->alloc (m_tab_size * sizeof (vrange *)));
+ memset (m_tab, 0, m_tab_size * sizeof (vrange *));
// Create the cached type range.
- m_varying.set_varying (t);
- m_undefined.set_undefined ();
+ m_varying = m_range_allocator->alloc_vrange (t);
+ m_undefined = m_range_allocator->alloc_vrange (t);
+ m_varying->set_varying (t);
+ m_undefined->set_undefined ();
}
// Grow the vector when the CFG has increased in size.
@@ -122,10 +128,10 @@ sbr_vector::grow ()
int new_size = inc + curr_bb_size;
// Allocate new memory, copy the old vector and clear the new space.
- irange **t = static_cast <irange **>
- (m_range_allocator->alloc (new_size * sizeof (irange *)));
- memcpy (t, m_tab, m_tab_size * sizeof (irange *));
- memset (t + m_tab_size, 0, (new_size - m_tab_size) * sizeof (irange *));
+ vrange **t = static_cast <vrange **>
+ (m_range_allocator->alloc (new_size * sizeof (vrange *)));
+ memcpy (t, m_tab, m_tab_size * sizeof (vrange *));
+ memset (t + m_tab_size, 0, (new_size - m_tab_size) * sizeof (vrange *));
m_tab = t;
m_tab_size = new_size;
@@ -134,15 +140,15 @@ sbr_vector::grow ()
// Set the range for block BB to be R.
bool
-sbr_vector::set_bb_range (const_basic_block bb, const irange &r)
+sbr_vector::set_bb_range (const_basic_block bb, const vrange &r)
{
- irange *m;
+ vrange *m;
if (bb->index >= m_tab_size)
grow ();
if (r.varying_p ())
- m = &m_varying;
+ m = m_varying;
else if (r.undefined_p ())
- m = &m_undefined;
+ m = m_undefined;
else
m = m_range_allocator->clone (r);
m_tab[bb->index] = m;
@@ -153,11 +159,11 @@ sbr_vector::set_bb_range (const_basic_block bb, const irange &r)
// there is no range.
bool
-sbr_vector::get_bb_range (irange &r, const_basic_block bb)
+sbr_vector::get_bb_range (vrange &r, const_basic_block bb)
{
if (bb->index >= m_tab_size)
return false;
- irange *m = m_tab[bb->index];
+ vrange *m = m_tab[bb->index];
if (m)
{
r = *m;
@@ -193,14 +199,14 @@ class sbr_sparse_bitmap : public ssa_block_ranges
{
public:
sbr_sparse_bitmap (tree t, vrange_allocator *allocator, bitmap_obstack *bm);
- virtual bool set_bb_range (const_basic_block bb, const irange &r) override;
- virtual bool get_bb_range (irange &r, const_basic_block bb) override;
+ virtual bool set_bb_range (const_basic_block bb, const vrange &r) override;
+ virtual bool get_bb_range (vrange &r, const_basic_block bb) override;
virtual bool bb_range_p (const_basic_block bb) override;
private:
void bitmap_set_quad (bitmap head, int quad, int quad_value);
int bitmap_get_quad (const_bitmap head, int quad);
vrange_allocator *m_range_allocator;
- irange *m_range[SBR_NUM];
+ vrange *m_range[SBR_NUM];
bitmap_head bitvec;
tree m_type;
};
@@ -209,6 +215,7 @@ private:
sbr_sparse_bitmap::sbr_sparse_bitmap (tree t, vrange_allocator *allocator,
bitmap_obstack *bm)
+ : ssa_block_ranges (t)
{
gcc_checking_assert (TYPE_P (t));
m_type = t;
@@ -216,16 +223,14 @@ sbr_sparse_bitmap::sbr_sparse_bitmap (tree t, vrange_allocator *allocator,
bitmap_tree_view (&bitvec);
m_range_allocator = allocator;
// Pre-cache varying.
- m_range[0] = static_cast <irange *> (m_range_allocator->alloc_vrange (t));
+ m_range[0] = m_range_allocator->alloc_vrange (t);
m_range[0]->set_varying (t);
// Pre-cache zero and non-zero values for pointers.
if (POINTER_TYPE_P (t))
{
- m_range[1]
- = static_cast <irange *> (m_range_allocator->alloc_vrange (t));
+ m_range[1] = m_range_allocator->alloc_vrange (t);
m_range[1]->set_nonzero (t);
- m_range[2]
- = static_cast <irange *> (m_range_allocator->alloc_vrange (t));
+ m_range[2] = m_range_allocator->alloc_vrange (t);
m_range[2]->set_zero (t);
}
else
@@ -257,7 +262,7 @@ sbr_sparse_bitmap::bitmap_get_quad (const_bitmap head, int quad)
// Set the range on entry to basic block BB to R.
bool
-sbr_sparse_bitmap::set_bb_range (const_basic_block bb, const irange &r)
+sbr_sparse_bitmap::set_bb_range (const_basic_block bb, const vrange &r)
{
if (r.undefined_p ())
{
@@ -283,7 +288,7 @@ sbr_sparse_bitmap::set_bb_range (const_basic_block bb, const irange &r)
// there is no range.
bool
-sbr_sparse_bitmap::get_bb_range (irange &r, const_basic_block bb)
+sbr_sparse_bitmap::get_bb_range (vrange &r, const_basic_block bb)
{
int value = bitmap_get_quad (&bitvec, bb->index);
@@ -333,7 +338,7 @@ block_range_cache::~block_range_cache ()
bool
block_range_cache::set_bb_range (tree name, const_basic_block bb,
- const irange &r)
+ const vrange &r)
{
unsigned v = SSA_NAME_VERSION (name);
if (v >= m_ssa_ranges.length ())
@@ -379,7 +384,7 @@ block_range_cache::query_block_ranges (tree name)
// is one.
bool
-block_range_cache::get_bb_range (irange &r, tree name, const_basic_block bb)
+block_range_cache::get_bb_range (vrange &r, tree name, const_basic_block bb)
{
ssa_block_ranges *ptr = query_block_ranges (name);
if (ptr)
@@ -423,12 +428,13 @@ void
block_range_cache::dump (FILE *f, basic_block bb, bool print_varying)
{
unsigned x;
- int_range_max r;
bool summarize_varying = false;
for (x = 1; x < m_ssa_ranges.length (); ++x)
{
if (!gimple_range_ssa_p (ssa_name (x)))
continue;
+
+ Value_Range r (TREE_TYPE (ssa_name (x)));
if (m_ssa_ranges[x] && m_ssa_ranges[x]->get_bb_range (r, bb))
{
if (!print_varying && r.varying_p ())
@@ -450,6 +456,8 @@ block_range_cache::dump (FILE *f, basic_block bb, bool print_varying)
{
if (!gimple_range_ssa_p (ssa_name (x)))
continue;
+
+ Value_Range r (TREE_TYPE (ssa_name (x)));
if (m_ssa_ranges[x] && m_ssa_ranges[x]->get_bb_range (r, bb))
{
if (r.varying_p ())
@@ -485,13 +493,13 @@ ssa_global_cache::~ssa_global_cache ()
// Return the value in R.
bool
-ssa_global_cache::get_global_range (irange &r, tree name) const
+ssa_global_cache::get_global_range (vrange &r, tree name) const
{
unsigned v = SSA_NAME_VERSION (name);
if (v >= m_tab.length ())
return false;
- irange *stow = m_tab[v];
+ vrange *stow = m_tab[v];
if (!stow)
return false;
r = *stow;
@@ -502,13 +510,13 @@ ssa_global_cache::get_global_range (irange &r, tree name) const
// Return TRUE if there was already a range set, otherwise false.
bool
-ssa_global_cache::set_global_range (tree name, const irange &r)
+ssa_global_cache::set_global_range (tree name, const vrange &r)
{
unsigned v = SSA_NAME_VERSION (name);
if (v >= m_tab.length ())
m_tab.safe_grow_cleared (num_ssa_names + 1);
- irange *m = m_tab[v];
+ vrange *m = m_tab[v];
if (m && m->fits_p (r))
*m = r;
else
@@ -533,7 +541,7 @@ void
ssa_global_cache::clear ()
{
if (m_tab.address ())
- memset (m_tab.address(), 0, m_tab.length () * sizeof (irange *));
+ memset (m_tab.address(), 0, m_tab.length () * sizeof (vrange *));
}
// Dump the contents of the global cache to F.
@@ -545,9 +553,10 @@ ssa_global_cache::dump (FILE *f)
bool print_header = true;
for (unsigned x = 1; x < num_ssa_names; x++)
{
- int_range_max r;
- if (gimple_range_ssa_p (ssa_name (x)) &&
- get_global_range (r, ssa_name (x)) && !r.varying_p ())
+ if (!gimple_range_ssa_p (ssa_name (x)))
+ continue;
+ Value_Range r (TREE_TYPE (ssa_name (x)));
+ if (get_global_range (r, ssa_name (x)) && !r.varying_p ())
{
if (print_header)
{
@@ -809,11 +818,11 @@ ranger_cache::dump_bb (FILE *f, basic_block bb)
// global range is not set, and return the legacy global value in R.
bool
-ranger_cache::get_global_range (irange &r, tree name) const
+ranger_cache::get_global_range (vrange &r, tree name) const
{
if (m_globals.get_global_range (r, name))
return true;
- r = gimple_range_global (name);
+ gimple_range_global (r, name);
return false;
}
@@ -825,7 +834,7 @@ ranger_cache::get_global_range (irange &r, tree name) const
// After this call, the global cache will have a value.
bool
-ranger_cache::get_global_range (irange &r, tree name, bool ¤t_p)
+ranger_cache::get_global_range (vrange &r, tree name, bool ¤t_p)
{
bool had_global = get_global_range (r, name);
@@ -847,7 +856,7 @@ ranger_cache::get_global_range (irange &r, tree name, bool ¤t_p)
// Set the global range of NAME to R and give it a timestamp.
void
-ranger_cache::set_global_range (tree name, const irange &r)
+ranger_cache::set_global_range (tree name, const vrange &r)
{
if (m_globals.set_global_range (name, r))
{
@@ -882,7 +891,7 @@ ranger_cache::set_global_range (tree name, const irange &r)
// get the best global value available.
void
-ranger_cache::range_of_def (irange &r, tree name, basic_block bb)
+ranger_cache::range_of_def (vrange &r, tree name, basic_block bb)
{
gcc_checking_assert (gimple_range_ssa_p (name));
gcc_checking_assert (!bb || bb == gimple_bb (SSA_NAME_DEF_STMT (name)));
@@ -895,7 +904,7 @@ ranger_cache::range_of_def (irange &r, tree name, basic_block bb)
if (gimple_get_lhs (s) == name)
fold_range (r, s, get_global_range_query ());
else
- r = gimple_range_global (name);
+ gimple_range_global (r, name);
}
}
@@ -903,12 +912,12 @@ ranger_cache::range_of_def (irange &r, tree name, basic_block bb)
// lookups.
void
-ranger_cache::entry_range (irange &r, tree name, basic_block bb,
+ranger_cache::entry_range (vrange &r, tree name, basic_block bb,
enum rfd_mode mode)
{
if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
{
- r = gimple_range_global (name);
+ gimple_range_global (r, name);
return;
}
@@ -923,12 +932,12 @@ ranger_cache::entry_range (irange &r, tree name, basic_block bb,
// lookups.
void
-ranger_cache::exit_range (irange &r, tree name, basic_block bb,
+ranger_cache::exit_range (vrange &r, tree name, basic_block bb,
enum rfd_mode mode)
{
if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
{
- r = gimple_range_global (name);
+ gimple_range_global (r, name);
return;
}
@@ -944,7 +953,7 @@ ranger_cache::exit_range (irange &r, tree name, basic_block bb,
// Always returns a range and true.
bool
-ranger_cache::edge_range (irange &r, edge e, tree name, enum rfd_mode mode)
+ranger_cache::edge_range (vrange &r, edge e, tree name, enum rfd_mode mode)
{
exit_range (r, name, e->src, mode);
// If this is not an abnormal edge, check for inferred ranges on exit.
@@ -961,7 +970,7 @@ ranger_cache::edge_range (irange &r, edge e, tree name, enum rfd_mode mode)
// Implement range_of_expr.
bool
-ranger_cache::range_of_expr (irange &r, tree name, gimple *stmt)
+ranger_cache::range_of_expr (vrange &r, tree name, gimple *stmt)
{
if (!gimple_range_ssa_p (name))
{
@@ -985,7 +994,7 @@ ranger_cache::range_of_expr (irange &r, tree name, gimple *stmt)
// the current cache values.
bool
-ranger_cache::range_on_edge (irange &r, edge e, tree expr)
+ranger_cache::range_on_edge (vrange &r, edge e, tree expr)
{
if (gimple_range_ssa_p (expr))
return edge_range (r, e, expr, RFD_NONE);
@@ -997,7 +1006,7 @@ ranger_cache::range_on_edge (irange &r, edge e, tree expr)
// def block for NAME. Otherwise, return false if the cache is empty.
bool
-ranger_cache::block_range (irange &r, basic_block bb, tree name, bool calc)
+ranger_cache::block_range (vrange &r, basic_block bb, tree name, bool calc)
{
gcc_checking_assert (gimple_range_ssa_p (name));
@@ -1041,9 +1050,10 @@ ranger_cache::propagate_cache (tree name)
basic_block bb;
edge_iterator ei;
edge e;
- int_range_max new_range;
- int_range_max current_range;
- int_range_max e_range;
+ tree type = TREE_TYPE (name);
+ Value_Range new_range (type);
+ Value_Range current_range (type);
+ Value_Range e_range (type);
// Process each block by seeing if its calculated range on entry is
// the same as its cached value. If there is a difference, update
@@ -1178,8 +1188,8 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
{
edge_iterator ei;
edge e;
- int_range_max block_result;
- int_range_max undefined;
+ Value_Range block_result (TREE_TYPE (name));
+ Value_Range undefined (TREE_TYPE (name));
// At this point we shouldn't be looking at the def, entry or exit block.
gcc_checking_assert (bb != def_bb && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
@@ -1232,7 +1242,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
FOR_EACH_EDGE (e, ei, node->preds)
{
basic_block pred = e->src;
- int_range_max r;
+ Value_Range r (TREE_TYPE (name));
if (DEBUG_RANGE_CACHE)
fprintf (dump_file, " %d->%d ",e->src->index, e->dest->index);
@@ -1306,7 +1316,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
// dominator tree based on MODE.
bool
-ranger_cache::range_from_dom (irange &r, tree name, basic_block start_bb,
+ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
enum rfd_mode mode)
{
if (mode == RFD_NONE || !dom_info_available_p (CDI_DOMINATORS))
diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
index 73d12f35abe..1e4b5b30565 100644
--- a/gcc/gimple-range-cache.h
+++ b/gcc/gimple-range-cache.h
@@ -34,8 +34,8 @@ public:
block_range_cache ();
~block_range_cache ();
- bool set_bb_range (tree name, const_basic_block bb, const irange &r);
- bool get_bb_range (irange &r, tree name, const_basic_block bb);
+ bool set_bb_range (tree name, const_basic_block bb, const vrange &v);
+ bool get_bb_range (vrange &v, tree name, const_basic_block bb);
bool bb_range_p (tree name, const_basic_block bb);
void dump (FILE *f);
@@ -57,13 +57,13 @@ class ssa_global_cache
public:
ssa_global_cache ();
~ssa_global_cache ();
- bool get_global_range (irange &r, tree name) const;
- bool set_global_range (tree name, const irange &r);
+ bool get_global_range (vrange &r, tree name) const;
+ bool set_global_range (tree name, const vrange &r);
void clear_global_range (tree name);
void clear ();
void dump (FILE *f = stderr);
private:
- vec<irange *> m_tab;
+ vec<vrange *> m_tab;
vrange_allocator *m_range_allocator;
};
@@ -77,13 +77,13 @@ public:
ranger_cache (int not_executable_flag, bool use_imm_uses);
~ranger_cache ();
- virtual bool range_of_expr (irange &r, tree name, gimple *stmt);
- virtual bool range_on_edge (irange &r, edge e, tree expr);
- bool block_range (irange &r, basic_block bb, tree name, bool calc = true);
+ virtual bool range_of_expr (vrange &r, tree name, gimple *stmt);
+ virtual bool range_on_edge (vrange &r, edge e, tree expr);
+ bool block_range (vrange &r, basic_block bb, tree name, bool calc = true);
- bool get_global_range (irange &r, tree name) const;
- bool get_global_range (irange &r, tree name, bool ¤t_p);
- void set_global_range (tree name, const irange &r);
+ bool get_global_range (vrange &r, tree name) const;
+ bool get_global_range (vrange &r, tree name, bool ¤t_p);
+ void set_global_range (tree name, const vrange &r);
void propagate_updated_value (tree name, basic_block bb);
@@ -106,11 +106,11 @@ private:
RFD_READ_ONLY, // Scan DOM tree, do not write to cache.
RFD_FILL // Scan DOM tree, updating important nodes.
};
- bool range_from_dom (irange &r, tree name, basic_block bb, enum rfd_mode);
- void range_of_def (irange &r, tree name, basic_block bb = NULL);
- void entry_range (irange &r, tree expr, basic_block bb, enum rfd_mode);
- void exit_range (irange &r, tree expr, basic_block bb, enum rfd_mode);
- bool edge_range (irange &r, edge e, tree name, enum rfd_mode);
+ bool range_from_dom (vrange &r, tree name, basic_block bb, enum rfd_mode);
+ void range_of_def (vrange &r, tree name, basic_block bb = NULL);
+ void entry_range (vrange &r, tree expr, basic_block bb, enum rfd_mode);
+ void exit_range (vrange &r, tree expr, basic_block bb, enum rfd_mode);
+ bool edge_range (vrange &r, edge e, tree name, enum rfd_mode);
vec<basic_block> m_workback;
class update_list *m_update;
diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
index 5264e627c9a..6fe33408f7e 100644
--- a/gcc/gimple-range-edge.cc
+++ b/gcc/gimple-range-edge.cc
@@ -83,11 +83,8 @@ gimple_outgoing_range::~gimple_outgoing_range ()
// Use a cached value if it exists, or calculate it if not.
bool
-gimple_outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
+gimple_outgoing_range::switch_edge_range (irange &r, gswitch *sw, edge e)
{
- gcc_checking_assert (is_a<gswitch *> (s));
- gswitch *sw = as_a<gswitch *> (s);
-
// ADA currently has cases where the index is 64 bits and the case
// arguments are 32 bit, causing a trap when we create a case_range.
// Until this is resolved (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87798)
@@ -204,12 +201,9 @@ gimple_outgoing_range::edge_range_p (irange &r, edge e)
gcc_checking_assert (is_a<gswitch *> (s));
gswitch *sw = as_a<gswitch *> (s);
- tree type = TREE_TYPE (gimple_switch_index (sw));
-
- if (!irange::supports_type_p (type))
- return NULL;
- if (get_edge_range (r, sw, e))
+ // Switches can only be integers.
+ if (switch_edge_range (as_a <irange> (r), sw, e))
return s;
return NULL;
diff --git a/gcc/gimple-range-edge.h b/gcc/gimple-range-edge.h
index ce383b0aa6f..a9c4af8715b 100644
--- a/gcc/gimple-range-edge.h
+++ b/gcc/gimple-range-edge.h
@@ -43,7 +43,7 @@ public:
gimple *edge_range_p (irange &r, edge e);
private:
void calc_switch_ranges (gswitch *sw);
- bool get_edge_range (irange &r, gimple *s, edge e);
+ bool switch_edge_range (irange &r, gswitch *sw, edge e);
int m_max_edges;
hash_map<edge, irange *> *m_edge_table;
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index c53d2863d5e..c1a801668c4 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -60,7 +60,7 @@ fur_source::fur_source (range_query *q)
// Invoke range_of_expr on EXPR.
bool
-fur_source::get_operand (irange &r, tree expr)
+fur_source::get_operand (vrange &r, tree expr)
{
return m_query->range_of_expr (r, expr);
}
@@ -69,7 +69,7 @@ fur_source::get_operand (irange &r, tree expr)
// range_query to get the range on the edge.
bool
-fur_source::get_phi_operand (irange &r, tree expr, edge e)
+fur_source::get_phi_operand (vrange &r, tree expr, edge e)
{
return m_query->range_on_edge (r, e, expr);
}
@@ -109,8 +109,8 @@ class fur_edge : public fur_source
{
public:
fur_edge (edge e, range_query *q = NULL);
- virtual bool get_operand (irange &r, tree expr) override;
- virtual bool get_phi_operand (irange &r, tree expr, edge e) override;
+ virtual bool get_operand (vrange &r, tree expr) override;
+ virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
private:
edge m_edge;
};
@@ -126,7 +126,7 @@ fur_edge::fur_edge (edge e, range_query *q) : fur_source (q)
// Get the value of EXPR on edge m_edge.
bool
-fur_edge::get_operand (irange &r, tree expr)
+fur_edge::get_operand (vrange &r, tree expr)
{
return m_query->range_on_edge (r, m_edge, expr);
}
@@ -135,7 +135,7 @@ fur_edge::get_operand (irange &r, tree expr)
// range_query to get the range on the edge.
bool
-fur_edge::get_phi_operand (irange &r, tree expr, edge e)
+fur_edge::get_phi_operand (vrange &r, tree expr, edge e)
{
// Edge to edge recalculations not supoprted yet, until we sort it out.
gcc_checking_assert (e == m_edge);
@@ -152,7 +152,7 @@ fur_stmt::fur_stmt (gimple *s, range_query *q) : fur_source (q)
// Retreive range of EXPR as it occurs as a use on stmt M_STMT.
bool
-fur_stmt::get_operand (irange &r, tree expr)
+fur_stmt::get_operand (vrange &r, tree expr)
{
return m_query->range_of_expr (r, expr, m_stmt);
}
@@ -161,7 +161,7 @@ fur_stmt::get_operand (irange &r, tree expr)
// range_query to get the range on the edge.
bool
-fur_stmt::get_phi_operand (irange &r, tree expr, edge e)
+fur_stmt::get_phi_operand (vrange &r, tree expr, edge e)
{
// Pick up the range of expr from edge E.
fur_edge e_src (e, m_query);
@@ -214,42 +214,42 @@ fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
class fur_list : public fur_source
{
public:
- fur_list (irange &r1);
- fur_list (irange &r1, irange &r2);
- fur_list (unsigned num, irange *list);
- virtual bool get_operand (irange &r, tree expr) override;
- virtual bool get_phi_operand (irange &r, tree expr, edge e) override;
+ fur_list (vrange &r1);
+ fur_list (vrange &r1, vrange &r2);
+ fur_list (unsigned num, vrange **list);
+ virtual bool get_operand (vrange &r, tree expr) override;
+ virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
private:
- int_range_max m_local[2];
- irange *m_list;
+ vrange *m_local[2];
+ vrange **m_list;
unsigned m_index;
unsigned m_limit;
};
// One range supplied for unary operations.
-fur_list::fur_list (irange &r1) : fur_source (NULL)
+fur_list::fur_list (vrange &r1) : fur_source (NULL)
{
m_list = m_local;
m_index = 0;
m_limit = 1;
- m_local[0] = r1;
+ m_local[0] = &r1;
}
// Two ranges supplied for binary operations.
-fur_list::fur_list (irange &r1, irange &r2) : fur_source (NULL)
+fur_list::fur_list (vrange &r1, vrange &r2) : fur_source (NULL)
{
m_list = m_local;
m_index = 0;
m_limit = 2;
- m_local[0] = r1;
- m_local[1] = r2;
+ m_local[0] = &r1;
+ m_local[1] = &r2;
}
// Arbitrary number of ranges in a vector.
-fur_list::fur_list (unsigned num, irange *list) : fur_source (NULL)
+fur_list::fur_list (unsigned num, vrange **list) : fur_source (NULL)
{
m_list = list;
m_index = 0;
@@ -259,18 +259,18 @@ fur_list::fur_list (unsigned num, irange *list) : fur_source (NULL)
// Get the next operand from the vector, ensure types are compatible.
bool
-fur_list::get_operand (irange &r, tree expr)
+fur_list::get_operand (vrange &r, tree expr)
{
if (m_index >= m_limit)
return m_query->range_of_expr (r, expr);
- r = m_list[m_index++];
+ r = *m_list[m_index++];
gcc_checking_assert (range_compatible_p (TREE_TYPE (expr), r.type ()));
return true;
}
// This will simply pick the next operand from the vector.
bool
-fur_list::get_phi_operand (irange &r, tree expr, edge e ATTRIBUTE_UNUSED)
+fur_list::get_phi_operand (vrange &r, tree expr, edge e ATTRIBUTE_UNUSED)
{
return get_operand (r, expr);
}
@@ -278,7 +278,7 @@ fur_list::get_phi_operand (irange &r, tree expr, edge e ATTRIBUTE_UNUSED)
// Fold stmt S into range R using R1 as the first operand.
bool
-fold_range (irange &r, gimple *s, irange &r1)
+fold_range (vrange &r, gimple *s, vrange &r1)
{
fold_using_range f;
fur_list src (r1);
@@ -288,7 +288,7 @@ fold_range (irange &r, gimple *s, irange &r1)
// Fold stmt S into range R using R1 and R2 as the first two operands.
bool
-fold_range (irange &r, gimple *s, irange &r1, irange &r2)
+fold_range (vrange &r, gimple *s, vrange &r1, vrange &r2)
{
fold_using_range f;
fur_list src (r1, r2);
@@ -299,7 +299,7 @@ fold_range (irange &r, gimple *s, irange &r1, irange &r2)
// operands encountered.
bool
-fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector)
+fold_range (vrange &r, gimple *s, unsigned num_elements, vrange **vector)
{
fold_using_range f;
fur_list src (num_elements, vector);
@@ -309,7 +309,7 @@ fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector)
// Fold stmt S into range R using range query Q.
bool
-fold_range (irange &r, gimple *s, range_query *q)
+fold_range (vrange &r, gimple *s, range_query *q)
{
fold_using_range f;
fur_stmt src (s, q);
@@ -319,7 +319,7 @@ fold_range (irange &r, gimple *s, range_query *q)
// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE.
bool
-fold_range (irange &r, gimple *s, edge on_edge, range_query *q)
+fold_range (vrange &r, gimple *s, edge on_edge, range_query *q)
{
fold_using_range f;
fur_edge src (on_edge, q);
@@ -370,7 +370,7 @@ adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt)
// Adjust the range for an IMAGPART_EXPR.
static void
-adjust_imagpart_expr (irange &res, const gimple *stmt)
+adjust_imagpart_expr (vrange &res, const gimple *stmt)
{
tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
@@ -413,7 +413,7 @@ adjust_imagpart_expr (irange &res, const gimple *stmt)
// Adjust the range for a REALPART_EXPR.
static void
-adjust_realpart_expr (irange &res, const gimple *stmt)
+adjust_realpart_expr (vrange &res, const gimple *stmt)
{
tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
@@ -442,12 +442,12 @@ adjust_realpart_expr (irange &res, const gimple *stmt)
// this statement.
static void
-gimple_range_adjustment (irange &res, const gimple *stmt)
+gimple_range_adjustment (vrange &res, const gimple *stmt)
{
switch (gimple_expr_code (stmt))
{
case POINTER_DIFF_EXPR:
- adjust_pointer_diff_expr (res, stmt);
+ adjust_pointer_diff_expr (as_a <irange> (res), stmt);
return;
case IMAGPART_EXPR:
@@ -536,7 +536,7 @@ gimple_range_operand2 (const gimple *stmt)
// be calculated, return false.
bool
-fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
+fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
{
bool res = false;
// If name and S are specified, make sure it is an LHS of S.
@@ -549,7 +549,7 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
// Process addresses.
if (gimple_code (s) == GIMPLE_ASSIGN
&& gimple_assign_rhs_code (s) == ADDR_EXPR)
- return range_of_address (r, s, src);
+ return range_of_address (as_a <irange> (r), s, src);
if (range_op_handler (s))
res = range_of_range_op (r, s, src);
@@ -566,7 +566,7 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
if (!name || !gimple_range_ssa_p (name))
return false;
// We don't understand the stmt, so return the global range.
- r = gimple_range_global (name);
+ gimple_range_global (r, name);
return true;
}
@@ -587,9 +587,8 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
// If a range cannot be calculated, return false.
bool
-fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
+fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
{
- int_range_max range1, range2;
tree type = gimple_range_type (s);
if (!type)
return false;
@@ -599,13 +598,16 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
tree lhs = gimple_get_lhs (s);
tree op1 = gimple_range_operand1 (s);
tree op2 = gimple_range_operand2 (s);
+ Value_Range range1 (TREE_TYPE (op1));
+ Value_Range range2 (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
if (src.get_operand (range1, op1))
{
if (!op2)
{
// Fold range, and register any dependency if available.
- int_range<2> r2 (type);
+ Value_Range r2 (type);
+ r2.set_varying (type);
handler.fold_range (r, type, range1, r2);
if (lhs && gimple_range_ssa_p (op1))
{
@@ -630,7 +632,8 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
}
// Fold range, and register any dependency if available.
handler.fold_range (r, type, range1, range2, rel);
- relation_fold_and_or (r, s, src);
+ if (irange::supports_type_p (type))
+ relation_fold_and_or (as_a <irange> (r), s, src);
if (lhs)
{
if (src.gori ())
@@ -663,7 +666,8 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
e0 = NULL;
if (!single_pred_p (e1->dest))
e1 = NULL;
- src.register_outgoing_edges (as_a<gcond *> (s), r, e0, e1);
+ src.register_outgoing_edges (as_a<gcond *> (s),
+ as_a <irange> (r), e0, e1);
}
}
else
@@ -729,12 +733,12 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
{
/* For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
allow going from non-NULL pointer to NULL. */
- if (!range_includes_zero_p (&r))
+ if (r.undefined_p () || !r.contains_p (build_zero_cst (r.type ())))
{
/* We could here instead adjust r by off >> LOG2_BITS_PER_UNIT
using POINTER_PLUS_EXPR if off_cst and just fall back to
this. */
- r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ r.set_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
return true;
}
}
@@ -746,22 +750,22 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
&& known_ne (off, 0)
&& (flag_delete_null_pointer_checks || known_gt (off, 0)))
{
- r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ r.set_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
return true;
}
- r = int_range<2> (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ r.set_varying (TREE_TYPE (gimple_assign_rhs1 (stmt)));
return true;
}
// Handle "= &a".
if (tree_single_nonzero_warnv_p (expr, &strict_overflow_p))
{
- r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ r.set_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
return true;
}
// Otherwise return varying.
- r = int_range<2> (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ r.set_varying (TREE_TYPE (gimple_assign_rhs1 (stmt)));
return true;
}
@@ -769,12 +773,12 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
// If a range cannot be calculated, return false.
bool
-fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
+fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src)
{
tree phi_def = gimple_phi_result (phi);
tree type = gimple_range_type (phi);
- int_range_max arg_range;
- int_range_max equiv_range;
+ Value_Range arg_range (type);
+ Value_Range equiv_range (type);
unsigned x;
if (!type)
@@ -881,7 +885,7 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
// If a range cannot be calculated, return false.
bool
-fold_using_range::range_of_call (irange &r, gcall *call, fur_source &src)
+fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &src)
{
tree type = gimple_range_type (call);
if (!type)
@@ -893,18 +897,18 @@ fold_using_range::range_of_call (irange &r, gcall *call, fur_source &src)
if (range_of_builtin_call (r, call, src))
;
else if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p))
- r.set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
+ r.set_nonnegative (type);
else if (gimple_call_nonnull_result_p (call)
|| gimple_call_nonnull_arg (call))
- r = range_nonzero (type);
+ r.set_nonzero (type);
else
r.set_varying (type);
// If there is an LHS, intersect that with what is known.
if (lhs)
{
- value_range def;
- def = gimple_range_global (lhs);
+ Value_Range def (TREE_TYPE (lhs));
+ gimple_range_global (def, lhs);
r.intersect (def);
}
return true;
@@ -971,13 +975,30 @@ get_letter_range (tree type, irange &lowers, irange &uppers)
// TRUE. Otherwise return FALSE.
bool
-fold_using_range::range_of_builtin_call (irange &r, gcall *call,
+fold_using_range::range_of_builtin_call (vrange &r, gcall *call,
fur_source &src)
{
combined_fn func = gimple_call_combined_fn (call);
if (func == CFN_LAST)
return false;
+ tree type = gimple_range_type (call);
+ gcc_checking_assert (type);
+
+ if (irange::supports_type_p (type))
+ return range_of_builtin_int_call (as_a <irange> (r), call, src);
+
+ return false;
+}
+
+bool
+fold_using_range::range_of_builtin_int_call (irange &r, gcall *call,
+ fur_source &src)
+{
+ combined_fn func = gimple_call_combined_fn (call);
+ if (func == CFN_LAST)
+ return false;
+
tree type = gimple_range_type (call);
tree arg;
int mini, maxi, zerov = 0, prec;
@@ -1256,9 +1277,8 @@ fold_using_range::range_of_builtin_call (irange &r, gcall *call,
// If a range cannot be calculated, return false.
bool
-fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src)
+fold_using_range::range_of_cond_expr (vrange &r, gassign *s, fur_source &src)
{
- int_range_max cond_range, range1, range2;
tree cond = gimple_assign_rhs1 (s);
tree op1 = gimple_assign_rhs2 (s);
tree op2 = gimple_assign_rhs3 (s);
@@ -1267,6 +1287,9 @@ fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src)
if (!type)
return false;
+ Value_Range range1 (TREE_TYPE (op1));
+ Value_Range range2 (TREE_TYPE (op2));
+ Value_Range cond_range (TREE_TYPE (cond));
gcc_checking_assert (gimple_assign_rhs_code (s) == COND_EXPR);
gcc_checking_assert (range_compatible_p (TREE_TYPE (op1), TREE_TYPE (op2)));
src.get_operand (cond_range, cond);
@@ -1438,7 +1461,6 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
void
fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge e1)
{
- int_range_max r;
int_range<2> e0_range, e1_range;
tree name;
basic_block bb = gimple_bb (s);
@@ -1505,6 +1527,7 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
continue;
tree ssa1 = gimple_range_ssa_p (gimple_range_operand1 (stmt));
tree ssa2 = gimple_range_ssa_p (gimple_range_operand2 (stmt));
+ Value_Range r (TREE_TYPE (name));
if (ssa1 && ssa2)
{
if (e0 && gori ()->outgoing_edge_range_p (r, e0, name, *m_query)
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index 4b5d4b6e0b8..df24280ee40 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_GIMPLE_RANGE_FOLD_H
// This file is the main include point for gimple range folding.
-// These routines will fold stmt S into the result irange R.
+// These routines will fold stmt S into the result range R.
// Any ssa_names on the stmt will be calculated using the range_query
// parameter via a call to range_of_expr.
// If no range_query is provided, current global range info will be used.
@@ -31,15 +31,15 @@ along with GCC; see the file COPYING3. If not see
// it appeared on that edge.
// Fold stmt S into range R using range query Q.
-bool fold_range (irange &r, gimple *s, range_query *q = NULL);
+bool fold_range (vrange &r, gimple *s, range_query *q = NULL);
// Recalculate stmt S into R using range query Q as if it were on edge ON_EDGE.
-bool fold_range (irange &r, gimple *s, edge on_edge, range_query *q = NULL);
+bool fold_range (vrange &v, gimple *s, edge on_edge, range_query *q = NULL);
// These routines the operands to be specified when manually folding.
// Any excess queries will be drawn from the current range_query.
-bool fold_range (irange &r, gimple *s, irange &r1);
-bool fold_range (irange &r, gimple *s, irange &r1, irange &r2);
-bool fold_range (irange &r, gimple *s, unsigned num_elements, irange *vector);
+bool fold_range (vrange &r, gimple *s, vrange &r1);
+bool fold_range (vrange &r, gimple *s, vrange &r1, vrange &r2);
+bool fold_range (vrange &r, gimple *s, unsigned num_elements, vrange **vector);
// Return the type of range which statement S calculates. If the type is
// unsupported or no type can be determined, return NULL_TREE.
@@ -66,7 +66,7 @@ gimple_range_type (const gimple *s)
type = TREE_TYPE (type);
}
}
- if (type && irange::supports_type_p (type))
+ if (type && vrange::supports_type_p (type))
return type;
return NULL_TREE;
}
@@ -79,7 +79,7 @@ gimple_range_ssa_p (tree exp)
if (exp && TREE_CODE (exp) == SSA_NAME &&
!SSA_NAME_IS_VIRTUAL_OPERAND (exp) &&
!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) &&
- irange::supports_type_p (TREE_TYPE (exp)))
+ vrange::supports_type_p (TREE_TYPE (exp)))
return exp;
return NULL_TREE;
}
@@ -108,8 +108,8 @@ public:
fur_source (range_query *q = NULL);
inline range_query *query () { return m_query; }
inline class gori_compute *gori () { return m_gori; };
- virtual bool get_operand (irange &r, tree expr);
- virtual bool get_phi_operand (irange &r, tree expr, edge e);
+ virtual bool get_operand (vrange &r, tree expr);
+ virtual bool get_phi_operand (vrange &r, tree expr, edge e);
virtual relation_kind query_relation (tree op1, tree op2);
virtual void register_relation (gimple *stmt, relation_kind k, tree op1,
tree op2);
@@ -128,8 +128,8 @@ class fur_stmt : public fur_source
{
public:
fur_stmt (gimple *s, range_query *q = NULL);
- virtual bool get_operand (irange &r, tree expr) override;
- virtual bool get_phi_operand (irange &r, tree expr, edge e) override;
+ virtual bool get_operand (vrange &r, tree expr) override;
+ virtual bool get_phi_operand (vrange &r, tree expr, edge e) override;
virtual relation_kind query_relation (tree op1, tree op2) override;
private:
gimple *m_stmt;
@@ -161,17 +161,18 @@ extern tree gimple_range_operand2 (const gimple *s);
class fold_using_range
{
public:
- bool fold_stmt (irange &r, gimple *s, class fur_source &src,
+ bool fold_stmt (vrange &r, gimple *s, class fur_source &src,
tree name = NULL_TREE);
protected:
- bool range_of_range_op (irange &r, gimple *s, fur_source &src);
- bool range_of_call (irange &r, gcall *call, fur_source &src);
- bool range_of_cond_expr (irange &r, gassign* cond, fur_source &src);
+ bool range_of_range_op (vrange &r, gimple *s, fur_source &src);
+ bool range_of_call (vrange &r, gcall *call, fur_source &src);
+ bool range_of_cond_expr (vrange &r, gassign* cond, fur_source &src);
bool range_of_address (irange &r, gimple *s, fur_source &src);
- bool range_of_builtin_call (irange &r, gcall *call, fur_source &src);
+ bool range_of_builtin_call (vrange &r, gcall *call, fur_source &src);
+ bool range_of_builtin_int_call (irange &r, gcall *call, fur_source &src);
void range_of_builtin_ubsan_call (irange &r, gcall *call, tree_code code,
fur_source &src);
- bool range_of_phi (irange &r, gphi *phi, fur_source &src);
+ bool range_of_phi (vrange &r, gphi *phi, fur_source &src);
void range_of_ssa_name_with_loop_info (irange &, tree, class loop *, gphi *,
fur_source &src);
void relation_fold_and_or (irange& lhs_range, gimple *s, fur_source &src);
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 72032132cac..0a3e54eae4e 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
// LHS_RANGE. Return false if nothing can be determined.
bool
-gimple_range_calc_op1 (irange &r, const gimple *stmt, const irange &lhs_range)
+gimple_range_calc_op1 (vrange &r, const gimple *stmt, const vrange &lhs_range)
{
gcc_checking_assert (gimple_num_ops (stmt) < 3);
// Give up on empty ranges.
@@ -55,8 +55,8 @@ gimple_range_calc_op1 (irange &r, const gimple *stmt, const irange &lhs_range)
// nothing can be determined.
bool
-gimple_range_calc_op1 (irange &r, const gimple *stmt,
- const irange &lhs_range, const irange &op2_range)
+gimple_range_calc_op1 (vrange &r, const gimple *stmt,
+ const vrange &lhs_range, const vrange &op2_range)
{
// Give up on empty ranges.
if (lhs_range.undefined_p ())
@@ -86,8 +86,8 @@ gimple_range_calc_op1 (irange &r, const gimple *stmt,
// nothing can be determined.
bool
-gimple_range_calc_op2 (irange &r, const gimple *stmt,
- const irange &lhs_range, const irange &op1_range)
+gimple_range_calc_op2 (vrange &r, const gimple *stmt,
+ const vrange &lhs_range, const vrange &op1_range)
{
// Give up on empty ranges.
if (lhs_range.undefined_p ())
@@ -663,8 +663,8 @@ gori_compute::gori_compute (int not_executable_flag)
// was not resolvable.
bool
-gori_compute::compute_operand_range_switch (irange &r, gswitch *s,
- const irange &lhs,
+gori_compute::compute_operand_range_switch (vrange &r, gswitch *s,
+ const vrange &lhs,
tree name, fur_source &src)
{
tree op1 = gimple_switch_index (s);
@@ -691,8 +691,8 @@ gori_compute::compute_operand_range_switch (irange &r, gswitch *s,
// store the evaluation in R, otherwise return FALSE.
bool
-gori_compute::compute_operand_range (irange &r, gimple *stmt,
- const irange &lhs, tree name,
+gori_compute::compute_operand_range (vrange &r, gimple *stmt,
+ const vrange &lhs, tree name,
fur_source &src)
{
// If the lhs doesn't tell us anything, neither will unwinding further.
@@ -743,13 +743,18 @@ gori_compute::compute_operand_range (irange &r, gimple *stmt,
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
- int_range_max op1_trange, op1_frange;
- int_range_max op2_trange, op2_frange;
- compute_logical_operands (op1_trange, op1_frange, stmt, lhs,
+ tree type = TREE_TYPE (name);
+ Value_Range op1_trange (type), op1_frange (type);
+ Value_Range op2_trange (type), op2_frange (type);
+ compute_logical_operands (op1_trange, op1_frange, stmt,
+ as_a <irange> (lhs),
name, src, op1, op1_in_chain);
- compute_logical_operands (op2_trange, op2_frange, stmt, lhs,
+ compute_logical_operands (op2_trange, op2_frange, stmt,
+ as_a <irange> (lhs),
name, src, op2, op2_in_chain);
- res = logical_combine (r, gimple_expr_code (stmt), lhs,
+ res = logical_combine (r,
+ gimple_expr_code (stmt),
+ as_a <irange> (lhs),
op1_trange, op1_frange, op2_trange, op2_frange);
if (idx)
tracer.trailer (idx, "compute_operand", res, name, r);
@@ -789,10 +794,10 @@ range_is_either_true_or_false (const irange &r)
// the LHS.
bool
-gori_compute::logical_combine (irange &r, enum tree_code code,
+gori_compute::logical_combine (vrange &r, enum tree_code code,
const irange &lhs,
- const irange &op1_true, const irange &op1_false,
- const irange &op2_true, const irange &op2_false)
+ const vrange &op1_true, const vrange &op1_false,
+ const vrange &op2_true, const vrange &op2_false)
{
if (op1_true.varying_p () && op1_false.varying_p ()
&& op2_true.varying_p () && op2_false.varying_p ())
@@ -868,7 +873,7 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
if (!range_is_either_true_or_false (lhs))
{
bool res;
- int_range_max r1;
+ Value_Range r1 (r);
if (logical_combine (r1, code, m_bool_zero, op1_true, op1_false,
op2_true, op2_false)
&& logical_combine (r, code, m_bool_one, op1_true, op1_false,
@@ -898,11 +903,11 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
else
{
// The FALSE side is the union of the other 3 cases.
- int_range_max ff (op1_false);
+ Value_Range ff (op1_false);
ff.intersect (op2_false);
- int_range_max tf (op1_true);
+ Value_Range tf (op1_true);
tf.intersect (op2_false);
- int_range_max ft (op1_false);
+ Value_Range ft (op1_false);
ft.intersect (op2_true);
r = ff;
r.union_ (tf);
@@ -925,11 +930,11 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
{
// The TRUE side of an OR operation will be the union of
// the other three combinations.
- int_range_max tt (op1_true);
+ Value_Range tt (op1_true);
tt.intersect (op2_true);
- int_range_max tf (op1_true);
+ Value_Range tf (op1_true);
tf.intersect (op2_false);
- int_range_max ft (op1_false);
+ Value_Range ft (op1_false);
ft.intersect (op2_true);
r = tt;
r.union_ (tf);
@@ -951,7 +956,7 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
// OP_IN_CHAIN is true.
void
-gori_compute::compute_logical_operands (irange &true_range, irange &false_range,
+gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range,
gimple *stmt,
const irange &lhs,
tree name, fur_source &src,
@@ -1007,13 +1012,15 @@ gori_compute::compute_logical_operands (irange &true_range, irange &false_range,
// R, or false if no range could be calculated.
bool
-gori_compute::compute_operand1_range (irange &r, gimple *stmt,
- const irange &lhs, tree name,
+gori_compute::compute_operand1_range (vrange &r, gimple *stmt,
+ const vrange &lhs, tree name,
fur_source &src)
{
- int_range_max op1_range, op2_range;
tree op1 = gimple_range_operand1 (stmt);
tree op2 = gimple_range_operand2 (stmt);
+ Value_Range op1_range (TREE_TYPE (op1));
+ Value_Range tmp (TREE_TYPE (op1));
+ Value_Range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
// Fetch the known range for op1 in this block.
src.get_operand (op1_range, op1);
@@ -1022,7 +1029,7 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
if (op2)
{
src.get_operand (op2_range, op2);
- if (!gimple_range_calc_op1 (r, stmt, lhs, op2_range))
+ if (!gimple_range_calc_op1 (tmp, stmt, lhs, op2_range))
return false;
}
else
@@ -1030,7 +1037,7 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
// We pass op1_range to the unary operation. Nomally it's a
// hidden range_for_type parameter, but sometimes having the
// actual range can result in better information.
- if (!gimple_range_calc_op1 (r, stmt, lhs, op1_range))
+ if (!gimple_range_calc_op1 (tmp, stmt, lhs, op1_range))
return false;
}
@@ -1053,7 +1060,7 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
tracer.print (idx, "Computes ");
print_generic_expr (dump_file, op1, TDF_SLIM);
fprintf (dump_file, " = ");
- r.dump (dump_file);
+ tmp.dump (dump_file);
fprintf (dump_file, " intersect Known range : ");
op1_range.dump (dump_file);
fputc ('\n', dump_file);
@@ -1061,13 +1068,14 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
// Intersect the calculated result with the known result and return if done.
if (op1 == name)
{
- r.intersect (op1_range);
+ tmp.intersect (op1_range);
+ r = tmp;
if (idx)
tracer.trailer (idx, "produces ", true, name, r);
return true;
}
// If the calculation continues, we're using op1_range as the new LHS.
- op1_range.intersect (r);
+ op1_range.intersect (tmp);
if (idx)
tracer.trailer (idx, "produces ", true, op1, op1_range);
@@ -1084,19 +1092,21 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt,
// R, or false if no range could be calculated.
bool
-gori_compute::compute_operand2_range (irange &r, gimple *stmt,
- const irange &lhs, tree name,
+gori_compute::compute_operand2_range (vrange &r, gimple *stmt,
+ const vrange &lhs, tree name,
fur_source &src)
{
- int_range_max op1_range, op2_range;
tree op1 = gimple_range_operand1 (stmt);
tree op2 = gimple_range_operand2 (stmt);
+ Value_Range op1_range (TREE_TYPE (op1));
+ Value_Range op2_range (TREE_TYPE (op2));
+ Value_Range tmp (TREE_TYPE (op2));
src.get_operand (op1_range, op1);
src.get_operand (op2_range, op2);
// Intersect with range for op2 based on lhs and op1.
- if (!gimple_range_calc_op2 (r, stmt, lhs, op1_range))
+ if (!gimple_range_calc_op2 (tmp, stmt, lhs, op1_range))
return false;
unsigned idx;
@@ -1118,7 +1128,7 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt,
tracer.print (idx, "Computes ");
print_generic_expr (dump_file, op2, TDF_SLIM);
fprintf (dump_file, " = ");
- r.dump (dump_file);
+ tmp.dump (dump_file);
fprintf (dump_file, " intersect Known range : ");
op2_range.dump (dump_file);
fputc ('\n', dump_file);
@@ -1126,13 +1136,14 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt,
// Intersect the calculated result with the known result and return if done.
if (op2 == name)
{
- r.intersect (op2_range);
+ tmp.intersect (op2_range);
+ r = tmp;
if (idx)
tracer.trailer (idx, " produces ", true, NULL_TREE, r);
return true;
}
// If the calculation continues, we're using op2_range as the new LHS.
- op2_range.intersect (r);
+ op2_range.intersect (tmp);
if (idx)
tracer.trailer (idx, " produces ", true, op2, op2_range);
@@ -1149,13 +1160,13 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt,
// R, or false if no range could be calculated.
bool
-gori_compute::compute_operand1_and_operand2_range (irange &r,
+gori_compute::compute_operand1_and_operand2_range (vrange &r,
gimple *stmt,
- const irange &lhs,
+ const vrange &lhs,
tree name,
fur_source &src)
{
- int_range_max op_range;
+ Value_Range op_range (TREE_TYPE (name));
// Calculate a good a range for op2. Since op1 == op2, this will
// have already included whatever the actual range of name is.
@@ -1236,10 +1247,9 @@ gori_compute::has_edge_range_p (tree name, edge e)
// control edge or NAME is not defined by this edge.
bool
-gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
+gori_compute::outgoing_edge_range_p (vrange &r, edge e, tree name,
range_query &q)
{
- int_range_max lhs;
unsigned idx;
if ((e->flags & m_not_executable_flag))
@@ -1252,6 +1262,7 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
}
gcc_checking_assert (gimple_range_ssa_p (name));
+ int_range_max lhs;
// Determine if there is an outgoing edge.
gimple *stmt = outgoing.edge_range_p (lhs, e);
if (!stmt)
@@ -1312,10 +1323,9 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
// edge and OP2 on the false edge.
bool
-gori_compute::condexpr_adjust (irange &r1, irange &r2, gimple *, tree cond,
+gori_compute::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond,
tree op1, tree op2, fur_source &src)
{
- int_range_max tmp, cond_true, cond_false;
tree ssa1 = gimple_range_ssa_p (op1);
tree ssa2 = gimple_range_ssa_p (op2);
if (!ssa1 && !ssa2)
@@ -1341,15 +1351,19 @@ gori_compute::condexpr_adjust (irange &r1, irange &r2, gimple *, tree cond,
return false;
// Pick up the current values of each part of the condition.
- int_range_max cl, cr;
- src.get_operand (cl, gimple_assign_rhs1 (cond_def));
- src.get_operand (cr, gimple_assign_rhs2 (cond_def));
+ tree rhs1 = gimple_assign_rhs1 (cond_def);
+ tree rhs2 = gimple_assign_rhs2 (cond_def);
+ Value_Range cl (TREE_TYPE (rhs1));
+ Value_Range cr (TREE_TYPE (rhs2));
+ src.get_operand (cl, rhs1);
+ src.get_operand (cr, rhs2);
tree cond_name = c1 ? c1 : c2;
gimple *def_stmt = SSA_NAME_DEF_STMT (cond_name);
// Evaluate the value of COND_NAME on the true and false edges, using either
// the op1 or op2 routines based on its location.
+ Value_Range cond_true (type), cond_false (type);
if (c1)
{
if (!hand.op1_range (cond_false, type, m_bool_zero, cr))
@@ -1380,6 +1394,7 @@ gori_compute::condexpr_adjust (irange &r1, irange &r2, gimple *, tree cond,
}
// Now solve for SSA1 or SSA2 if they are in the dependency chain.
+ Value_Range tmp (type);
if (ssa1 && in_chain_p (ssa1, cond_name))
{
if (compute_operand_range (tmp, def_stmt, cond_true, ssa1, src))
diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
index 605884e2e53..f5f691fe424 100644
--- a/gcc/gimple-range-gori.h
+++ b/gcc/gimple-range-gori.h
@@ -121,7 +121,7 @@ private:
// on *ANY* edge that has been seen. FALSE indicates that the global value
// is applicable everywhere that has been processed.
//
-// outgoing_edge_range_p (irange &range, edge e, tree name)
+// outgoing_edge_range_p (vrange &range, edge e, tree name)
// Actually does the calculation of RANGE for name on E
// This represents application of whatever static range effect edge E
// may have on NAME, not any cumulative effect.
@@ -157,8 +157,8 @@ class gori_compute : public gori_map
{
public:
gori_compute (int not_executable_flag = 0);
- bool outgoing_edge_range_p (irange &r, edge e, tree name, range_query &q);
- bool condexpr_adjust (irange &r1, irange &r2, gimple *s, tree cond, tree op1,
+ bool outgoing_edge_range_p (vrange &r, edge e, tree name, range_query &q);
+ bool condexpr_adjust (vrange &r1, vrange &r2, gimple *s, tree cond, tree op1,
tree op2, fur_source &src);
bool has_edge_range_p (tree name, basic_block bb = NULL);
bool has_edge_range_p (tree name, edge e);
@@ -166,24 +166,24 @@ public:
private:
bool may_recompute_p (tree name, edge e);
bool may_recompute_p (tree name, basic_block bb = NULL);
- bool compute_operand_range (irange &r, gimple *stmt, const irange &lhs,
+ bool compute_operand_range (vrange &r, gimple *stmt, const vrange &lhs,
tree name, class fur_source &src);
- bool compute_operand_range_switch (irange &r, gswitch *s, const irange &lhs,
+ bool compute_operand_range_switch (vrange &r, gswitch *s, const vrange &lhs,
tree name, fur_source &src);
- bool compute_operand1_range (irange &r, gimple *stmt, const irange &lhs,
+ bool compute_operand1_range (vrange &r, gimple *stmt, const vrange &lhs,
tree name, fur_source &src);
- bool compute_operand2_range (irange &r, gimple *stmt, const irange &lhs,
+ bool compute_operand2_range (vrange &r, gimple *stmt, const vrange &lhs,
tree name, fur_source &src);
- bool compute_operand1_and_operand2_range (irange &r, gimple *stmt,
- const irange &lhs, tree name,
+ bool compute_operand1_and_operand2_range (vrange &r, gimple *stmt,
+ const vrange &lhs, tree name,
fur_source &src);
- void compute_logical_operands (irange &true_range, irange &false_range,
+ void compute_logical_operands (vrange &true_range, vrange &false_range,
gimple *stmt, const irange &lhs,
tree name, fur_source &src, tree op,
bool op_in_chain);
- bool logical_combine (irange &r, enum tree_code code, const irange &lhs,
- const irange &op1_true, const irange &op1_false,
- const irange &op2_true, const irange &op2_false);
+ bool logical_combine (vrange &r, enum tree_code code, const irange &lhs,
+ const vrange &op1_true, const vrange &op1_false,
+ const vrange &op2_true, const vrange &op2_false);
int_range<2> m_bool_zero; // Boolean false cached.
int_range<2> m_bool_one; // Boolean true cached.
@@ -193,14 +193,14 @@ private:
};
// These routines provide a GIMPLE interface to the range-ops code.
-extern bool gimple_range_calc_op1 (irange &r, const gimple *s,
- const irange &lhs_range);
-extern bool gimple_range_calc_op1 (irange &r, const gimple *s,
- const irange &lhs_range,
- const irange &op2_range);
-extern bool gimple_range_calc_op2 (irange &r, const gimple *s,
- const irange &lhs_range,
- const irange &op1_range);
+extern bool gimple_range_calc_op1 (vrange &r, const gimple *s,
+ const vrange &lhs_range);
+extern bool gimple_range_calc_op1 (vrange &r, const gimple *s,
+ const vrange &lhs_range,
+ const vrange &op2_range);
+extern bool gimple_range_calc_op2 (vrange &r, const gimple *s,
+ const vrange &lhs_range,
+ const vrange &op1_range);
// For each name that is an import into BB's exports..
#define FOR_EACH_GORI_IMPORT_NAME(gori, bb, name) \
diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc
index 14ddfb803d8..eee149104b4 100644
--- a/gcc/gimple-range-infer.cc
+++ b/gcc/gimple-range-infer.cc
@@ -58,7 +58,7 @@ non_null_loadstore (gimple *, tree op, tree, void *data)
// Add NAME and RANGE to the the range inference summary.
void
-gimple_infer_range::add_range (tree name, irange &range)
+gimple_infer_range::add_range (tree name, vrange &range)
{
m_names[num_args] = name;
m_ranges[num_args] = range;
@@ -126,7 +126,7 @@ class exit_range
{
public:
tree name;
- irange *range;
+ vrange *range;
exit_range *next;
};
@@ -181,7 +181,7 @@ infer_range_manager::~infer_range_manager ()
// Return a non-zero range value of the appropriate type for NAME from
// the cache, creating it if necessary.
-const irange&
+const vrange&
infer_range_manager::get_nonzero (tree name)
{
unsigned v = SSA_NAME_VERSION (name);
@@ -189,10 +189,8 @@ infer_range_manager::get_nonzero (tree name)
m_nonzero.safe_grow_cleared (num_ssa_names + 20);
if (!m_nonzero[v])
{
- tree type = TREE_TYPE (name);
- m_nonzero[v]
- = static_cast <irange *> (m_range_allocator.alloc_vrange (type));
- m_nonzero[v]->set_nonzero (type);
+ m_nonzero[v] = m_range_allocator.alloc_vrange (TREE_TYPE (name));
+ m_nonzero[v]->set_nonzero (TREE_TYPE (name));
}
return *(m_nonzero[v]);
}
@@ -219,7 +217,7 @@ infer_range_manager::has_range_p (tree name, basic_block bb)
// to include it.
bool
-infer_range_manager::maybe_adjust_range (irange &r, tree name, basic_block bb)
+infer_range_manager::maybe_adjust_range (vrange &r, tree name, basic_block bb)
{
if (!has_range_p (name, bb))
return false;
@@ -232,7 +230,7 @@ infer_range_manager::maybe_adjust_range (irange &r, tree name, basic_block bb)
// Add range R as an inferred range for NAME in block BB.
void
-infer_range_manager::add_range (tree name, basic_block bb, const irange &r)
+infer_range_manager::add_range (tree name, basic_block bb, const vrange &r)
{
if (bb->index >= (int)m_on_exit.length ())
m_on_exit.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1);
@@ -254,7 +252,7 @@ infer_range_manager::add_range (tree name, basic_block bb, const irange &r)
exit_range *ptr = m_on_exit[bb->index].find_ptr (name);
if (ptr)
{
- int_range_max cur = r;
+ Value_Range cur (r);
// If no new info is added, just return.
if (!cur.intersect (*(ptr->range)))
return;
@@ -263,7 +261,7 @@ infer_range_manager::add_range (tree name, basic_block bb, const irange &r)
else
{
vrange &v = cur;
- ptr->range = static_cast <irange *> (m_range_allocator.clone (v));
+ ptr->range = m_range_allocator.clone (v);
}
return;
}
diff --git a/gcc/gimple-range-infer.h b/gcc/gimple-range-infer.h
index 65f6e83809d..aafa8bb74f0 100644
--- a/gcc/gimple-range-infer.h
+++ b/gcc/gimple-range-infer.h
@@ -35,15 +35,15 @@ public:
inline unsigned num () const { return num_args; }
inline tree name (unsigned index) const
{ gcc_checking_assert (index < num_args); return m_names[index]; }
- inline const irange& range (unsigned index) const
+ inline const vrange& range (unsigned index) const
{ gcc_checking_assert (index < num_args); return m_ranges[index]; }
- void add_range (tree name, irange &range);
+ void add_range (tree name, vrange &range);
void add_nonzero (tree name);
private:
unsigned num_args;
static const int size_limit = 10;
tree m_names[size_limit];
- int_range<3> m_ranges[size_limit];
+ Value_Range m_ranges[size_limit];
inline void bump_index () { if (num_args < size_limit - 1) num_args++; }
};
@@ -58,10 +58,10 @@ class infer_range_manager
public:
infer_range_manager (bool do_search);
~infer_range_manager ();
- void add_range (tree name, basic_block bb, const irange &r);
+ void add_range (tree name, basic_block bb, const vrange &r);
void add_nonzero (tree name, basic_block bb);
bool has_range_p (tree name, basic_block bb);
- bool maybe_adjust_range (irange &r, tree name, basic_block bb);
+ bool maybe_adjust_range (vrange &r, tree name, basic_block bb);
private:
class exit_range_head
{
@@ -73,8 +73,8 @@ private:
};
void register_all_uses (tree name);
vec <exit_range_head> m_on_exit;
- const irange &get_nonzero (tree name);
- vec <irange *> m_nonzero;
+ const vrange &get_nonzero (tree name);
+ vec <vrange *> m_nonzero;
bitmap m_seen;
bitmap_obstack m_bitmaps;
struct obstack m_list_obstack;
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index 66f433dd1d5..f8ae6fb9ffb 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -83,7 +83,7 @@ path_range_query::clear_cache (tree name)
// If NAME has a cache entry, return it in R, and return TRUE.
inline bool
-path_range_query::get_cache (irange &r, tree name)
+path_range_query::get_cache (vrange &r, tree name)
{
if (!gimple_range_ssa_p (name))
return get_global_range_query ()->range_of_expr (r, name);
@@ -98,7 +98,7 @@ path_range_query::get_cache (irange &r, tree name)
// Set the cache entry for NAME to R.
void
-path_range_query::set_cache (const irange &r, tree name)
+path_range_query::set_cache (const vrange &r, tree name)
{
unsigned v = SSA_NAME_VERSION (name);
bitmap_set_bit (m_has_cache_entry, v);
@@ -149,7 +149,7 @@ path_range_query::defined_outside_path (tree name)
// Return the range of NAME on entry to the path.
void
-path_range_query::range_on_path_entry (irange &r, tree name)
+path_range_query::range_on_path_entry (vrange &r, tree name)
{
gcc_checking_assert (defined_outside_path (name));
basic_block entry = entry_bb ();
@@ -168,7 +168,7 @@ path_range_query::range_on_path_entry (irange &r, tree name)
// block. This can happen when we're querying a block with only an
// outgoing edge (no statement but the fall through edge), but for
// which we can determine a range on entry to the block.
- int_range_max tmp;
+ Value_Range tmp (TREE_TYPE (name));
bool changed = false;
r.set_undefined ();
for (unsigned i = 0; i < EDGE_COUNT (entry->preds); ++i)
@@ -190,9 +190,9 @@ path_range_query::range_on_path_entry (irange &r, tree name)
// Return the range of NAME at the end of the path being analyzed.
bool
-path_range_query::internal_range_of_expr (irange &r, tree name, gimple *stmt)
+path_range_query::internal_range_of_expr (vrange &r, tree name, gimple *stmt)
{
- if (!irange::supports_type_p (TREE_TYPE (name)))
+ if (!vrange::supports_type_p (TREE_TYPE (name)))
return false;
if (get_cache (r, name))
@@ -209,18 +209,22 @@ path_range_query::internal_range_of_expr (irange &r, tree name, gimple *stmt)
&& range_defined_in_block (r, name, gimple_bb (stmt)))
{
if (TREE_CODE (name) == SSA_NAME)
- r.intersect (gimple_range_global (name));
+ {
+ Value_Range glob (TREE_TYPE (name));
+ gimple_range_global (glob, name);
+ r.intersect (glob);
+ }
set_cache (r, name);
return true;
}
- r = gimple_range_global (name);
+ gimple_range_global (r, name);
return true;
}
bool
-path_range_query::range_of_expr (irange &r, tree name, gimple *stmt)
+path_range_query::range_of_expr (vrange &r, tree name, gimple *stmt)
{
if (internal_range_of_expr (r, name, stmt))
{
@@ -269,7 +273,7 @@ path_range_query::ssa_defined_in_bb (tree name, basic_block bb)
// calculating the PHI's range must not trigger additional lookups.
void
-path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
+path_range_query::ssa_range_in_phi (vrange &r, gphi *phi)
{
tree name = gimple_phi_result (phi);
basic_block bb = gimple_bb (phi);
@@ -283,7 +287,7 @@ path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
// Try to fold the phi exclusively with global or cached values.
// This will get things like PHI <5(99), 6(88)>. We do this by
// calling range_of_expr with no context.
- int_range_max arg_range;
+ Value_Range arg_range (TREE_TYPE (name));
r.set_undefined ();
for (size_t i = 0; i < nargs; ++i)
{
@@ -312,7 +316,7 @@ path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
{
if (m_resolve)
{
- int_range_max tmp;
+ Value_Range tmp (TREE_TYPE (name));
// Using both the range on entry to the path, and the
// range on this edge yields significantly better
// results.
@@ -335,7 +339,7 @@ path_range_query::ssa_range_in_phi (irange &r, gphi *phi)
// TRUE. Otherwise, return FALSE.
bool
-path_range_query::range_defined_in_block (irange &r, tree name, basic_block bb)
+path_range_query::range_defined_in_block (vrange &r, tree name, basic_block bb)
{
gimple *def_stmt = SSA_NAME_DEF_STMT (name);
basic_block def_bb = gimple_bb (def_stmt);
@@ -377,7 +381,6 @@ path_range_query::range_defined_in_block (irange &r, tree name, basic_block bb)
void
path_range_query::compute_ranges_in_phis (basic_block bb)
{
- int_range_max r;
auto_bitmap phi_set;
// PHIs must be resolved simultaneously on entry to the block
@@ -390,7 +393,11 @@ path_range_query::compute_ranges_in_phis (basic_block bb)
gphi *phi = iter.phi ();
tree name = gimple_phi_result (phi);
- if (import_p (name) && range_defined_in_block (r, name, bb))
+ if (!import_p (name))
+ continue;
+
+ Value_Range r (TREE_TYPE (name));
+ if (range_defined_in_block (r, name, bb))
{
unsigned v = SSA_NAME_VERSION (name);
set_cache (r, name);
@@ -423,7 +430,6 @@ void
path_range_query::compute_ranges_in_block (basic_block bb)
{
bitmap_iterator bi;
- int_range_max r, cached_range;
unsigned i;
if (m_resolve && !at_entry ())
@@ -444,6 +450,7 @@ path_range_query::compute_ranges_in_block (basic_block bb)
EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
{
tree name = ssa_name (i);
+ Value_Range r (TREE_TYPE (name));
if (gimple_code (SSA_NAME_DEF_STMT (name)) != GIMPLE_PHI
&& range_defined_in_block (r, name, bb))
@@ -480,8 +487,10 @@ path_range_query::compute_ranges_in_block (basic_block bb)
if (bitmap_bit_p (exports, i))
{
+ Value_Range r (TREE_TYPE (name));
if (g.outgoing_edge_range_p (r, e, name, *this))
{
+ Value_Range cached_range (TREE_TYPE (name));
if (get_cache (cached_range, name))
r.intersect (cached_range);
@@ -539,7 +548,7 @@ bool
path_range_query::add_to_imports (tree name, bitmap imports)
{
if (TREE_CODE (name) == SSA_NAME
- && irange::supports_type_p (TREE_TYPE (name)))
+ && vrange::supports_type_p (TREE_TYPE (name)))
return bitmap_set_bit (imports, SSA_NAME_VERSION (name));
return false;
}
@@ -751,11 +760,11 @@ jt_fur_source::query_relation (tree op1, tree op2)
// Return the range of STMT at the end of the path being analyzed.
bool
-path_range_query::range_of_stmt (irange &r, gimple *stmt, tree)
+path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree)
{
tree type = gimple_range_type (stmt);
- if (!type || !irange::supports_type_p (type))
+ if (!type || !vrange::supports_type_p (type))
return false;
// If resolving unknowns, fold the statement making use of any
diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h
index 914983bb0aa..2c4624e4cef 100644
--- a/gcc/gimple-range-path.h
+++ b/gcc/gimple-range-path.h
@@ -38,29 +38,29 @@ public:
const bitmap_head *imports = NULL);
void compute_ranges (edge e);
void compute_imports (bitmap imports, basic_block exit);
- bool range_of_expr (irange &r, tree name, gimple * = NULL) override;
- bool range_of_stmt (irange &r, gimple *, tree name = NULL) override;
+ bool range_of_expr (vrange &r, tree name, gimple * = NULL) override;
+ bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override;
bool unreachable_path_p ();
void dump (FILE *) override;
void debug ();
private:
- bool internal_range_of_expr (irange &r, tree name, gimple *);
+ bool internal_range_of_expr (vrange &r, tree name, gimple *);
bool defined_outside_path (tree name);
- void range_on_path_entry (irange &r, tree name);
+ void range_on_path_entry (vrange &r, tree name);
path_oracle *get_path_oracle () { return (path_oracle *)m_oracle; }
// Cache manipulation.
- void set_cache (const irange &r, tree name);
- bool get_cache (irange &r, tree name);
+ void set_cache (const vrange &r, tree name);
+ bool get_cache (vrange &r, tree name);
void clear_cache (tree name);
// Methods to compute ranges for the given path.
- bool range_defined_in_block (irange &, tree name, basic_block bb);
+ bool range_defined_in_block (vrange &, tree name, basic_block bb);
void compute_ranges_in_block (basic_block bb);
void compute_ranges_in_phis (basic_block bb);
void adjust_for_non_null_uses (basic_block bb);
- void ssa_range_in_phi (irange &r, gphi *phi);
+ void ssa_range_in_phi (vrange &r, gphi *phi);
void compute_outgoing_relations (basic_block bb, basic_block next);
void compute_phi_relations (basic_block bb, basic_block prev);
void maybe_register_phi_relation (gphi *, edge e);
diff --git a/gcc/gimple-range-tests.cc b/gcc/gimple-range-tests.cc
index 572acd33d7f..84ecc486889 100644
--- a/gcc/gimple-range-tests.cc
+++ b/gcc/gimple-range-tests.cc
@@ -42,8 +42,9 @@ public:
ASSERT_TRUE (r == expect);
}
- virtual bool range_of_expr (irange &r, tree expr, gimple * = NULL) override
+ virtual bool range_of_expr (vrange &v, tree expr, gimple * = NULL) override
{
+ irange &r = as_a <irange> (v);
if (expr == op0)
{
r.set (build_int_cst (type, 5), build_int_cst (type, 10));
diff --git a/gcc/gimple-range-trace.cc b/gcc/gimple-range-trace.cc
index 39971093e6d..46827f9c580 100644
--- a/gcc/gimple-range-trace.cc
+++ b/gcc/gimple-range-trace.cc
@@ -102,7 +102,7 @@ range_tracer::print (unsigned counter, const char *str)
void
range_tracer::trailer (unsigned counter, const char *caller, bool result,
- tree name, const irange &r)
+ tree name, const vrange &r)
{
gcc_checking_assert (tracing && counter != 0);
@@ -141,7 +141,6 @@ debug_seed_ranger (gimple_ranger &ranger)
}
basic_block bb;
- int_range_max r;
gimple_stmt_iterator gsi;
FOR_EACH_BB_FN (bb, cfun)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -151,7 +150,11 @@ debug_seed_ranger (gimple_ranger &ranger)
if (is_gimple_debug (stmt))
continue;
- ranger.range_of_stmt (r, stmt);
+ if (tree type = gimple_range_type (stmt))
+ {
+ Value_Range r (type);
+ ranger.range_of_stmt (r, stmt);
+ }
}
}
diff --git a/gcc/gimple-range-trace.h b/gcc/gimple-range-trace.h
index 302afda3104..3f92e51803b 100644
--- a/gcc/gimple-range-trace.h
+++ b/gcc/gimple-range-trace.h
@@ -32,7 +32,7 @@ public:
range_tracer (const char *name = "");
unsigned header (const char *str);
void trailer (unsigned counter, const char *caller, bool result, tree name,
- const irange &r);
+ const vrange &r);
void print (unsigned counter, const char *str);
inline void enable_trace () { tracing = true; }
inline void disable_trace () { tracing = false; }
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 0a99787fc75..12da16841c2 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -71,7 +71,7 @@ gimple_ranger::~gimple_ranger ()
}
bool
-gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
+gimple_ranger::range_of_expr (vrange &r, tree expr, gimple *stmt)
{
unsigned idx;
if (!gimple_range_ssa_p (expr))
@@ -93,7 +93,7 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
// If there is no statement, just get the global value.
if (!stmt)
{
- int_range_max tmp;
+ Value_Range tmp (TREE_TYPE (expr));
m_cache.get_global_range (r, expr);
// Pick up implied context information from the on-entry cache
// if current_bb is set. Do not attempt any new calculations.
@@ -137,9 +137,9 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt)
// Return the range of NAME on entry to block BB in R.
void
-gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name)
+gimple_ranger::range_on_entry (vrange &r, basic_block bb, tree name)
{
- int_range_max entry_range;
+ Value_Range entry_range (TREE_TYPE (name));
gcc_checking_assert (gimple_range_ssa_p (name));
unsigned idx;
@@ -164,7 +164,7 @@ gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name)
// Return false if no range can be calculated.
void
-gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name)
+gimple_ranger::range_on_exit (vrange &r, basic_block bb, tree name)
{
// on-exit from the exit block?
gcc_checking_assert (bb != EXIT_BLOCK_PTR_FOR_FN (cfun));
@@ -198,10 +198,10 @@ gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name)
// Calculate a range for NAME on edge E and return it in R.
bool
-gimple_ranger::range_on_edge (irange &r, edge e, tree name)
+gimple_ranger::range_on_edge (vrange &r, edge e, tree name)
{
- int_range_max edge_range;
- gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
+ Value_Range edge_range (TREE_TYPE (name));
+ gcc_checking_assert (vrange::supports_type_p (TREE_TYPE (name)));
// Do not process values along abnormal edges.
if (e->flags & EDGE_ABNORMAL)
@@ -249,7 +249,7 @@ gimple_ranger::range_on_edge (irange &r, edge e, tree name)
// fold_range wrapper for range_of_stmt to use as an internal client.
bool
-gimple_ranger::fold_range_internal (irange &r, gimple *s, tree name)
+gimple_ranger::fold_range_internal (vrange &r, gimple *s, tree name)
{
fold_using_range f;
fur_depend src (s, &(gori ()), this);
@@ -263,7 +263,7 @@ gimple_ranger::fold_range_internal (irange &r, gimple *s, tree name)
// avoided. If a range cannot be calculated, return false and UNDEFINED.
bool
-gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
+gimple_ranger::range_of_stmt (vrange &r, gimple *s, tree name)
{
bool res;
r.set_undefined ();
@@ -313,7 +313,7 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
prefill_stmt_dependencies (name);
// Calculate a new value.
- int_range_max tmp;
+ Value_Range tmp (TREE_TYPE (name));
fold_range_internal (tmp, s, name);
// Combine the new value with the old value. This is required because
@@ -334,7 +334,7 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
// stack if so. R is a scratch range.
inline void
-gimple_ranger::prefill_name (irange &r, tree name)
+gimple_ranger::prefill_name (vrange &r, tree name)
{
if (!gimple_range_ssa_p (name))
return;
@@ -357,7 +357,6 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
if (SSA_NAME_IS_DEFAULT_DEF (ssa))
return;
- int_range_max r;
unsigned idx;
gimple *stmt = SSA_NAME_DEF_STMT (ssa);
gcc_checking_assert (stmt && gimple_bb (stmt));
@@ -388,9 +387,10 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
{
// Fold and save the value for NAME.
stmt = SSA_NAME_DEF_STMT (name);
+ Value_Range r (TREE_TYPE (name));
fold_range_internal (r, stmt, name);
// Make sure we don't lose any current global info.
- int_range_max tmp;
+ Value_Range tmp (TREE_TYPE (name));
m_cache.get_global_range (tmp, name);
r.intersect (tmp);
m_cache.set_global_range (name, r);
@@ -414,6 +414,7 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
gphi *phi = dyn_cast <gphi *> (stmt);
if (phi)
{
+ Value_Range r (TREE_TYPE (gimple_phi_result (phi)));
for (unsigned x = 0; x < gimple_phi_num_args (phi); x++)
prefill_name (r, gimple_phi_arg_def (phi, x));
}
@@ -421,6 +422,7 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
{
gcc_checking_assert (range_op_handler (stmt));
tree op = gimple_range_operand2 (stmt);
+ Value_Range r (TREE_TYPE (name));
if (op)
prefill_name (r, op);
op = gimple_range_operand1 (stmt);
@@ -429,7 +431,10 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
}
}
if (idx)
- tracer.trailer (idx, "ROS ", false, ssa, r);
+ {
+ unsupported_range r;
+ tracer.trailer (idx, "ROS ", false, ssa, r);
+ }
}
@@ -487,8 +492,10 @@ gimple_ranger::export_global_ranges ()
bool print_header = true;
for (unsigned x = 1; x < num_ssa_names; x++)
{
- int_range_max r;
tree name = ssa_name (x);
+ if (!name)
+ continue;
+ Value_Range r (TREE_TYPE (name));
if (name && !SSA_NAME_IN_FREE_LIST (name)
&& gimple_range_ssa_p (name)
&& m_cache.get_global_range (r, name)
@@ -507,13 +514,17 @@ gimple_ranger::export_global_ranges ()
print_header = false;
}
- value_range vr = r;
+ if (!irange::supports_type_p (TREE_TYPE (name)))
+ continue;
+
+ vrange &v = r;
+ value_range vr = as_a <irange> (v);
print_generic_expr (dump_file, name , TDF_SLIM);
fprintf (dump_file, " : ");
vr.dump (dump_file);
fprintf (dump_file, "\n");
int_range_max same = vr;
- if (same != r)
+ if (same != as_a <irange> (v))
{
fprintf (dump_file, " irange : ");
r.dump (dump_file);
@@ -531,7 +542,6 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb)
unsigned x;
edge_iterator ei;
edge e;
- int_range_max range, tmp_range;
fprintf (f, "\n=========== BB %d ============\n", bb->index);
m_cache.dump_bb (f, bb);
@@ -541,9 +551,11 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb)
for (x = 1; x < num_ssa_names; x++)
{
tree name = ssa_name (x);
- if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) &&
- gimple_bb (SSA_NAME_DEF_STMT (name)) == bb &&
- m_cache.get_global_range (range, name))
+ if (!gimple_range_ssa_p (name) || !SSA_NAME_DEF_STMT (name))
+ continue;
+ Value_Range range (TREE_TYPE (name));
+ if (gimple_bb (SSA_NAME_DEF_STMT (name)) == bb
+ && m_cache.get_global_range (range, name))
{
if (!range.varying_p ())
{
@@ -562,10 +574,14 @@ gimple_ranger::dump_bb (FILE *f, basic_block bb)
for (x = 1; x < num_ssa_names; x++)
{
tree name = gimple_range_ssa_p (ssa_name (x));
- if (name && gori ().has_edge_range_p (name, e)
- && m_cache.range_on_edge (range, e, name))
+ if (!name || !gori ().has_edge_range_p (name, e))
+ continue;
+
+ Value_Range range (TREE_TYPE (name));
+ if (m_cache.range_on_edge (range, e, name))
{
gimple *s = SSA_NAME_DEF_STMT (name);
+ Value_Range tmp_range (TREE_TYPE (name));
// Only print the range if this is the def block, or
// the on entry cache for either end of the edge is
// set.
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index c67280dc1d2..34f61025ac3 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -48,11 +48,11 @@ class gimple_ranger : public range_query
public:
gimple_ranger (bool use_imm_uses = true);
~gimple_ranger ();
- virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL) override;
- virtual bool range_of_expr (irange &r, tree name, gimple * = NULL) override;
- virtual bool range_on_edge (irange &r, edge e, tree name) override;
- void range_on_entry (irange &r, basic_block bb, tree name);
- void range_on_exit (irange &r, basic_block bb, tree name);
+ virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override;
+ virtual bool range_of_expr (vrange &r, tree name, gimple * = NULL) override;
+ virtual bool range_on_edge (vrange &r, edge e, tree name) override;
+ void range_on_entry (vrange &r, basic_block bb, tree name);
+ void range_on_exit (vrange &r, basic_block bb, tree name);
void export_global_ranges ();
inline gori_compute &gori () { return m_cache.m_gori; }
virtual void dump (FILE *f) override;
@@ -62,8 +62,8 @@ public:
bool fold_stmt (gimple_stmt_iterator *gsi, tree (*) (tree));
void register_inferred_ranges (gimple *s);
protected:
- bool fold_range_internal (irange &r, gimple *s, tree name);
- void prefill_name (irange &r, tree name);
+ bool fold_range_internal (vrange &r, gimple *s, tree name);
+ void prefill_name (vrange &r, tree name);
void prefill_stmt_dependencies (tree ssa);
ranger_cache m_cache;
range_tracer tracer;
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 9357a4e576a..00f65858b0c 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -328,11 +328,11 @@ check_nul_terminated_array (GimpleOrTree expr, tree src, tree bound)
wide_int bndrng[2];
if (bound)
{
- value_range r;
+ Value_Range r (TREE_TYPE (bound));
get_global_range_query ()->range_of_expr (r, bound);
- if (r.kind () != VR_RANGE)
+ if (r.undefined_p () || r.varying_p ())
return true;
bndrng[0] = r.lower_bound ();
@@ -2790,9 +2790,8 @@ memmodel_to_uhwi (tree ord, gimple *stmt, unsigned HOST_WIDE_INT *cstval)
{
/* Use the range query to determine constant values in the absence
of constant propagation (such as at -O0). */
- value_range rng;
+ Value_Range rng (TREE_TYPE (ord));
if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt)
- || !rng.constant_p ()
|| !rng.singleton_p (&ord))
return false;
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index afa51064953..1e0f609d8b6 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -221,7 +221,7 @@ refine_value_range_using_guard (tree type, tree var,
get_type_static_bounds (type, mint, maxt);
mpz_init (minc1);
mpz_init (maxc1);
- value_range r;
+ Value_Range r (TREE_TYPE (varc1));
/* Setup range information for varc1. */
if (integer_zerop (varc1))
{
@@ -374,7 +374,7 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
gphi_iterator gsi;
/* Either for VAR itself... */
- value_range var_range;
+ Value_Range var_range (TREE_TYPE (var));
get_range_query (cfun)->range_of_expr (var_range, var);
rtype = var_range.kind ();
if (!var_range.undefined_p ())
@@ -385,10 +385,10 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
/* Or for PHI results in loop->header where VAR is used as
PHI argument from the loop preheader edge. */
+ Value_Range phi_range (TREE_TYPE (var));
for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
{
gphi *phi = gsi.phi ();
- value_range phi_range;
if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var
&& get_range_query (cfun)->range_of_expr (phi_range,
gimple_phi_result (phi))
@@ -410,7 +410,7 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
involved. */
if (wi::gt_p (minv, maxv, sgn))
{
- value_range vr;
+ Value_Range vr (TREE_TYPE (var));
get_range_query (cfun)->range_of_expr (vr, var);
rtype = vr.kind ();
if (!vr.undefined_p ())
@@ -3650,7 +3650,7 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt,
if (tree_int_cst_sign_bit (step))
{
wide_int max;
- value_range base_range;
+ Value_Range base_range (TREE_TYPE (orig_base));
if (get_range_query (cfun)->range_of_expr (base_range, orig_base)
&& !base_range.undefined_p ())
max = base_range.upper_bound ();
@@ -3672,7 +3672,7 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt,
else
{
wide_int min;
- value_range base_range;
+ Value_Range base_range (TREE_TYPE (orig_base));
if (get_range_query (cfun)->range_of_expr (base_range, orig_base)
&& !base_range.undefined_p ())
min = base_range.lower_bound ();
@@ -3947,7 +3947,7 @@ infer_loop_bounds_from_signedness (class loop *loop, gimple *stmt)
low = lower_bound_in_type (type, type);
high = upper_bound_in_type (type, type);
- value_range r;
+ Value_Range r (TREE_TYPE (def));
get_range_query (cfun)->range_of_expr (r, def);
if (r.kind () == VR_RANGE)
{
@@ -4997,7 +4997,7 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop)
if (!def_bb || !dominated_by_p (CDI_DOMINATORS, loop->latch, def_bb))
return false;
- value_range r;
+ Value_Range r (TREE_TYPE (var));
get_range_query (cfun)->range_of_expr (r, var);
if (r.kind () != VR_RANGE)
return false;
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index a55905c2c68..ad1d05ccdff 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -140,13 +140,13 @@ struct unswitch_predicate
int_range<2> rhs_range (TREE_TYPE (rhs));
if (CONSTANT_CLASS_P (rhs))
rhs_range.set (rhs);
- if (!range_op->op1_range (true_range, TREE_TYPE (lhs),
- int_range<2> (boolean_true_node,
- boolean_true_node), rhs_range)
- || !range_op->op1_range (false_range, TREE_TYPE (lhs),
- int_range<2> (boolean_false_node,
- boolean_false_node),
- rhs_range))
+ if (!range_op.op1_range (true_range, TREE_TYPE (lhs),
+ int_range<2> (boolean_true_node,
+ boolean_true_node), rhs_range)
+ || !range_op.op1_range (false_range, TREE_TYPE (lhs),
+ int_range<2> (boolean_false_node,
+ boolean_false_node),
+ rhs_range))
{
true_range.set_varying (TREE_TYPE (lhs));
false_range.set_varying (TREE_TYPE (lhs));
diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
index 4eb65ca7cac..931aa7479bb 100644
--- a/gcc/tree-ssa-threadedge.cc
+++ b/gcc/tree-ssa-threadedge.cc
@@ -1409,19 +1409,19 @@ tree
hybrid_jt_simplifier::simplify (gimple *stmt, gimple *, basic_block,
jt_state *state)
{
- int_range_max r;
-
compute_ranges_from_state (stmt, state);
if (gimple_code (stmt) == GIMPLE_COND
|| gimple_code (stmt) == GIMPLE_ASSIGN)
{
+ Value_Range r (gimple_range_type (stmt));
tree ret;
if (m_query->range_of_stmt (r, stmt) && r.singleton_p (&ret))
return ret;
}
else if (gimple_code (stmt) == GIMPLE_SWITCH)
{
+ int_range_max r;
gswitch *switch_stmt = dyn_cast <gswitch *> (stmt);
tree index = gimple_switch_index (switch_stmt);
if (m_query->range_of_expr (r, index, stmt))
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 31e56eeae53..e40e358ebd4 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -57,13 +57,13 @@ value_query::value_of_stmt (gimple *stmt, tree name)
// range_query default methods.
bool
-range_query::range_on_edge (irange &r, edge, tree expr)
+range_query::range_on_edge (vrange &r, edge, tree expr)
{
return range_of_expr (r, expr);
}
bool
-range_query::range_of_stmt (irange &r, gimple *stmt, tree name)
+range_query::range_of_stmt (vrange &r, gimple *stmt, tree name)
{
if (!name)
name = gimple_get_lhs (stmt);
@@ -79,11 +79,12 @@ tree
range_query::value_of_expr (tree expr, gimple *stmt)
{
tree t;
- int_range_max r;
- if (!irange::supports_type_p (TREE_TYPE (expr)))
+ if (!vrange::supports_type_p (TREE_TYPE (expr)))
return NULL_TREE;
+ Value_Range r (TREE_TYPE (expr));
+
if (range_of_expr (r, expr, stmt))
{
// A constant used in an unreachable block oftens returns as UNDEFINED.
@@ -100,10 +101,10 @@ tree
range_query::value_on_edge (edge e, tree expr)
{
tree t;
- int_range_max r;
- if (!irange::supports_type_p (TREE_TYPE (expr)))
+ if (!vrange::supports_type_p (TREE_TYPE (expr)))
return NULL_TREE;
+ Value_Range r (TREE_TYPE (expr));
if (range_on_edge (r, e, expr))
{
// A constant used in an unreachable block oftens returns as UNDEFINED.
@@ -121,15 +122,15 @@ tree
range_query::value_of_stmt (gimple *stmt, tree name)
{
tree t;
- int_range_max r;
if (!name)
name = gimple_get_lhs (stmt);
gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
- if (!name || !irange::supports_type_p (TREE_TYPE (name)))
+ if (!name || !vrange::supports_type_p (TREE_TYPE (name)))
return NULL_TREE;
+ Value_Range r (TREE_TYPE (name));
if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
return t;
return NULL_TREE;
@@ -187,7 +188,7 @@ range_query::~range_query ()
// representable, and UNDEFINED/false if not.
bool
-range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
+range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
{
tree type;
if (TYPE_P (expr))
@@ -195,7 +196,7 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
else
type = TREE_TYPE (expr);
- if (!irange::supports_type_p (type))
+ if (!vrange::supports_type_p (type))
{
r.set_undefined ();
return false;
@@ -214,7 +215,7 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
return true;
case SSA_NAME:
- r = gimple_range_global (expr);
+ gimple_range_global (r, expr);
return true;
case ADDR_EXPR:
@@ -223,7 +224,7 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
bool ov;
if (tree_single_nonzero_warnv_p (expr, &ov))
{
- r = range_nonzero (type);
+ r.set_nonzero (type);
return true;
}
break;
@@ -237,7 +238,8 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
range_op_handler op (TREE_CODE (expr), type);
if (op)
{
- int_range_max r0, r1;
+ Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ Value_Range r1 (TREE_TYPE (TREE_OPERAND (expr, 1)));
range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
range_of_expr (r1, TREE_OPERAND (expr, 1), stmt);
op.fold_range (r, type, r0, r1);
@@ -250,11 +252,13 @@ range_query::get_tree_range (irange &r, tree expr, gimple *stmt)
{
range_op_handler op (TREE_CODE (expr), type);
tree op0_type = TREE_TYPE (TREE_OPERAND (expr, 0));
- if (op && irange::supports_type_p (op0_type))
+ if (op && vrange::supports_type_p (op0_type))
{
- int_range_max r0;
+ Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ Value_Range r1 (type);
+ r1.set_varying (type);
range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
- op.fold_range (r, type, r0, int_range<1> (type));
+ op.fold_range (r, type, r0, r1);
}
else
r.set_varying (type);
@@ -311,7 +315,7 @@ get_ssa_name_ptr_info_nonnull (const_tree name)
// updated.
bool
-update_global_range (irange &r, tree name)
+update_global_range (vrange &r, tree name)
{
tree type = TREE_TYPE (name);
@@ -330,8 +334,7 @@ update_global_range (irange &r, tree name)
if (r.undefined_p ())
return false;
- value_range vr = r;
- set_range_info (name, vr);
+ set_range_info (name, as_a <irange> (r));
return true;
}
else if (POINTER_TYPE_P (type))
@@ -349,7 +352,7 @@ update_global_range (irange &r, tree name)
// return VARYING.
static void
-get_range_global (irange &r, tree name)
+get_range_global (vrange &r, tree name)
{
tree type = TREE_TYPE (name);
@@ -369,7 +372,7 @@ get_range_global (irange &r, tree name)
r.set_nonzero (type);
else if (INTEGRAL_TYPE_P (type))
{
- get_ssa_name_range_info (r, name);
+ get_ssa_name_range_info (as_a <irange> (r), name);
if (r.undefined_p ())
r.set_varying (type);
}
@@ -384,7 +387,8 @@ get_range_global (irange &r, tree name)
}
else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
{
- get_ssa_name_range_info (r, name);
+ gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
+ get_ssa_name_range_info (as_a <irange> (r), name);
if (r.undefined_p ())
r.set_varying (type);
}
@@ -414,21 +418,19 @@ get_range_global (irange &r, tree name)
// See discussion here:
// https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html
-value_range
-gimple_range_global (tree name)
+void
+gimple_range_global (vrange &r, tree name)
{
tree type = TREE_TYPE (name);
- gcc_checking_assert (TREE_CODE (name) == SSA_NAME
- && irange::supports_type_p (type));
+ gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
if (SSA_NAME_IS_DEFAULT_DEF (name) || (cfun && cfun->after_inlining)
|| is_a<gphi *> (SSA_NAME_DEF_STMT (name)))
{
- value_range vr;
- get_range_global (vr, name);
- return vr;
+ get_range_global (r, name);
+ return;
}
- return value_range (type);
+ r.set_varying (type);
}
// ----------------------------------------------
@@ -437,7 +439,7 @@ gimple_range_global (tree name)
global_range_query global_ranges;
bool
-global_range_query::range_of_expr (irange &r, tree expr, gimple *stmt)
+global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
{
tree type = TREE_TYPE (expr);
@@ -456,15 +458,16 @@ global_range_query::range_of_expr (irange &r, tree expr, gimple *stmt)
relation_kind
range_query::query_relation (gimple *s, tree ssa1, tree ssa2, bool get_range)
{
- int_range_max tmp;
if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME)
return VREL_VARYING;
// Ensure ssa1 and ssa2 have both been evaluated.
if (get_range)
{
- range_of_expr (tmp, ssa1, s);
- range_of_expr (tmp, ssa2, s);
+ Value_Range tmp1 (TREE_TYPE (ssa1));
+ Value_Range tmp2 (TREE_TYPE (ssa2));
+ range_of_expr (tmp1, ssa1, s);
+ range_of_expr (tmp2, ssa2, s);
}
return m_oracle->query_relation (gimple_bb (s), ssa1, ssa2);
}
@@ -477,7 +480,6 @@ relation_kind
range_query::query_relation (edge e, tree ssa1, tree ssa2, bool get_range)
{
basic_block bb;
- int_range_max tmp;
if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME)
return VREL_VARYING;
@@ -492,6 +494,7 @@ range_query::query_relation (edge e, tree ssa1, tree ssa2, bool get_range)
// Ensure ssa1 and ssa2 have both been evaluated.
if (get_range)
{
+ Value_Range tmp (TREE_TYPE (ssa1));
range_on_edge (tmp, e, ssa1);
range_on_edge (tmp, e, ssa2);
}
diff --git a/gcc/value-query.h b/gcc/value-query.h
index cf1a1d74de3..280e47e3f6b 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -89,9 +89,9 @@ public:
//
// Note that range_of_expr must always return TRUE unless ranges are
// unsupported for EXPR's type (supports_type_p is false).
- virtual bool range_of_expr (irange &r, tree expr, gimple * = NULL) = 0;
- virtual bool range_on_edge (irange &r, edge, tree expr);
- virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL);
+ virtual bool range_of_expr (vrange &r, tree expr, gimple * = NULL) = 0;
+ virtual bool range_on_edge (vrange &r, edge, tree expr);
+ virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL);
// Query if there is any relation between SSA1 and SSA2.
relation_kind query_relation (gimple *s, tree ssa1, tree ssa2,
@@ -110,8 +110,8 @@ public:
protected:
class value_range_equiv *allocate_value_range_equiv ();
void free_value_range_equiv (class value_range_equiv *);
- bool get_tree_range (irange &r, tree expr, gimple *stmt);
- bool get_arith_expr_range (irange &r, tree expr, gimple *stmt);
+ bool get_tree_range (vrange &v, tree expr, gimple *stmt);
+ bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt);
relation_oracle *m_oracle;
private:
@@ -123,7 +123,7 @@ private:
class global_range_query : public range_query
{
public:
- bool range_of_expr (irange &r, tree expr, gimple * = NULL) override;
+ bool range_of_expr (vrange &r, tree expr, gimple * = NULL) override;
};
extern global_range_query global_ranges;
@@ -143,7 +143,7 @@ get_range_query (const struct function *fun)
return fun->x_range_query ? fun->x_range_query : &global_ranges;
}
-extern value_range gimple_range_global (tree name);
-extern bool update_global_range (irange &r, tree name);
+extern void gimple_range_global (vrange &v, tree name);
+extern bool update_global_range (vrange &v, tree name);
#endif // GCC_QUERY_H
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 6f8583c8d01..38f204e2f5d 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -177,7 +177,7 @@ vr_values::get_value_range (const_tree var,
}
bool
-vr_values::range_of_expr (irange &r, tree expr, gimple *stmt)
+vr_values::range_of_expr (vrange &r, tree expr, gimple *stmt)
{
if (!gimple_range_ssa_p (expr))
return get_tree_range (r, expr, stmt);
@@ -1630,6 +1630,20 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
gcc_unreachable ();
}
+static inline void
+fix_overflow (tree *min, tree *max)
+{
+ /* Even for valid range info, sometimes overflow flag will leak in.
+ As GIMPLE IL should have no constants with TREE_OVERFLOW set, we
+ drop them. */
+ if (TREE_OVERFLOW_P (*min))
+ *min = drop_tree_overflow (*min);
+ if (TREE_OVERFLOW_P (*max))
+ *max = drop_tree_overflow (*max);
+
+ gcc_checking_assert (compare_values (*min, *max) != 1);
+}
+
/* Given a VAR in STMT within LOOP, determine the bounds of the
variable and store it in MIN/MAX and return TRUE. If no bounds
could be determined, return FALSE. */
@@ -1640,6 +1654,7 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
{
tree init, step, chrec, tmin, tmax, type = TREE_TYPE (var);
enum ev_direction dir;
+ int_range<2> r;
chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
@@ -1647,7 +1662,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
if (is_gimple_min_invariant (chrec))
{
*min = *max = chrec;
- goto fix_overflow;
+ fix_overflow (min, max);
+ return true;
}
if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
@@ -1659,13 +1675,17 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
if (!init || !step)
return false;
+ Value_Range rinit (TREE_TYPE (init));
+ Value_Range rstep (TREE_TYPE (step));
/* If INIT is an SSA with a singleton range, set INIT to said
singleton, otherwise leave INIT alone. */
- if (TREE_CODE (init) == SSA_NAME)
- query->get_value_range (init, stmt)->singleton_p (&init);
+ if (TREE_CODE (init) == SSA_NAME
+ && query->range_of_expr (rinit, init, stmt))
+ rinit.singleton_p (&init);
/* Likewise for step. */
- if (TREE_CODE (step) == SSA_NAME)
- query->get_value_range (step, stmt)->singleton_p (&step);
+ if (TREE_CODE (step) == SSA_NAME
+ && query->range_of_expr (rstep, step, stmt))
+ rstep.singleton_p (&step);
/* If STEP is symbolic, we can't know whether INIT will be the
minimum or maximum value in the range. Also, unless INIT is
@@ -1699,7 +1719,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
if (TREE_CODE (step) == INTEGER_CST
&& is_gimple_val (init)
&& (TREE_CODE (init) != SSA_NAME
- || query->get_value_range (init, stmt)->kind () == VR_RANGE))
+ || (query->range_of_expr (r, init, stmt)
+ && r.kind () == VR_RANGE)))
{
widest_int nit;
@@ -1724,7 +1745,7 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
{
value_range maxvr, vr0, vr1;
if (TREE_CODE (init) == SSA_NAME)
- vr0 = *(query->get_value_range (init, stmt));
+ query->range_of_expr (vr0, init, stmt);
else if (is_gimple_min_invariant (init))
vr0.set (init);
else
@@ -1737,10 +1758,10 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
/* Likewise if the addition did. */
if (maxvr.kind () == VR_RANGE)
{
- value_range initvr;
+ int_range<2> initvr;
if (TREE_CODE (init) == SSA_NAME)
- initvr = *(query->get_value_range (init, stmt));
+ query->range_of_expr (initvr, init, stmt);
else if (is_gimple_min_invariant (init))
initvr.set (init);
else
@@ -1770,16 +1791,7 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
else
*min = init;
- fix_overflow:
- /* Even for valid range info, sometimes overflow flag will leak in.
- As GIMPLE IL should have no constants with TREE_OVERFLOW set, we
- drop them. */
- if (TREE_OVERFLOW_P (*min))
- *min = drop_tree_overflow (*min);
- if (TREE_OVERFLOW_P (*max))
- *max = drop_tree_overflow (*max);
-
- gcc_checking_assert (compare_values (*min, *max) != 1);
+ fix_overflow (min, max);
return true;
}
@@ -2446,7 +2458,9 @@ simplify_using_ranges::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
fprintf (dump_file, "\t");
print_generic_expr (dump_file, use);
fprintf (dump_file, ": ");
- dump_value_range (dump_file, query->get_value_range (use, stmt));
+ Value_Range r (TREE_TYPE (use));
+ query->range_of_expr (r, use, stmt);
+ r.dump (dump_file);
}
fprintf (dump_file, "\n");
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 7a377cebd01..f018d0dfc4b 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -109,7 +109,7 @@ class vr_values : public range_query
vr_values (void);
~vr_values (void);
- virtual bool range_of_expr (irange &r, tree expr, gimple *stmt) override;
+ virtual bool range_of_expr (vrange &r, tree expr, gimple *stmt) override;
virtual tree value_of_expr (tree, gimple * = NULL) override;
virtual tree value_on_edge (edge, tree) override;
virtual tree value_of_stmt (gimple *, tree = NULL_TREE) override;
--
2.36.1
next prev parent reply other threads:[~2022-06-01 9:05 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-30 13:27 [PATCH 1/5] Implement abstract vrange class Aldy Hernandez
2022-05-30 13:27 ` [PATCH 2/5] Implement generic range temporaries Aldy Hernandez
2022-05-30 14:56 ` Andrew MacLeod
2022-05-31 6:21 ` Aldy Hernandez
2022-05-31 16:40 ` Andrew MacLeod
2022-06-01 9:01 ` Aldy Hernandez
2022-05-30 13:27 ` [PATCH 3/5] Convert range-op.* to vrange Aldy Hernandez
2022-06-01 9:01 ` Aldy Hernandez
2022-05-30 13:27 ` [PATCH 4/5] Revamp irange_allocator to handle vranges Aldy Hernandez
2022-06-01 9:02 ` Aldy Hernandez
2022-05-30 13:27 ` [PATCH 5/5] Convert ranger and clients to vrange Aldy Hernandez
2022-06-01 9:04 ` Aldy Hernandez [this message]
2022-06-27 0:33 ` Xi Ruoyao
2022-06-01 8:57 ` [PATCH 1/5] Implement abstract vrange class Aldy Hernandez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAGm3qMXkb8YnG1SU0Xwh_a5cBa2kB3Aa6nKck9OrsVtOhmYCKQ@mail.gmail.com \
--to=aldyh@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).