From: Jeff Law Date: Wed, 22 Nov 2017 20:31:14 +0000 (-0700) Subject: * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a5de02e9e3efdcdacc5dc100b61d1fd45e719955;p=gcc.git * 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. From-SVN: r255074 --- 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 + + * 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 * 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 > 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 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 (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 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 }