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 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 > - (allocator->alloc (m_tab_size * sizeof (irange *))); > - memset (m_tab, 0, m_tab_size * sizeof (irange *)); > + m_tab = static_cast > + (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 > - (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 > + (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 (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 (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 (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 m_tab; > + vec 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 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 (s)); > - gswitch *sw = as_a (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 (s)); > gswitch *sw = as_a (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 (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 *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 (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 (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 (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 (s), r, e0, e1); > + src.register_outgoing_edges (as_a (s), > + as_a (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 (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 (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 (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 (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 (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 (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 m_on_exit; > - const irange &get_nonzero (tree name); > - vec m_nonzero; > + const vrange &get_nonzero (tree name); > + vec 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 (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 (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 (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 (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 (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 (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 (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 (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 >