From: Aldy Hernandez Date: Thu, 17 Sep 2020 07:34:29 +0000 (+0200) Subject: Convert vr-values to value query class. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a889e06ac68;p=gcc.git Convert vr-values to value query class. gcc/ChangeLog: * gimple-loop-versioning.cc (lv_dom_walker::before_dom_children): Pass m_range_analyzer instead of get_vr_values. (loop_versioning::name_prop::get_value): Rename to... (loop_versioning::name_prop::value_of_expr): ...this. * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer): Adjust for evrp_range_analyzer inheriting from vr_values. (evrp_range_analyzer::try_find_new_range): Same. (evrp_range_analyzer::record_ranges_from_incoming_edge): Same. (evrp_range_analyzer::record_ranges_from_phis): Same. (evrp_range_analyzer::record_ranges_from_stmt): Same. (evrp_range_analyzer::push_value_range): Same. (evrp_range_analyzer::pop_value_range): Same. * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Inherit from vr_values. Adjust accordingly. * gimple-ssa-evrp.c: Adjust for evrp_range_analyzer inheriting from vr_values. (evrp_folder::value_of_evrp): Rename from get_value. * tree-ssa-ccp.c (class ccp_folder): Rename get_value to value_of_expr. (ccp_folder::get_value): Rename to... (ccp_folder::value_of_expr): ...this. * tree-ssa-copy.c (class copy_folder): Rename get_value to value_of_expr. (copy_folder::get_value): Rename to... (copy_folder::value_of_expr): ...this. * tree-ssa-dom.c (dom_opt_dom_walker::after_dom_children): Adjust for evrp_range_analyzer inheriting from vr_values. (dom_opt_dom_walker::optimize_stmt): Same. * tree-ssa-propagate.c (substitute_and_fold_engine::replace_uses_in): Call value_of_* instead of get_value. (substitute_and_fold_engine::replace_phi_args_in): Same. (substitute_and_fold_engine::propagate_into_phi_args): Same. (substitute_and_fold_dom_walker::before_dom_children): Same. * tree-ssa-propagate.h: Include value-query.h. (class substitute_and_fold_engine): Inherit from value_query. * tree-ssa-strlen.c (strlen_dom_walker::before_dom_children): Adjust for evrp_range_analyzer inheriting from vr_values. * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis): Same. * tree-vrp.c (class vrp_folder): Same. (vrp_folder::get_value): Rename to value_of_expr. * vr-values.c (vr_values::get_lattice_entry): Adjust for vr_values inheriting from range_query. (vr_values::range_of_expr): New. (vr_values::value_of_expr): New. (vr_values::value_on_edge): New. (vr_values::value_of_stmt): New. (simplify_using_ranges::op_with_boolean_value_range_p): Call get_value_range through query. (check_for_binary_op_overflow): Rename store to query. (vr_values::vr_values): Remove vrp_value_range_pool. (vr_values::~vr_values): Same. (simplify_using_ranges::get_vr_for_comparison): Call get_value_range through query. (simplify_using_ranges::compare_names): Same. (simplify_using_ranges::vrp_evaluate_conditional): Same. (simplify_using_ranges::vrp_visit_cond_stmt): Same. (simplify_using_ranges::simplify_abs_using_ranges): Same. (simplify_using_ranges::simplify_cond_using_ranges_1): Same. (simplify_cond_using_ranges_2): Same. (simplify_using_ranges::simplify_switch_using_ranges): Same. (simplify_using_ranges::two_valued_val_range_p): Same. (simplify_using_ranges::simplify_using_ranges): Rename store to query. (simplify_using_ranges::simplify): Assert that we have a query. * vr-values.h (class range_query): Remove. (class simplify_using_ranges): Remove inheritance of range_query. (class vr_values): Add virtuals for range_of_expr, value_of_expr, value_on_edge, value_of_stmt, and get_value_range. Call range_query allocator instead of using vrp_value_range_pool. Remove vrp_value_range_pool. (simplify_using_ranges::get_value_range): Remove. --- diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc index 2687088a908..afe353e452d 100644 --- a/gcc/gimple-loop-versioning.cc +++ b/gcc/gimple-loop-versioning.cc @@ -277,7 +277,7 @@ private: { public: name_prop (loop_info &li) : m_li (li) {} - tree get_value (tree, gimple *) FINAL OVERRIDE; + tree value_of_expr (tree name, gimple *) FINAL OVERRIDE; private: /* Information about the versioning we've performed on the loop. */ @@ -512,8 +512,7 @@ loop_versioning::lv_dom_walker::before_dom_children (basic_block bb) m_range_analyzer.enter (bb); if (bb == bb->loop_father->header) - m_lv.prune_loop_conditions (bb->loop_father, - m_range_analyzer.get_vr_values ()); + m_lv.prune_loop_conditions (bb->loop_father, &m_range_analyzer); for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) @@ -534,8 +533,7 @@ loop_versioning::lv_dom_walker::after_dom_children (basic_block bb) Return the new value if so, otherwise return null. */ tree -loop_versioning::name_prop::get_value (tree val, - gimple *stmt ATTRIBUTE_UNUSED) +loop_versioning::name_prop::value_of_expr (tree val, gimple *) { if (TREE_CODE (val) == SSA_NAME && bitmap_bit_p (&m_li.unity_names, SSA_NAME_VERSION (val))) diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c index 9f8ce5575a2..485774d3f22 100644 --- a/gcc/gimple-ssa-evrp-analyze.c +++ b/gcc/gimple-ssa-evrp-analyze.c @@ -54,7 +54,6 @@ evrp_range_analyzer::evrp_range_analyzer (bool update_global_ranges) FOR_EACH_EDGE (e, ei, bb->preds) e->flags |= EDGE_EXECUTABLE; } - vr_values = new class vr_values; } /* Push an unwinding marker onto the unwinding stack. */ @@ -87,15 +86,14 @@ evrp_range_analyzer::try_find_new_range (tree name, const value_range_equiv *old_vr = get_value_range (name); /* Discover VR when condition is true. */ - vr_values->extract_range_for_var_from_comparison_expr (name, code, op, - limit, &vr); + extract_range_for_var_from_comparison_expr (name, code, op, limit, &vr); /* If we found any usable VR, set the VR to ssa_name and create a PUSH old value in the stack with the old VR. */ if (!vr.undefined_p () && !vr.varying_p ()) { if (old_vr->equal_p (vr, /*ignore_equivs=*/true)) return NULL; - value_range_equiv *new_vr = vr_values->allocate_value_range_equiv (); + value_range_equiv *new_vr = allocate_value_range_equiv (); new_vr->move (&vr); return new_vr; } @@ -214,7 +212,7 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb) tem.intersect (vrs[i].second); if (tem.equal_p (*old_vr)) { - vr_values->free_value_range (vrs[i].second); + free_value_range (vrs[i].second); continue; } push_value_range (vrs[i].first, vrs[i].second); @@ -261,7 +259,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) value_range_equiv vr_result; bool interesting = stmt_interesting_for_vrp (phi); if (!has_unvisited_preds && interesting) - vr_values->extract_range_from_phi_node (phi, &vr_result); + extract_range_from_phi_node (phi, &vr_result); else { vr_result.set_varying (TREE_TYPE (lhs)); @@ -274,9 +272,9 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) && interesting && (l = loop_containing_stmt (phi)) && l->header == gimple_bb (phi)) - vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs); + adjust_range_with_scev (&vr_result, l, phi, lhs); } - vr_values->update_value_range (lhs, &vr_result); + update_value_range (lhs, &vr_result); /* Set the SSA with the value range. */ if (m_update_global_ranges) @@ -303,7 +301,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) { edge taken_edge; value_range_equiv vr; - vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr); + extract_range_from_stmt (stmt, &taken_edge, &output, &vr); if (output) { /* Set the SSA with the value range. There are two cases to @@ -321,7 +319,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) { /* Case one. We can just update the underlying range information as well as the global information. */ - vr_values->update_value_range (output, &vr); + update_value_range (output, &vr); if (m_update_global_ranges) set_ssa_range_info (output, &vr); } @@ -332,18 +330,17 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) a new range and push the old range onto the stack. We also have to be very careful about sharing the underlying bitmaps. Ugh. */ - value_range_equiv *new_vr - = vr_values->allocate_value_range_equiv (); + value_range_equiv *new_vr = allocate_value_range_equiv (); new_vr->set (vr.min (), vr.max (), NULL, vr.kind ()); vr.equiv_clear (); push_value_range (output, new_vr); } } else - vr_values->set_defs_to_varying (stmt); + set_defs_to_varying (stmt); } else - vr_values->set_defs_to_varying (stmt); + set_defs_to_varying (stmt); /* See if we can derive a range for any of STMT's operands. */ tree op; @@ -429,7 +426,7 @@ evrp_range_analyzer::push_value_range (tree var, value_range_equiv *vr) dump_value_range (dump_file, vr); fprintf (dump_file, "\n"); } - value_range_equiv *old_vr = vr_values->swap_vr_value (var, vr); + value_range_equiv *old_vr = swap_vr_value (var, vr); stack.safe_push (std::make_pair (var, old_vr)); } @@ -451,7 +448,7 @@ evrp_range_analyzer::pop_value_range () } /* We saved off a lattice entry, now give it back and release the one we popped. */ - value_range_equiv *popped_vr = vr_values->swap_vr_value (var, vr); + value_range_equiv *popped_vr = swap_vr_value (var, vr); if (popped_vr) - vr_values->free_value_range (popped_vr); + free_value_range (popped_vr); } diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h index 8abbbe3180d..c6d27f5c109 100644 --- a/gcc/gimple-ssa-evrp-analyze.h +++ b/gcc/gimple-ssa-evrp-analyze.h @@ -20,13 +20,12 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_GIMPLE_SSA_EVRP_ANALYZE_H #define GCC_GIMPLE_SSA_EVRP_ANALYZE_H -class evrp_range_analyzer +class evrp_range_analyzer : public vr_values { public: evrp_range_analyzer (bool update_global_ranges); ~evrp_range_analyzer (void) { - delete vr_values; stack.release (); } @@ -36,34 +35,18 @@ class evrp_range_analyzer void leave (basic_block); void record_ranges_from_stmt (gimple *, bool); - /* Main interface to retrieve range information. */ - const value_range_equiv *get_value_range (const_tree op) - { return vr_values->get_value_range (op); } - /* Record a new unwindable range. */ void push_value_range (tree var, value_range_equiv *vr); - /* Dump all the current value ranges. This is primarily - a debugging interface. */ - void dump_all_value_ranges (FILE *fp) - { vr_values->dump_all_value_ranges (fp); } - /* A bit of a wart. This should ideally go away. */ void vrp_visit_cond_stmt (gcond *cond, edge *e) { - simplify_using_ranges simpl (vr_values); + simplify_using_ranges simpl (this); simpl.vrp_visit_cond_stmt (cond, e); } - /* Get the underlying vr_values class instance. If TRANSFER is - true, then we are transferring ownership. Else we keep ownership. - - This should be converted to a unique_ptr. */ - class vr_values *get_vr_values (void) { return vr_values; } - private: DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer); - class vr_values *vr_values; void pop_value_range (); value_range_equiv *try_find_new_range (tree, tree op, tree_code code, diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index e8fde63aa34..60bf82a6805 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -45,11 +45,11 @@ along with GCC; see the file COPYING3. If not see class evrp_folder : public substitute_and_fold_engine { public: - evrp_folder () : m_range_analyzer (/*update_global_ranges=*/true), - m_vr_values (m_range_analyzer.get_vr_values ()), - simplifier (m_vr_values) - { - } + evrp_folder () : + substitute_and_fold_engine (), + m_range_analyzer (/*update_global_ranges=*/true), + simplifier (&m_range_analyzer) + { } ~evrp_folder () { @@ -61,9 +61,9 @@ public: } } - tree get_value (tree op, gimple *stmt ATTRIBUTE_UNUSED) OVERRIDE + tree value_of_expr (tree name, gimple *stmt) OVERRIDE { - return m_vr_values->op_with_constant_singleton_value_range (op); + return m_range_analyzer.value_of_expr (name, stmt); } void pre_fold_bb (basic_block bb) OVERRIDE @@ -95,14 +95,12 @@ public: void post_new_stmt (gimple *stmt) OVERRIDE { - m_range_analyzer.get_vr_values ()->set_defs_to_varying (stmt); + m_range_analyzer.set_defs_to_varying (stmt); } private: DISABLE_COPY_AND_ASSIGN (evrp_folder); - class evrp_range_analyzer m_range_analyzer; - class vr_values *m_vr_values; - + evrp_range_analyzer m_range_analyzer; simplify_using_ranges simplifier; }; diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 65dffe06530..0432fe5513d 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -946,7 +946,7 @@ do_dbg_cnt (void) class ccp_folder : public substitute_and_fold_engine { public: - tree get_value (tree, gimple *) FINAL OVERRIDE; + tree value_of_expr (tree, gimple *) FINAL OVERRIDE; bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE; }; @@ -955,7 +955,7 @@ class ccp_folder : public substitute_and_fold_engine of calling member functions. */ tree -ccp_folder::get_value (tree op, gimple *stmt ATTRIBUTE_UNUSED) +ccp_folder::value_of_expr (tree op, gimple *) { return get_constant_value (op); } diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 9bcb708379e..3d779825829 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -492,13 +492,13 @@ init_copy_prop (void) class copy_folder : public substitute_and_fold_engine { public: - tree get_value (tree, gimple *) FINAL OVERRIDE; + tree value_of_expr (tree name, gimple *) FINAL OVERRIDE; }; /* Callback for substitute_and_fold to get at the final copy-of values. */ tree -copy_folder::get_value (tree name, gimple *stmt ATTRIBUTE_UNUSED) +copy_folder::value_of_expr (tree name, gimple *) { tree val; if (SSA_NAME_VERSION (name) >= n_copy_of) diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index de5025f3879..c21bfe9f64e 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1500,7 +1500,7 @@ dom_opt_dom_walker::before_dom_children (basic_block bb) void dom_opt_dom_walker::after_dom_children (basic_block bb) { - x_vr_values = evrp_range_analyzer.get_vr_values (); + x_vr_values = &evrp_range_analyzer; thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies, m_avail_exprs_stack, &evrp_range_analyzer, @@ -1970,7 +1970,7 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si, opt_stats.num_stmts++; /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */ - cprop_into_stmt (stmt, evrp_range_analyzer.get_vr_values ()); + cprop_into_stmt (stmt, &evrp_range_analyzer); /* If the statement has been modified with constant replacements, fold its RHS before checking for redundant computations. */ diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 5a30176d3b4..87dbf55fab9 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -868,7 +868,7 @@ substitute_and_fold_engine::replace_uses_in (gimple *stmt) FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE) { tree tuse = USE_FROM_PTR (use); - tree val = get_value (tuse, stmt); + tree val = value_of_expr (tuse, stmt); if (val == tuse || val == NULL_TREE) continue; @@ -909,12 +909,11 @@ substitute_and_fold_engine::replace_phi_args_in (gphi *phi) if (TREE_CODE (arg) == SSA_NAME) { - tree val = get_value (arg, phi); + edge e = gimple_phi_arg_edge (phi, i); + tree val = value_on_edge (e, arg); if (val && val != arg && may_propagate_copy (arg, val)) { - edge e = gimple_phi_arg_edge (phi, i); - if (TREE_CODE (val) != SSA_NAME) prop_stats.num_const_prop++; else @@ -1036,7 +1035,7 @@ substitute_and_fold_engine::propagate_into_phi_args (basic_block bb) if (TREE_CODE (arg) != SSA_NAME || virtual_operand_p (arg)) continue; - tree val = get_value (arg, phi); + tree val = value_on_edge (e, arg); if (val && is_gimple_min_invariant (val) && may_propagate_copy (arg, val)) @@ -1070,7 +1069,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) } if (res && TREE_CODE (res) == SSA_NAME) { - tree sprime = substitute_and_fold_engine->get_value (res, phi); + tree sprime = substitute_and_fold_engine->value_of_expr (res, phi); if (sprime && sprime != res && may_propagate_copy (res, sprime)) @@ -1110,7 +1109,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) tree lhs = gimple_get_lhs (stmt); if (lhs && TREE_CODE (lhs) == SSA_NAME) { - tree sprime = substitute_and_fold_engine->get_value (lhs, stmt); + tree sprime = substitute_and_fold_engine->value_of_expr (lhs, stmt); if (sprime && sprime != lhs && may_propagate_copy (lhs, sprime) diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h index 9406cdf8f51..da362ab562d 100644 --- a/gcc/tree-ssa-propagate.h +++ b/gcc/tree-ssa-propagate.h @@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see #ifndef _TREE_SSA_PROPAGATE_H #define _TREE_SSA_PROPAGATE_H 1 +#include "value-query.h" + /* If SIM_P is true, statement S will be simulated again. */ static inline void @@ -97,14 +99,13 @@ class ssa_propagation_engine void simulate_block (basic_block); }; -class substitute_and_fold_engine +class substitute_and_fold_engine : public value_query { public: substitute_and_fold_engine (bool fold_all_stmts = false) : fold_all_stmts (fold_all_stmts) { } virtual ~substitute_and_fold_engine (void) { } virtual bool fold_stmt (gimple_stmt_iterator *) { return false; } - virtual tree get_value (tree, gimple *) { return NULL_TREE; } bool substitute_and_fold (basic_block = NULL); bool replace_uses_in (gimple *); diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 47f537ab210..9907cc0c824 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -5860,7 +5860,7 @@ strlen_dom_walker::before_dom_children (basic_block bb) can be used by printf argument processing. */ evrp.record_ranges_from_stmt (stmt, false); - if (check_and_optimize_stmt (&gsi, &cleanup_eh, evrp.get_vr_values ())) + if (check_and_optimize_stmt (&gsi, &cleanup_eh, &evrp)) gsi_next (&gsi); } diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 03a210846cb..f43d5812270 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -163,8 +163,8 @@ record_temporary_equivalences_from_phis (edge e, { /* Get an empty new VR we can pass to update_value_range and save away in the VR stack. */ - vr_values *vr_values = evrp_range_analyzer->get_vr_values (); - value_range_equiv *new_vr = vr_values->allocate_value_range_equiv (); + value_range_equiv *new_vr + = evrp_range_analyzer->allocate_value_range_equiv (); new (new_vr) value_range_equiv (); /* There are three cases to consider: @@ -178,7 +178,7 @@ record_temporary_equivalences_from_phis (edge e, Otherwise set NEW_VR to varying. This may be overly conservative. */ if (TREE_CODE (src) == SSA_NAME) - new_vr->deep_copy (vr_values->get_value_range (src)); + new_vr->deep_copy (evrp_range_analyzer->get_value_range (src)); else if (TREE_CODE (src) == INTEGER_CST) new_vr->set (src); else diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b493e402382..0e19690f41f 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4010,9 +4010,12 @@ class vrp_folder : public substitute_and_fold_engine : substitute_and_fold_engine (/* Fold all stmts. */ true), m_vr_values (v), simplifier (v) { } - tree get_value (tree, gimple *stmt) FINAL OVERRIDE; bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE; + tree value_of_expr (tree name, gimple *stmt) OVERRIDE + { + return m_vr_values->value_of_expr (name, stmt); + } class vr_values *m_vr_values; private: @@ -4023,8 +4026,6 @@ private: { return simplifier.vrp_evaluate_conditional (code, op0, op1, stmt); } bool simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) { return simplifier.simplify (gsi); } - tree op_with_constant_singleton_value_range (tree op) - { return m_vr_values->op_with_constant_singleton_value_range (op); } simplify_using_ranges simplifier; }; @@ -4102,18 +4103,6 @@ vrp_folder::fold_stmt (gimple_stmt_iterator *si) return simplify_stmt_using_ranges (si); } -/* If OP has a value range with a single constant value return that, - otherwise return NULL_TREE. This returns OP itself if OP is a - constant. - - Implemented as a pure wrapper right now, but this will change. */ - -tree -vrp_folder::get_value (tree op, gimple *stmt ATTRIBUTE_UNUSED) -{ - return op_with_constant_singleton_value_range (op); -} - /* Return the LHS of any ASSERT_EXPR where OP appears as the first argument to the ASSERT_EXPR and in which the ASSERT_EXPR dominates BB. If no such ASSERT_EXPR is found, return OP. */ diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 9b21441dff3..4d7dfd0b4bf 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -92,7 +92,7 @@ vr_values::get_lattice_entry (const_tree var) return vr; /* Create a default value range. */ - vr = new (vrp_value_range_pool.allocate ()) value_range_equiv; + vr = allocate_value_range_equiv (); vr_value[ver] = vr; /* After propagation finished return varying. */ @@ -173,6 +173,49 @@ vr_values::get_value_range (const_tree var, return vr; } +bool +vr_values::range_of_expr (irange &r, tree name, gimple *stmt) +{ + if (const value_range *vr = get_value_range (name, stmt)) + { + if (vr->undefined_p () || vr->varying_p () || vr->constant_p ()) + r = *vr; + else + { + value_range tmp = *vr; + tmp.normalize_symbolics (); + r = tmp; + } + return true; + } + return false; +} + +tree +vr_values::value_of_expr (tree op, gimple *) +{ + return op_with_constant_singleton_value_range (op); +} + +tree +vr_values::value_on_edge (edge, tree op) +{ + return op_with_constant_singleton_value_range (op); +} + +tree +vr_values::value_of_stmt (gimple *stmt, tree op) +{ + if (!op) + op = gimple_get_lhs (stmt); + + gcc_checking_assert (!op|| op == gimple_get_lhs (stmt)); + + if (op) + return op_with_constant_singleton_value_range (op); + return NULL_TREE; +} + /* Set the lattice entry for DEF to VARYING. */ void @@ -451,7 +494,7 @@ simplify_using_ranges::op_with_boolean_value_range_p (tree op) /* ?? Errr, this should probably check for [0,0] and [1,1] as well as [0,1]. */ - const value_range *vr = get_value_range (op); + const value_range *vr = query->get_value_range (op); return *vr == value_range (build_zero_cst (TREE_TYPE (op)), build_one_cst (TREE_TYPE (op))); } @@ -1006,20 +1049,20 @@ vr_values::extract_range_from_comparison (value_range_equiv *vr, overflow. */ static bool -check_for_binary_op_overflow (range_query *store, +check_for_binary_op_overflow (range_query *query, enum tree_code subcode, tree type, tree op0, tree op1, bool *ovf) { value_range vr0, vr1; if (TREE_CODE (op0) == SSA_NAME) - vr0 = *store->get_value_range (op0); + vr0 = *query->get_value_range (op0); else if (TREE_CODE (op0) == INTEGER_CST) vr0.set (op0); else vr0.set_varying (TREE_TYPE (op0)); if (TREE_CODE (op1) == SSA_NAME) - vr1 = *store->get_value_range (op1); + vr1 = *query->get_value_range (op1); else if (TREE_CODE (op1) == INTEGER_CST) vr1.set (op1); else @@ -1948,8 +1991,7 @@ vr_values::dump_all_value_ranges (FILE *file) /* Initialize VRP lattice. */ -vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges"), - simplifier (this) +vr_values::vr_values () : simplifier (this) { values_propagated = false; num_vr_values = num_ssa_names * 2; @@ -1966,7 +2008,6 @@ vr_values::~vr_values () free (vr_value); free (vr_phi_edge_counts); bitmap_obstack_release (&vrp_equiv_obstack); - vrp_value_range_pool.release (); /* So that we can distinguish between VRP data being available and not available. */ @@ -2092,7 +2133,7 @@ const value_range_equiv * simplify_using_ranges::get_vr_for_comparison (int i, value_range_equiv *tem) { /* Shallow-copy equiv bitmap. */ - const value_range_equiv *vr = get_value_range (ssa_name (i)); + const value_range_equiv *vr = query->get_value_range (ssa_name (i)); /* If name N_i does not have a valid range, use N_i as its own range. This allows us to compare against names that may @@ -2117,7 +2158,7 @@ simplify_using_ranges::compare_name_with_value bool *strict_overflow_p, bool use_equiv_p) { /* Get the set of equivalences for VAR. */ - bitmap e = get_value_range (var)->equiv (); + bitmap e = query->get_value_range (var)->equiv (); /* Start at -1. Set it to 0 if we do a comparison without relying on overflow, or 1 if all comparisons rely on overflow. */ @@ -2197,8 +2238,8 @@ simplify_using_ranges::compare_names (enum tree_code comp, tree n1, tree n2, { /* Compare the ranges of every name equivalent to N1 against the ranges of every name equivalent to N2. */ - bitmap e1 = get_value_range (n1)->equiv (); - bitmap e2 = get_value_range (n2)->equiv (); + bitmap e1 = query->get_value_range (n1)->equiv (); + bitmap e2 = query->get_value_range (n2)->equiv (); /* Use the fake bitmaps if e1 or e2 are not available. */ static bitmap s_e1 = NULL, s_e2 = NULL; @@ -2310,8 +2351,8 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code code, tree op0, tree op1, bool * strict_overflow_p) { const value_range_equiv *vr0, *vr1; - vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL; - vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL; + vr0 = (TREE_CODE (op0) == SSA_NAME) ? query->get_value_range (op0) : NULL; + vr1 = (TREE_CODE (op1) == SSA_NAME) ? query->get_value_range (op1) : NULL; tree res = NULL_TREE; if (vr0 && vr1) @@ -2390,7 +2431,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops } else gcc_unreachable (); - const value_range_equiv *vr0 = get_value_range (op0, stmt); + const value_range_equiv *vr0 = query->get_value_range (op0, stmt); /* If vro, the range for OP0 to pass the overflow test, has no intersection with *vr0, OP0's known range, then the overflow test can't pass, so return the node for false. @@ -2496,7 +2537,7 @@ simplify_using_ranges::vrp_evaluate_conditional (tree_code code, tree op0, always fold regardless of the value of OP0. If -Wtype-limits was specified, emit a warning. */ tree type = TREE_TYPE (op0); - const value_range_equiv *vr0 = get_value_range (op0, stmt); + const value_range_equiv *vr0 = query->get_value_range (op0, stmt); if (vr0->varying_p () && INTEGRAL_TYPE_P (type) @@ -2547,7 +2588,7 @@ 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, get_value_range (use, stmt)); + dump_value_range (dump_file, query->get_value_range (use, stmt)); } fprintf (dump_file, "\n"); @@ -3123,7 +3164,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges } else { - vr = get_value_range (op0, stmt); + vr = query->get_value_range (op0, stmt); if (range_int_cst_p (vr)) { op0min = vr->min (); @@ -3134,7 +3175,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges if (rhs_code == TRUNC_MOD_EXPR && TREE_CODE (op1) == SSA_NAME) { - const value_range_equiv *vr1 = get_value_range (op1, stmt); + const value_range_equiv *vr1 = query->get_value_range (op1, stmt); if (range_int_cst_p (vr1)) op1min = vr1->min (); } @@ -3283,7 +3324,7 @@ simplify_using_ranges::simplify_abs_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt) { tree op = gimple_assign_rhs1 (stmt); - const value_range *vr = get_value_range (op, stmt); + const value_range *vr = query->get_value_range (op, stmt); if (vr) { @@ -3373,14 +3414,14 @@ simplify_using_ranges::simplify_bit_ops_using_ranges wide_int mask; if (TREE_CODE (op0) == SSA_NAME) - vr0 = *(get_value_range (op0, stmt)); + vr0 = *(query->get_value_range (op0, stmt)); else if (is_gimple_min_invariant (op0)) vr0.set (op0); else return false; if (TREE_CODE (op1) == SSA_NAME) - vr1 = *(get_value_range (op1, stmt)); + vr1 = *(query->get_value_range (op1, stmt)); else if (is_gimple_min_invariant (op1)) vr1.set (op1); else @@ -3599,7 +3640,7 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt) && INTEGRAL_TYPE_P (TREE_TYPE (op0)) && is_gimple_min_invariant (op1)) { - const value_range *vr = get_value_range (op0, stmt); + const value_range *vr = query->get_value_range (op0, stmt); /* If we have range information for OP0, then we might be able to simplify this conditional. */ @@ -3672,7 +3713,7 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt) subsequent passes. */ void -simplify_cond_using_ranges_2 (vr_values *store, gcond *stmt) +simplify_cond_using_ranges_2 (vr_values *query, gcond *stmt) { tree op0 = gimple_cond_lhs (stmt); tree op1 = gimple_cond_rhs (stmt); @@ -3702,7 +3743,7 @@ simplify_cond_using_ranges_2 (vr_values *store, gcond *stmt) && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop) && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0))) { - const value_range *vr = store->get_value_range (innerop); + const value_range *vr = query->get_value_range (innerop); if (range_int_cst_p (vr) && range_fits_type_p (vr, @@ -3743,7 +3784,7 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt) if (TREE_CODE (op) == SSA_NAME) { - vr = get_value_range (op, stmt); + vr = query->get_value_range (op, stmt); /* We can only handle integer ranges. */ if (vr->varying_p () @@ -4036,7 +4077,7 @@ simplify_using_ranges::simplify_float_conversion_using_ranges gimple *stmt) { tree rhs1 = gimple_assign_rhs1 (stmt); - const value_range *vr = get_value_range (rhs1, stmt); + const value_range *vr = query->get_value_range (rhs1, stmt); scalar_float_mode fltmode = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))); scalar_int_mode mode; @@ -4141,7 +4182,7 @@ simplify_using_ranges::simplify_internal_call_using_ranges return false; else type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt))); - if (!check_for_binary_op_overflow (store, subcode, type, op0, op1, &ovf) + if (!check_for_binary_op_overflow (query, subcode, type, op0, op1, &ovf) || (is_ubsan && ovf)) return false; @@ -4200,7 +4241,7 @@ simplify_using_ranges::simplify_internal_call_using_ranges bool simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b) { - value_range vr = *get_value_range (var); + value_range vr = *query->get_value_range (var); vr.normalize_symbolics (); if (vr.varying_p () || vr.undefined_p ()) return false; @@ -4217,8 +4258,8 @@ simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b) return false; } -simplify_using_ranges::simplify_using_ranges (range_query *store) - : store (store) +simplify_using_ranges::simplify_using_ranges (range_query *query) + : query (query) { to_remove_edges = vNULL; to_update_switch_stmts = vNULL; @@ -4234,6 +4275,8 @@ simplify_using_ranges::~simplify_using_ranges () bool simplify_using_ranges::simplify (gimple_stmt_iterator *gsi) { + gcc_checking_assert (query); + gimple *stmt = gsi_stmt (*gsi); if (is_gimple_assign (stmt)) { diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 7051e13fc00..a30f05cbeaa 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -21,28 +21,19 @@ along with GCC; see the file COPYING3. If not see #define GCC_VR_VALUES_H #include "value-range-equiv.h" +#include "value-query.h" // Abstract class to return a range for a given SSA. -class range_query -{ -public: - virtual const value_range_equiv *get_value_range (const_tree, - gimple * = NULL) = 0; - virtual ~range_query () { } -}; - // Class to simplify a statement using range information. -// -// The constructor takes a full vr_values, but all it needs is -// get_value_range() from it. This class could be made to work with -// any range repository. -class simplify_using_ranges : public range_query +class simplify_using_ranges { public: - simplify_using_ranges (class range_query *); + simplify_using_ranges (class range_query *query = NULL); ~simplify_using_ranges (); + void set_range_query (class range_query *q) { query = q; } + bool simplify (gimple_stmt_iterator *); // ?? These should be cleaned, merged, and made private. @@ -53,8 +44,6 @@ public: bool *, bool *); private: - const value_range_equiv *get_value_range (const_tree op, - gimple *stmt = NULL) OVERRIDE; bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *); @@ -89,7 +78,7 @@ private: vec to_remove_edges; vec to_update_switch_stmts; - class range_query *store; + class range_query *query; }; /* The VR_VALUES class holds the current view of range information @@ -112,7 +101,12 @@ class vr_values : public range_query vr_values (void); ~vr_values (void); - const value_range_equiv *get_value_range (const_tree, gimple * = NULL); + virtual bool range_of_expr (irange &r, tree name, 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; + virtual const value_range_equiv *get_value_range (const_tree, + gimple * = NULL) OVERRIDE; void set_vr_value (tree, value_range_equiv *); value_range_equiv *swap_vr_value (tree, value_range_equiv *); @@ -136,9 +130,9 @@ class vr_values : public range_query /* Allocate a new value_range object. */ value_range_equiv *allocate_value_range_equiv (void) - { return vrp_value_range_pool.allocate (); } + { return range_query::allocate_value_range_equiv (); } void free_value_range (value_range_equiv *vr) - { vrp_value_range_pool.remove (vr); } + { free_value_range_equiv (vr); } private: value_range_equiv *get_lattice_entry (const_tree); @@ -155,9 +149,6 @@ class vr_values : public range_query void vrp_visit_assignment_or_call (gimple*, tree *, value_range_equiv *); void vrp_visit_switch_stmt (gswitch *, edge *); - /* Allocation pools for value_range objects. */ - object_allocator vrp_value_range_pool; - /* This probably belongs in the lattice rather than in here. */ bool values_propagated; @@ -176,12 +167,6 @@ class vr_values : public range_query simplify_using_ranges simplifier; }; -inline const value_range_equiv * -simplify_using_ranges::get_value_range (const_tree op, gimple *stmt) -{ - return store->get_value_range (op, stmt); -} - extern tree get_output_for_vrp (gimple *); // FIXME: Move this to tree-vrp.c.