Message ID | ee92f7bf-f292-6a86-acf8-c9911a5c2aac@redhat.com |
---|---|
State | New |
Headers | show |
Series | [RFA] 10/n Various class definition cleanups | expand |
On Sat, Nov 18, 2017 at 9:39 AM, Jeff Law <law@redhat.com> wrote: > > A batch of random cleanups in the various vrp related bits. > > The goal here is to start banging some of the classes into shape. > Included in this patch: > > > For evrp_folder: > Accepts vr_values in its ctor to attach. > Uses DISABLE_COPY_AND_ASSIGN > > For evrp_dom_walker: > Has the evrp_folder attached to it to avoid continually > recreating an evrp_folder instance. > Delegators removed, created free value_range_constant_singleton > along the way to help remove one of them. > > For evrp_range_analyzer: > The attached vr_values member is now private. > 3 delegators are kept and made part of the public API > The remaining half-dozen or so delegators are gone > > For vr_values: > Privatizes several data members > Privatizes many methods > > > I'm still not at all happy with management of the attached vr_values > class instance. I was going to use our unique_ptr, but without examples > my attempts failed. I'll have to give it another whirl when I'm fresher. > > Bootstrapped and regression tested on x86_64. > > OK for the trunk once the vr_values attachment code is cleaned up and it > goes through another round of testing? Ok. Thanks, Richard. > jeff > > > > > > * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer) > Initialize vr_values. > (evrp_range_analyzer::try_find_new_range): Call methods attached to > vr_values via vr_values class instance rather than delegators. > (evrp_range_analyzer::record_ranges_from_phis): Likewise. > (evrp_range_analyzer::record_ranges_from_stmt): Likewise. > (evrp_range_analyzer::push_value_range): Likewise. > (evrp_range_analyzer::pop_value_range): Likewise. > * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove > most delegators. Those remaining are exposed as public interfaces. > Make vr_values a pointer. > (evrp_range_analyzer::~evrp_range_analyzer): Conditionally > delete the attached vr_values. > (evrp_range_analyzer::get_vr_value): New method. > * gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN. > (evrp_folder::evrp_folder): New ctor to initialize vr_values. > (class evrp_dom_walker): Attach evrp_folder class, initialize > it in the ctor. Remove temporary delegators. > (evrp_dom_walker::before_dom_children): Call methods in attached > evrp_range_analyzer class via class instance pointer. Use > free value_range_constant_singleton to remove need for > op_with_constant_singleton_value delegator method. Do not > create a vrp_prop class instance for every call! Narrow > scope of a couple variables. > (evrp_dom_walker::cleanup): Call methods in attached > evrp_range_analyzer class via class instance pointer. > * vr-values.h (class vr_values): Privatize many methods and > data members. > > > diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c > index 9e581834d08..c3877791a5e 100644 > --- a/gcc/gimple-ssa-evrp-analyze.c > +++ b/gcc/gimple-ssa-evrp-analyze.c > @@ -53,6 +53,7 @@ evrp_range_analyzer::evrp_range_analyzer () : stack (10) > FOR_EACH_EDGE (e, ei, bb->preds) > e->flags |= EDGE_EXECUTABLE; > } > + vr_values = new class vr_values; > } > > void > @@ -73,8 +74,8 @@ evrp_range_analyzer::try_find_new_range (tree name, > value_range *old_vr = get_value_range (name); > > /* Discover VR when condition is true. */ > - extract_range_for_var_from_comparison_expr (name, code, op, > - limit, &vr); > + vr_values->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.type == VR_RANGE || vr.type == VR_ANTI_RANGE) > @@ -83,7 +84,7 @@ evrp_range_analyzer::try_find_new_range (tree name, > && vrp_operand_equal_p (old_vr->min, vr.min) > && vrp_operand_equal_p (old_vr->max, vr.max)) > return NULL; > - value_range *new_vr = vr_values.vrp_value_range_pool.allocate (); > + value_range *new_vr = vr_values->vrp_value_range_pool.allocate (); > *new_vr = vr; > return new_vr; > } > @@ -167,7 +168,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) > value_range vr_result = VR_INITIALIZER; > bool interesting = stmt_interesting_for_vrp (phi); > if (!has_unvisited_preds && interesting) > - extract_range_from_phi_node (phi, &vr_result); > + vr_values->extract_range_from_phi_node (phi, &vr_result); > else > { > set_value_range_to_varying (&vr_result); > @@ -179,9 +180,9 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) > if (interesting > && (l = loop_containing_stmt (phi)) > && l->header == gimple_bb (phi)) > - adjust_range_with_scev (&vr_result, l, phi, lhs); > + vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs); > } > - update_value_range (lhs, &vr_result); > + vr_values->update_value_range (lhs, &vr_result); > > /* Set the SSA with the value range. */ > if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) > @@ -216,11 +217,11 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) > { > edge taken_edge; > value_range vr = VR_INITIALIZER; > - extract_range_from_stmt (stmt, &taken_edge, &output, &vr); > + vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr); > if (output > && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)) > { > - update_value_range (output, &vr); > + vr_values->update_value_range (output, &vr); > > /* Set the SSA with the value range. */ > if (INTEGRAL_TYPE_P (TREE_TYPE (output))) > @@ -240,10 +241,10 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) > set_ptr_nonnull (output); > } > else > - set_defs_to_varying (stmt); > + vr_values->set_defs_to_varying (stmt); > } > else > - set_defs_to_varying (stmt); > + vr_values->set_defs_to_varying (stmt); > > /* See if we can derive a range for any of STMT's operands. */ > tree op; > @@ -319,7 +320,7 @@ evrp_range_analyzer::push_value_range (tree var, value_range *vr) > fprintf (dump_file, "\n"); > } > stack.safe_push (std::make_pair (var, get_value_range (var))); > - set_vr_value (var, vr); > + vr_values->set_vr_value (var, vr); > } > > /* Pop the Value Range from the vrp_stack and update VAR with it. */ > @@ -337,7 +338,7 @@ evrp_range_analyzer::pop_value_range (tree var) > dump_value_range (dump_file, vr); > fprintf (dump_file, "\n"); > } > - set_vr_value (var, vr); > + vr_values->set_vr_value (var, vr); > stack.pop (); > return vr; > } > diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h > index 2e6c609c45b..b60bba848cc 100644 > --- a/gcc/gimple-ssa-evrp-analyze.h > +++ b/gcc/gimple-ssa-evrp-analyze.h > @@ -24,16 +24,46 @@ class evrp_range_analyzer > { > public: > evrp_range_analyzer (void); > - ~evrp_range_analyzer (void) { stack.release (); } > + ~evrp_range_analyzer (void) > + { > + if (vr_values) > + delete vr_values; > + stack.release (); > + } > > void enter (basic_block); > void leave (basic_block); > void record_ranges_from_stmt (gimple *); > > - class vr_values vr_values; > + /* Main interface to retrieve range information. */ > + value_range *get_value_range (const_tree op) > + { return vr_values->get_value_range (op); } > + > + /* 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) > + { return vr_values->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 (bool transfer) > + { > + class vr_values *x = vr_values; > + if (transfer) > + vr_values = NULL; > + return x; > + } > > private: > DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer); > + class vr_values *vr_values; > + > void push_value_range (tree var, value_range *vr); > value_range *pop_value_range (tree var); > value_range *try_find_new_range (tree, tree op, tree_code code, tree limit); > @@ -42,30 +72,6 @@ class evrp_range_analyzer > > /* STACK holds the old VR. */ > auto_vec<std::pair <tree, value_range*> > stack; > - > - /* Temporary delegators. */ > - value_range *get_value_range (const_tree op) > - { return vr_values.get_value_range (op); } > - bool update_value_range (const_tree op, value_range *vr) > - { return vr_values.update_value_range (op, vr); } > - void extract_range_from_phi_node (gphi *phi, value_range *vr) > - { vr_values.extract_range_from_phi_node (phi, vr); } > - void adjust_range_with_scev (value_range *vr, struct loop *loop, > - gimple *stmt, tree var) > - { vr_values.adjust_range_with_scev (vr, loop, stmt, var); } > - void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p, > - tree *output_p, value_range *vr) > - { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); } > - void set_defs_to_varying (gimple *stmt) > - { return vr_values.set_defs_to_varying (stmt); } > - void set_vr_value (tree name, value_range *vr) > - { vr_values.set_vr_value (name, vr); } > - void extract_range_for_var_from_comparison_expr (tree var, > - enum tree_code cond_code, > - tree op, tree limit, > - value_range *vr_p) > - { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code, > - op, limit, vr_p); } > }; > > #endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */ > diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c > index 27a983dd9ae..a554cf9e834 100644 > --- a/gcc/gimple-ssa-evrp.c > +++ b/gcc/gimple-ssa-evrp.c > @@ -46,8 +46,11 @@ class evrp_folder : public substitute_and_fold_engine > { > public: > tree get_value (tree) FINAL OVERRIDE; > - > + evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { } > class vr_values *vr_values; > + > + private: > + DISABLE_COPY_AND_ASSIGN (evrp_folder); > }; > > tree > @@ -63,7 +66,9 @@ evrp_folder::get_value (tree op) > class evrp_dom_walker : public dom_walker > { > public: > - evrp_dom_walker () : dom_walker (CDI_DOMINATORS) > + evrp_dom_walker () > + : dom_walker (CDI_DOMINATORS), > + evrp_folder (evrp_range_analyzer.get_vr_values (false)) > { > need_eh_cleanup = BITMAP_ALLOC (NULL); > } > @@ -82,14 +87,7 @@ public: > auto_vec<gimple *> stmts_to_remove; > > class evrp_range_analyzer evrp_range_analyzer; > - > - /* Temporary delegators. */ > - value_range *get_value_range (const_tree op) > - { return evrp_range_analyzer.vr_values.get_value_range (op); } > - tree op_with_constant_singleton_value_range (tree op) > - { return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); } > - void vrp_visit_cond_stmt (gcond *cond, edge *e) > - { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); } > + class evrp_folder evrp_folder; > }; > > edge > @@ -108,8 +106,9 @@ evrp_dom_walker::before_dom_children (basic_block bb) > if (virtual_operand_p (lhs)) > continue; > > + value_range *vr = evrp_range_analyzer.get_value_range (lhs); > /* Mark PHIs whose lhs we fully propagate for removal. */ > - tree val = op_with_constant_singleton_value_range (lhs); > + tree val = value_range_constant_singleton (vr); > if (val && may_propagate_copy (lhs, val)) > { > stmts_to_remove.safe_push (phi); > @@ -139,7 +138,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) > > if (gcond *cond = dyn_cast <gcond *> (stmt)) > { > - vrp_visit_cond_stmt (cond, &taken_edge); > + evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge); > if (taken_edge) > { > if (taken_edge->flags & EDGE_TRUE_VALUE) > @@ -153,16 +152,15 @@ evrp_dom_walker::before_dom_children (basic_block bb) > } > else if (stmt_interesting_for_vrp (stmt)) > { > - value_range vr = VR_INITIALIZER; > output = get_output_for_vrp (stmt); > if (output) > { > tree val; > - vr = *get_value_range (output); > + value_range *vr = evrp_range_analyzer.get_value_range (output); > > /* Mark stmts whose output we fully propagate for removal. */ > - if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE) > - && (val = op_with_constant_singleton_value_range (output)) > + if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) > + && (val = value_range_constant_singleton (vr)) > && may_propagate_copy (output, val) > && !stmt_could_throw_p (stmt) > && !gimple_has_side_effects (stmt)) > @@ -174,8 +172,6 @@ evrp_dom_walker::before_dom_children (basic_block bb) > } > > /* Try folding stmts with the VR discovered. */ > - class evrp_folder evrp_folder; > - evrp_folder.vr_values = &evrp_range_analyzer.vr_values; > bool did_replace = evrp_folder.replace_uses_in (stmt); > if (fold_stmt (&gsi, follow_single_use_edges) > || did_replace) > @@ -222,7 +218,8 @@ evrp_dom_walker::before_dom_children (basic_block bb) > if (TREE_CODE (arg) != SSA_NAME > || virtual_operand_p (arg)) > continue; > - tree val = op_with_constant_singleton_value_range (arg); > + value_range *vr = evrp_range_analyzer.get_value_range (arg); > + tree val = value_range_constant_singleton (vr); > if (val && may_propagate_copy (arg, val)) > propagate_value (use_p, val); > } > @@ -245,7 +242,7 @@ evrp_dom_walker::cleanup (void) > if (dump_file) > { > fprintf (dump_file, "\nValue ranges after Early VRP:\n\n"); > - evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file); > + evrp_range_analyzer.dump_all_value_ranges (dump_file); > fprintf (dump_file, "\n"); > } > > diff --git a/gcc/vr-values.h b/gcc/vr-values.h > index 24f013a9402..9eeebedfaed 100644 > --- a/gcc/vr-values.h > +++ b/gcc/vr-values.h > @@ -40,80 +40,81 @@ class vr_values > vr_values (void); > ~vr_values (void); > > - /* Value range array. After propagation, VR_VALUE[I] holds the range > - of values that SSA name N_I may take. */ > - unsigned int num_vr_values; > - value_range **vr_value; > - bool values_propagated; > + value_range *get_value_range (const_tree); > > - /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the > - number of executable edges we saw the last time we visited the > - node. */ > - int *vr_phi_edge_counts; > + void set_vr_value (tree, value_range *); > + void set_defs_to_varying (gimple *); > + bool update_value_range (const_tree, value_range *); > + tree op_with_constant_singleton_value_range (tree); > + void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree); > + tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *); > + void dump_all_value_ranges (FILE *); > + > + void extract_range_for_var_from_comparison_expr (tree, enum tree_code, > + tree, tree, value_range *); > + void extract_range_from_phi_node (gphi *, value_range *); > + void extract_range_basic (value_range *, gimple *); > + void extract_range_from_assignment (value_range *, gassign *); > + void extract_range_from_stmt (gimple *, edge *, tree *, value_range *); > + > + void vrp_visit_cond_stmt (gcond *, edge *); > + > + void simplify_cond_using_ranges_2 (gcond *); > + bool simplify_stmt_using_ranges (gimple_stmt_iterator *); > + > + /* This probably belongs in the lattice rather than in here. */ > + bool values_propagated; > > /* Allocation pools for tree-vrp allocations. */ > object_allocator<value_range> vrp_value_range_pool; > - bitmap_obstack vrp_equiv_obstack; > > - value_range *get_value_range (const_tree); > - void set_vr_value (tree, value_range *); > - > - void set_defs_to_varying (gimple *); > - bool update_value_range (const_tree, value_range *); > + private: > + bitmap_obstack vrp_equiv_obstack; > void add_equivalence (bitmap *, const_tree); > bool vrp_stmt_computes_nonzero (gimple *); > - tree op_with_constant_singleton_value_range (tree); > bool op_with_boolean_value_range_p (tree); > bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *); > - void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree); > value_range get_vr_for_comparison (int); > tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool); > tree compare_names (enum tree_code, tree, tree, bool *); > bool two_valued_val_range_p (tree, tree *, tree *); > - > tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code, > tree, tree, > bool *); > tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code, > tree, tree, bool, > bool *, bool *); > - tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *); > - > - > - void dump_all_value_ranges (FILE *); > - > - void extract_range_for_var_from_comparison_expr (tree, enum tree_code, > - tree, tree, value_range *); > void extract_range_from_assert (value_range *, tree); > void extract_range_from_ssa_name (value_range *, tree); > void extract_range_from_binary_expr (value_range *, enum tree_code, > tree, tree, tree); > void extract_range_from_unary_expr (value_range *, enum tree_code, > tree, tree); > - void extract_range_from_phi_node (gphi *, value_range *); > void extract_range_from_cond_expr (value_range *, gassign *); > - void extract_range_basic (value_range *, gimple *); > - void extract_range_from_assignment (value_range *, gassign *); > - void extract_range_from_stmt (gimple *, edge *, tree *, value_range *); > void extract_range_from_comparison (value_range *, enum tree_code, > tree, tree, tree); > - > void vrp_visit_assignment_or_call (gimple*, tree *, value_range *); > void vrp_visit_switch_stmt (gswitch *, edge *); > - void vrp_visit_cond_stmt (gcond *, edge *); > - > 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 *); > bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *); > bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *); > bool simplify_cond_using_ranges_1 (gcond *); > - void simplify_cond_using_ranges_2 (gcond *); > bool simplify_switch_using_ranges (gswitch *); > bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *, > gimple *); > bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *); > - bool simplify_stmt_using_ranges (gimple_stmt_iterator *); > + > + /* Value range array. After propagation, VR_VALUE[I] holds the range > + of values that SSA name N_I may take. */ > + unsigned int num_vr_values; > + value_range **vr_value; > + > + /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the > + number of executable edges we saw the last time we visited the > + node. */ > + int *vr_phi_edge_counts; > }; > > #define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL } >
On 11/20/2017 03:06 AM, Richard Biener wrote: > On Sat, Nov 18, 2017 at 9:39 AM, Jeff Law <law@redhat.com> wrote: >> >> A batch of random cleanups in the various vrp related bits. >> >> The goal here is to start banging some of the classes into shape. >> Included in this patch: >> >> >> For evrp_folder: >> Accepts vr_values in its ctor to attach. >> Uses DISABLE_COPY_AND_ASSIGN >> >> For evrp_dom_walker: >> Has the evrp_folder attached to it to avoid continually >> recreating an evrp_folder instance. >> Delegators removed, created free value_range_constant_singleton >> along the way to help remove one of them. >> >> For evrp_range_analyzer: >> The attached vr_values member is now private. >> 3 delegators are kept and made part of the public API >> The remaining half-dozen or so delegators are gone >> >> For vr_values: >> Privatizes several data members >> Privatizes many methods >> >> >> I'm still not at all happy with management of the attached vr_values >> class instance. I was going to use our unique_ptr, but without examples >> my attempts failed. I'll have to give it another whirl when I'm fresher. >> >> Bootstrapped and regression tested on x86_64. >> >> OK for the trunk once the vr_values attachment code is cleaned up and it >> goes through another round of testing? > > Ok. So for reference the final patch is attached. There were some trailing whitespace cleanups and of course changes in how we handle attachment of vr_values. After further digging it became clear we couldn't use unique_ptr for vr_values without actually making the code more complex -- there can be only one copy of the pointer at any time, so we'd have to hand it off between the two containing classes which would have to happen inside the before_dom_children which was just ewwww. It really needs to be a shared_ptr, but we don't have emulation of shared_ptr AFAIK. So we just fall back to not using smart pointers and documenting ownership. Installed on the trunk after a bootstrap cycle. jeff commit c561e1e7b5610f2f4aa99237204506b86ffd8578 Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed Nov 22 20:31:14 2017 +0000 * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer) Initialize vr_values. (evrp_range_analyzer::try_find_new_range): Call methods attached to vr_values via vr_values class instance rather than delegators. (evrp_range_analyzer::record_ranges_from_phis): Likewise. (evrp_range_analyzer::record_ranges_from_stmt): Likewise. (evrp_range_analyzer::push_value_range): Likewise. (evrp_range_analyzer::pop_value_range): Likewise. * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove most delegators. Those remaining are exposed as public interfaces. Make vr_values a pointer and private. (evrp_range_analyzer::~evrp_range_analyzer): Delete the attached vr_values. (evrp_range_analyzer::get_vr_value): New method. * gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN. (evrp_folder::evrp_folder): New ctor to initialize vr_values. (class evrp_dom_walker): Attach evrp_folder class, initialize it in the ctor. Remove temporary delegators. (evrp_dom_walker::before_dom_children): Call methods in attached evrp_range_analyzer class via class instance pointer. Use free value_range_constant_singleton to remove need for op_with_constant_singleton_value delegator method. Do not create a vrp_prop class instance for every call! Narrow scope of a couple variables. (evrp_dom_walker::cleanup): Call methods in attached evrp_range_analyzer class via class instance pointer. * vr-values.h (class vr_values): Privatize many methods and data members. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@255074 138bc75d-0d04-0410-961f-82ee72b054a4 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50f5a7334a9..4ecf5bcc038 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2017-11-22 Jeff Law <law@redhat.com> + + * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer) + Initialize vr_values. + (evrp_range_analyzer::try_find_new_range): Call methods attached to + vr_values via vr_values class instance rather than delegators. + (evrp_range_analyzer::record_ranges_from_phis): Likewise. + (evrp_range_analyzer::record_ranges_from_stmt): Likewise. + (evrp_range_analyzer::push_value_range): Likewise. + (evrp_range_analyzer::pop_value_range): Likewise. + * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove + most delegators. Those remaining are exposed as public interfaces. + Make vr_values a pointer and private. + (evrp_range_analyzer::~evrp_range_analyzer): Delete the attached + vr_values. + (evrp_range_analyzer::get_vr_value): New method. + * gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN. + (evrp_folder::evrp_folder): New ctor to initialize vr_values. + (class evrp_dom_walker): Attach evrp_folder class, initialize + it in the ctor. Remove temporary delegators. + (evrp_dom_walker::before_dom_children): Call methods in attached + evrp_range_analyzer class via class instance pointer. Use + free value_range_constant_singleton to remove need for + op_with_constant_singleton_value delegator method. Do not + create a vrp_prop class instance for every call! Narrow + scope of a couple variables. + (evrp_dom_walker::cleanup): Call methods in attached + evrp_range_analyzer class via class instance pointer. + * vr-values.h (class vr_values): Privatize many methods and + data members. + 2017-11-22 Richard Sandiford <richard.sandiford@linaro.org> * tree.def (REDUC_MAX_EXPR, REDUC_MIN_EXPR, REDUC_PLUS_EXPR): Delete. diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c index 9e581834d08..c3877791a5e 100644 --- a/gcc/gimple-ssa-evrp-analyze.c +++ b/gcc/gimple-ssa-evrp-analyze.c @@ -53,6 +53,7 @@ evrp_range_analyzer::evrp_range_analyzer () : stack (10) FOR_EACH_EDGE (e, ei, bb->preds) e->flags |= EDGE_EXECUTABLE; } + vr_values = new class vr_values; } void @@ -73,8 +74,8 @@ evrp_range_analyzer::try_find_new_range (tree name, value_range *old_vr = get_value_range (name); /* Discover VR when condition is true. */ - extract_range_for_var_from_comparison_expr (name, code, op, - limit, &vr); + vr_values->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.type == VR_RANGE || vr.type == VR_ANTI_RANGE) @@ -83,7 +84,7 @@ evrp_range_analyzer::try_find_new_range (tree name, && vrp_operand_equal_p (old_vr->min, vr.min) && vrp_operand_equal_p (old_vr->max, vr.max)) return NULL; - value_range *new_vr = vr_values.vrp_value_range_pool.allocate (); + value_range *new_vr = vr_values->vrp_value_range_pool.allocate (); *new_vr = vr; return new_vr; } @@ -167,7 +168,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) value_range vr_result = VR_INITIALIZER; bool interesting = stmt_interesting_for_vrp (phi); if (!has_unvisited_preds && interesting) - extract_range_from_phi_node (phi, &vr_result); + vr_values->extract_range_from_phi_node (phi, &vr_result); else { set_value_range_to_varying (&vr_result); @@ -179,9 +180,9 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) if (interesting && (l = loop_containing_stmt (phi)) && l->header == gimple_bb (phi)) - adjust_range_with_scev (&vr_result, l, phi, lhs); + vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs); } - update_value_range (lhs, &vr_result); + vr_values->update_value_range (lhs, &vr_result); /* Set the SSA with the value range. */ if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) @@ -216,11 +217,11 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) { edge taken_edge; value_range vr = VR_INITIALIZER; - extract_range_from_stmt (stmt, &taken_edge, &output, &vr); + vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr); if (output && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)) { - update_value_range (output, &vr); + vr_values->update_value_range (output, &vr); /* Set the SSA with the value range. */ if (INTEGRAL_TYPE_P (TREE_TYPE (output))) @@ -240,10 +241,10 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) set_ptr_nonnull (output); } else - set_defs_to_varying (stmt); + vr_values->set_defs_to_varying (stmt); } else - set_defs_to_varying (stmt); + vr_values->set_defs_to_varying (stmt); /* See if we can derive a range for any of STMT's operands. */ tree op; @@ -319,7 +320,7 @@ evrp_range_analyzer::push_value_range (tree var, value_range *vr) fprintf (dump_file, "\n"); } stack.safe_push (std::make_pair (var, get_value_range (var))); - set_vr_value (var, vr); + vr_values->set_vr_value (var, vr); } /* Pop the Value Range from the vrp_stack and update VAR with it. */ @@ -337,7 +338,7 @@ evrp_range_analyzer::pop_value_range (tree var) dump_value_range (dump_file, vr); fprintf (dump_file, "\n"); } - set_vr_value (var, vr); + vr_values->set_vr_value (var, vr); stack.pop (); return vr; } diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h index 2e6c609c45b..637678034a8 100644 --- a/gcc/gimple-ssa-evrp-analyze.h +++ b/gcc/gimple-ssa-evrp-analyze.h @@ -24,16 +24,45 @@ class evrp_range_analyzer { public: evrp_range_analyzer (void); - ~evrp_range_analyzer (void) { stack.release (); } + ~evrp_range_analyzer (void) + { + delete vr_values; + stack.release (); + } void enter (basic_block); void leave (basic_block); void record_ranges_from_stmt (gimple *); - class vr_values vr_values; + /* Main interface to retrieve range information. */ + value_range *get_value_range (const_tree op) + { return vr_values->get_value_range (op); } + + /* 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) + { return vr_values->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 (bool transfer) + { + class vr_values *x = vr_values; + if (transfer) + vr_values = NULL; + return x; + } private: DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer); + class vr_values *vr_values; + void push_value_range (tree var, value_range *vr); value_range *pop_value_range (tree var); value_range *try_find_new_range (tree, tree op, tree_code code, tree limit); @@ -42,30 +71,6 @@ class evrp_range_analyzer /* STACK holds the old VR. */ auto_vec<std::pair <tree, value_range*> > stack; - - /* Temporary delegators. */ - value_range *get_value_range (const_tree op) - { return vr_values.get_value_range (op); } - bool update_value_range (const_tree op, value_range *vr) - { return vr_values.update_value_range (op, vr); } - void extract_range_from_phi_node (gphi *phi, value_range *vr) - { vr_values.extract_range_from_phi_node (phi, vr); } - void adjust_range_with_scev (value_range *vr, struct loop *loop, - gimple *stmt, tree var) - { vr_values.adjust_range_with_scev (vr, loop, stmt, var); } - void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p, - tree *output_p, value_range *vr) - { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); } - void set_defs_to_varying (gimple *stmt) - { return vr_values.set_defs_to_varying (stmt); } - void set_vr_value (tree name, value_range *vr) - { vr_values.set_vr_value (name, vr); } - void extract_range_for_var_from_comparison_expr (tree var, - enum tree_code cond_code, - tree op, tree limit, - value_range *vr_p) - { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code, - op, limit, vr_p); } }; #endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */ diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 27a983dd9ae..a554cf9e834 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -46,8 +46,11 @@ class evrp_folder : public substitute_and_fold_engine { public: tree get_value (tree) FINAL OVERRIDE; - + evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { } class vr_values *vr_values; + + private: + DISABLE_COPY_AND_ASSIGN (evrp_folder); }; tree @@ -63,7 +66,9 @@ evrp_folder::get_value (tree op) class evrp_dom_walker : public dom_walker { public: - evrp_dom_walker () : dom_walker (CDI_DOMINATORS) + evrp_dom_walker () + : dom_walker (CDI_DOMINATORS), + evrp_folder (evrp_range_analyzer.get_vr_values (false)) { need_eh_cleanup = BITMAP_ALLOC (NULL); } @@ -82,14 +87,7 @@ public: auto_vec<gimple *> stmts_to_remove; class evrp_range_analyzer evrp_range_analyzer; - - /* Temporary delegators. */ - value_range *get_value_range (const_tree op) - { return evrp_range_analyzer.vr_values.get_value_range (op); } - tree op_with_constant_singleton_value_range (tree op) - { return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); } - void vrp_visit_cond_stmt (gcond *cond, edge *e) - { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); } + class evrp_folder evrp_folder; }; edge @@ -108,8 +106,9 @@ evrp_dom_walker::before_dom_children (basic_block bb) if (virtual_operand_p (lhs)) continue; + value_range *vr = evrp_range_analyzer.get_value_range (lhs); /* Mark PHIs whose lhs we fully propagate for removal. */ - tree val = op_with_constant_singleton_value_range (lhs); + tree val = value_range_constant_singleton (vr); if (val && may_propagate_copy (lhs, val)) { stmts_to_remove.safe_push (phi); @@ -139,7 +138,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) if (gcond *cond = dyn_cast <gcond *> (stmt)) { - vrp_visit_cond_stmt (cond, &taken_edge); + evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge); if (taken_edge) { if (taken_edge->flags & EDGE_TRUE_VALUE) @@ -153,16 +152,15 @@ evrp_dom_walker::before_dom_children (basic_block bb) } else if (stmt_interesting_for_vrp (stmt)) { - value_range vr = VR_INITIALIZER; output = get_output_for_vrp (stmt); if (output) { tree val; - vr = *get_value_range (output); + value_range *vr = evrp_range_analyzer.get_value_range (output); /* Mark stmts whose output we fully propagate for removal. */ - if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE) - && (val = op_with_constant_singleton_value_range (output)) + if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) + && (val = value_range_constant_singleton (vr)) && may_propagate_copy (output, val) && !stmt_could_throw_p (stmt) && !gimple_has_side_effects (stmt)) @@ -174,8 +172,6 @@ evrp_dom_walker::before_dom_children (basic_block bb) } /* Try folding stmts with the VR discovered. */ - class evrp_folder evrp_folder; - evrp_folder.vr_values = &evrp_range_analyzer.vr_values; bool did_replace = evrp_folder.replace_uses_in (stmt); if (fold_stmt (&gsi, follow_single_use_edges) || did_replace) @@ -222,7 +218,8 @@ evrp_dom_walker::before_dom_children (basic_block bb) if (TREE_CODE (arg) != SSA_NAME || virtual_operand_p (arg)) continue; - tree val = op_with_constant_singleton_value_range (arg); + value_range *vr = evrp_range_analyzer.get_value_range (arg); + tree val = value_range_constant_singleton (vr); if (val && may_propagate_copy (arg, val)) propagate_value (use_p, val); } @@ -245,7 +242,7 @@ evrp_dom_walker::cleanup (void) if (dump_file) { fprintf (dump_file, "\nValue ranges after Early VRP:\n\n"); - evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file); + evrp_range_analyzer.dump_all_value_ranges (dump_file); fprintf (dump_file, "\n"); } diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 24f013a9402..9eeebedfaed 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -40,80 +40,81 @@ class vr_values vr_values (void); ~vr_values (void); - /* Value range array. After propagation, VR_VALUE[I] holds the range - of values that SSA name N_I may take. */ - unsigned int num_vr_values; - value_range **vr_value; - bool values_propagated; + value_range *get_value_range (const_tree); - /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the - number of executable edges we saw the last time we visited the - node. */ - int *vr_phi_edge_counts; + void set_vr_value (tree, value_range *); + void set_defs_to_varying (gimple *); + bool update_value_range (const_tree, value_range *); + tree op_with_constant_singleton_value_range (tree); + void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree); + tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *); + void dump_all_value_ranges (FILE *); + + void extract_range_for_var_from_comparison_expr (tree, enum tree_code, + tree, tree, value_range *); + void extract_range_from_phi_node (gphi *, value_range *); + void extract_range_basic (value_range *, gimple *); + void extract_range_from_assignment (value_range *, gassign *); + void extract_range_from_stmt (gimple *, edge *, tree *, value_range *); + + void vrp_visit_cond_stmt (gcond *, edge *); + + void simplify_cond_using_ranges_2 (gcond *); + bool simplify_stmt_using_ranges (gimple_stmt_iterator *); + + /* This probably belongs in the lattice rather than in here. */ + bool values_propagated; /* Allocation pools for tree-vrp allocations. */ object_allocator<value_range> vrp_value_range_pool; - bitmap_obstack vrp_equiv_obstack; - value_range *get_value_range (const_tree); - void set_vr_value (tree, value_range *); - - void set_defs_to_varying (gimple *); - bool update_value_range (const_tree, value_range *); + private: + bitmap_obstack vrp_equiv_obstack; void add_equivalence (bitmap *, const_tree); bool vrp_stmt_computes_nonzero (gimple *); - tree op_with_constant_singleton_value_range (tree); bool op_with_boolean_value_range_p (tree); bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *); - void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree); value_range get_vr_for_comparison (int); tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool); tree compare_names (enum tree_code, tree, tree, bool *); bool two_valued_val_range_p (tree, tree *, tree *); - tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code, tree, tree, bool *); tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code, tree, tree, bool, bool *, bool *); - tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *); - - - void dump_all_value_ranges (FILE *); - - void extract_range_for_var_from_comparison_expr (tree, enum tree_code, - tree, tree, value_range *); void extract_range_from_assert (value_range *, tree); void extract_range_from_ssa_name (value_range *, tree); void extract_range_from_binary_expr (value_range *, enum tree_code, tree, tree, tree); void extract_range_from_unary_expr (value_range *, enum tree_code, tree, tree); - void extract_range_from_phi_node (gphi *, value_range *); void extract_range_from_cond_expr (value_range *, gassign *); - void extract_range_basic (value_range *, gimple *); - void extract_range_from_assignment (value_range *, gassign *); - void extract_range_from_stmt (gimple *, edge *, tree *, value_range *); void extract_range_from_comparison (value_range *, enum tree_code, tree, tree, tree); - void vrp_visit_assignment_or_call (gimple*, tree *, value_range *); void vrp_visit_switch_stmt (gswitch *, edge *); - void vrp_visit_cond_stmt (gcond *, edge *); - 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 *); bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_cond_using_ranges_1 (gcond *); - void simplify_cond_using_ranges_2 (gcond *); bool simplify_switch_using_ranges (gswitch *); bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *); - bool simplify_stmt_using_ranges (gimple_stmt_iterator *); + + /* Value range array. After propagation, VR_VALUE[I] holds the range + of values that SSA name N_I may take. */ + unsigned int num_vr_values; + value_range **vr_value; + + /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the + number of executable edges we saw the last time we visited the + node. */ + int *vr_phi_edge_counts; }; #define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }
diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c index 9e581834d08..c3877791a5e 100644 --- a/gcc/gimple-ssa-evrp-analyze.c +++ b/gcc/gimple-ssa-evrp-analyze.c @@ -53,6 +53,7 @@ evrp_range_analyzer::evrp_range_analyzer () : stack (10) FOR_EACH_EDGE (e, ei, bb->preds) e->flags |= EDGE_EXECUTABLE; } + vr_values = new class vr_values; } void @@ -73,8 +74,8 @@ evrp_range_analyzer::try_find_new_range (tree name, value_range *old_vr = get_value_range (name); /* Discover VR when condition is true. */ - extract_range_for_var_from_comparison_expr (name, code, op, - limit, &vr); + vr_values->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.type == VR_RANGE || vr.type == VR_ANTI_RANGE) @@ -83,7 +84,7 @@ evrp_range_analyzer::try_find_new_range (tree name, && vrp_operand_equal_p (old_vr->min, vr.min) && vrp_operand_equal_p (old_vr->max, vr.max)) return NULL; - value_range *new_vr = vr_values.vrp_value_range_pool.allocate (); + value_range *new_vr = vr_values->vrp_value_range_pool.allocate (); *new_vr = vr; return new_vr; } @@ -167,7 +168,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) value_range vr_result = VR_INITIALIZER; bool interesting = stmt_interesting_for_vrp (phi); if (!has_unvisited_preds && interesting) - extract_range_from_phi_node (phi, &vr_result); + vr_values->extract_range_from_phi_node (phi, &vr_result); else { set_value_range_to_varying (&vr_result); @@ -179,9 +180,9 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) if (interesting && (l = loop_containing_stmt (phi)) && l->header == gimple_bb (phi)) - adjust_range_with_scev (&vr_result, l, phi, lhs); + vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs); } - update_value_range (lhs, &vr_result); + vr_values->update_value_range (lhs, &vr_result); /* Set the SSA with the value range. */ if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) @@ -216,11 +217,11 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) { edge taken_edge; value_range vr = VR_INITIALIZER; - extract_range_from_stmt (stmt, &taken_edge, &output, &vr); + vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr); if (output && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)) { - update_value_range (output, &vr); + vr_values->update_value_range (output, &vr); /* Set the SSA with the value range. */ if (INTEGRAL_TYPE_P (TREE_TYPE (output))) @@ -240,10 +241,10 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) set_ptr_nonnull (output); } else - set_defs_to_varying (stmt); + vr_values->set_defs_to_varying (stmt); } else - set_defs_to_varying (stmt); + vr_values->set_defs_to_varying (stmt); /* See if we can derive a range for any of STMT's operands. */ tree op; @@ -319,7 +320,7 @@ evrp_range_analyzer::push_value_range (tree var, value_range *vr) fprintf (dump_file, "\n"); } stack.safe_push (std::make_pair (var, get_value_range (var))); - set_vr_value (var, vr); + vr_values->set_vr_value (var, vr); } /* Pop the Value Range from the vrp_stack and update VAR with it. */ @@ -337,7 +338,7 @@ evrp_range_analyzer::pop_value_range (tree var) dump_value_range (dump_file, vr); fprintf (dump_file, "\n"); } - set_vr_value (var, vr); + vr_values->set_vr_value (var, vr); stack.pop (); return vr; } diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h index 2e6c609c45b..b60bba848cc 100644 --- a/gcc/gimple-ssa-evrp-analyze.h +++ b/gcc/gimple-ssa-evrp-analyze.h @@ -24,16 +24,46 @@ class evrp_range_analyzer { public: evrp_range_analyzer (void); - ~evrp_range_analyzer (void) { stack.release (); } + ~evrp_range_analyzer (void) + { + if (vr_values) + delete vr_values; + stack.release (); + } void enter (basic_block); void leave (basic_block); void record_ranges_from_stmt (gimple *); - class vr_values vr_values; + /* Main interface to retrieve range information. */ + value_range *get_value_range (const_tree op) + { return vr_values->get_value_range (op); } + + /* 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) + { return vr_values->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 (bool transfer) + { + class vr_values *x = vr_values; + if (transfer) + vr_values = NULL; + return x; + } private: DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer); + class vr_values *vr_values; + void push_value_range (tree var, value_range *vr); value_range *pop_value_range (tree var); value_range *try_find_new_range (tree, tree op, tree_code code, tree limit); @@ -42,30 +72,6 @@ class evrp_range_analyzer /* STACK holds the old VR. */ auto_vec<std::pair <tree, value_range*> > stack; - - /* Temporary delegators. */ - value_range *get_value_range (const_tree op) - { return vr_values.get_value_range (op); } - bool update_value_range (const_tree op, value_range *vr) - { return vr_values.update_value_range (op, vr); } - void extract_range_from_phi_node (gphi *phi, value_range *vr) - { vr_values.extract_range_from_phi_node (phi, vr); } - void adjust_range_with_scev (value_range *vr, struct loop *loop, - gimple *stmt, tree var) - { vr_values.adjust_range_with_scev (vr, loop, stmt, var); } - void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p, - tree *output_p, value_range *vr) - { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); } - void set_defs_to_varying (gimple *stmt) - { return vr_values.set_defs_to_varying (stmt); } - void set_vr_value (tree name, value_range *vr) - { vr_values.set_vr_value (name, vr); } - void extract_range_for_var_from_comparison_expr (tree var, - enum tree_code cond_code, - tree op, tree limit, - value_range *vr_p) - { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code, - op, limit, vr_p); } }; #endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */ diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 27a983dd9ae..a554cf9e834 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -46,8 +46,11 @@ class evrp_folder : public substitute_and_fold_engine { public: tree get_value (tree) FINAL OVERRIDE; - + evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { } class vr_values *vr_values; + + private: + DISABLE_COPY_AND_ASSIGN (evrp_folder); }; tree @@ -63,7 +66,9 @@ evrp_folder::get_value (tree op) class evrp_dom_walker : public dom_walker { public: - evrp_dom_walker () : dom_walker (CDI_DOMINATORS) + evrp_dom_walker () + : dom_walker (CDI_DOMINATORS), + evrp_folder (evrp_range_analyzer.get_vr_values (false)) { need_eh_cleanup = BITMAP_ALLOC (NULL); } @@ -82,14 +87,7 @@ public: auto_vec<gimple *> stmts_to_remove; class evrp_range_analyzer evrp_range_analyzer; - - /* Temporary delegators. */ - value_range *get_value_range (const_tree op) - { return evrp_range_analyzer.vr_values.get_value_range (op); } - tree op_with_constant_singleton_value_range (tree op) - { return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); } - void vrp_visit_cond_stmt (gcond *cond, edge *e) - { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); } + class evrp_folder evrp_folder; }; edge @@ -108,8 +106,9 @@ evrp_dom_walker::before_dom_children (basic_block bb) if (virtual_operand_p (lhs)) continue; + value_range *vr = evrp_range_analyzer.get_value_range (lhs); /* Mark PHIs whose lhs we fully propagate for removal. */ - tree val = op_with_constant_singleton_value_range (lhs); + tree val = value_range_constant_singleton (vr); if (val && may_propagate_copy (lhs, val)) { stmts_to_remove.safe_push (phi); @@ -139,7 +138,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) if (gcond *cond = dyn_cast <gcond *> (stmt)) { - vrp_visit_cond_stmt (cond, &taken_edge); + evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge); if (taken_edge) { if (taken_edge->flags & EDGE_TRUE_VALUE) @@ -153,16 +152,15 @@ evrp_dom_walker::before_dom_children (basic_block bb) } else if (stmt_interesting_for_vrp (stmt)) { - value_range vr = VR_INITIALIZER; output = get_output_for_vrp (stmt); if (output) { tree val; - vr = *get_value_range (output); + value_range *vr = evrp_range_analyzer.get_value_range (output); /* Mark stmts whose output we fully propagate for removal. */ - if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE) - && (val = op_with_constant_singleton_value_range (output)) + if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE) + && (val = value_range_constant_singleton (vr)) && may_propagate_copy (output, val) && !stmt_could_throw_p (stmt) && !gimple_has_side_effects (stmt)) @@ -174,8 +172,6 @@ evrp_dom_walker::before_dom_children (basic_block bb) } /* Try folding stmts with the VR discovered. */ - class evrp_folder evrp_folder; - evrp_folder.vr_values = &evrp_range_analyzer.vr_values; bool did_replace = evrp_folder.replace_uses_in (stmt); if (fold_stmt (&gsi, follow_single_use_edges) || did_replace) @@ -222,7 +218,8 @@ evrp_dom_walker::before_dom_children (basic_block bb) if (TREE_CODE (arg) != SSA_NAME || virtual_operand_p (arg)) continue; - tree val = op_with_constant_singleton_value_range (arg); + value_range *vr = evrp_range_analyzer.get_value_range (arg); + tree val = value_range_constant_singleton (vr); if (val && may_propagate_copy (arg, val)) propagate_value (use_p, val); } @@ -245,7 +242,7 @@ evrp_dom_walker::cleanup (void) if (dump_file) { fprintf (dump_file, "\nValue ranges after Early VRP:\n\n"); - evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file); + evrp_range_analyzer.dump_all_value_ranges (dump_file); fprintf (dump_file, "\n"); } diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 24f013a9402..9eeebedfaed 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -40,80 +40,81 @@ class vr_values vr_values (void); ~vr_values (void); - /* Value range array. After propagation, VR_VALUE[I] holds the range - of values that SSA name N_I may take. */ - unsigned int num_vr_values; - value_range **vr_value; - bool values_propagated; + value_range *get_value_range (const_tree); - /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the - number of executable edges we saw the last time we visited the - node. */ - int *vr_phi_edge_counts; + void set_vr_value (tree, value_range *); + void set_defs_to_varying (gimple *); + bool update_value_range (const_tree, value_range *); + tree op_with_constant_singleton_value_range (tree); + void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree); + tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *); + void dump_all_value_ranges (FILE *); + + void extract_range_for_var_from_comparison_expr (tree, enum tree_code, + tree, tree, value_range *); + void extract_range_from_phi_node (gphi *, value_range *); + void extract_range_basic (value_range *, gimple *); + void extract_range_from_assignment (value_range *, gassign *); + void extract_range_from_stmt (gimple *, edge *, tree *, value_range *); + + void vrp_visit_cond_stmt (gcond *, edge *); + + void simplify_cond_using_ranges_2 (gcond *); + bool simplify_stmt_using_ranges (gimple_stmt_iterator *); + + /* This probably belongs in the lattice rather than in here. */ + bool values_propagated; /* Allocation pools for tree-vrp allocations. */ object_allocator<value_range> vrp_value_range_pool; - bitmap_obstack vrp_equiv_obstack; - value_range *get_value_range (const_tree); - void set_vr_value (tree, value_range *); - - void set_defs_to_varying (gimple *); - bool update_value_range (const_tree, value_range *); + private: + bitmap_obstack vrp_equiv_obstack; void add_equivalence (bitmap *, const_tree); bool vrp_stmt_computes_nonzero (gimple *); - tree op_with_constant_singleton_value_range (tree); bool op_with_boolean_value_range_p (tree); bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *); - void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree); value_range get_vr_for_comparison (int); tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool); tree compare_names (enum tree_code, tree, tree, bool *); bool two_valued_val_range_p (tree, tree *, tree *); - tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code, tree, tree, bool *); tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code, tree, tree, bool, bool *, bool *); - tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *); - - - void dump_all_value_ranges (FILE *); - - void extract_range_for_var_from_comparison_expr (tree, enum tree_code, - tree, tree, value_range *); void extract_range_from_assert (value_range *, tree); void extract_range_from_ssa_name (value_range *, tree); void extract_range_from_binary_expr (value_range *, enum tree_code, tree, tree, tree); void extract_range_from_unary_expr (value_range *, enum tree_code, tree, tree); - void extract_range_from_phi_node (gphi *, value_range *); void extract_range_from_cond_expr (value_range *, gassign *); - void extract_range_basic (value_range *, gimple *); - void extract_range_from_assignment (value_range *, gassign *); - void extract_range_from_stmt (gimple *, edge *, tree *, value_range *); void extract_range_from_comparison (value_range *, enum tree_code, tree, tree, tree); - void vrp_visit_assignment_or_call (gimple*, tree *, value_range *); void vrp_visit_switch_stmt (gswitch *, edge *); - void vrp_visit_cond_stmt (gcond *, edge *); - 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 *); bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_cond_using_ranges_1 (gcond *); - void simplify_cond_using_ranges_2 (gcond *); bool simplify_switch_using_ranges (gswitch *); bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *, gimple *); bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *); - bool simplify_stmt_using_ranges (gimple_stmt_iterator *); + + /* Value range array. After propagation, VR_VALUE[I] holds the range + of values that SSA name N_I may take. */ + unsigned int num_vr_values; + value_range **vr_value; + + /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the + number of executable edges we saw the last time we visited the + node. */ + int *vr_phi_edge_counts; }; #define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }