From 6566b0fb86addb5c28d3ff8b2631f7f9516d4054 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 17 Nov 2017 10:34:36 -0700 Subject: [PATCH] gimple-ssa-evrp.c (class evrp_range_analyzer): New class extracted from evrp_dom_walker class. * gimple-ssa-evrp.c (class evrp_range_analyzer): New class extracted from evrp_dom_walker class. Various methods moved into new class. (evrp_range_analyzer::evrp_range_analyzer): Constructor for new class. (evrp_range_analyzer::enter): New method. (evrp_range_analyzer::leave): New method. (evrp_dom_walker): Remove delegators no longer needed by this class. Replace vr_values data member with evrp_range_analyzer From-SVN: r254884 --- gcc/ChangeLog | 8 ++ gcc/gimple-ssa-evrp.c | 179 ++++++++++++++++++++++++------------------ 2 files changed, 109 insertions(+), 78 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 54fa3a0e4f6..8dde55ce2f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2017-11-17 Jeff Law + * gimple-ssa-evrp.c (class evrp_range_analyzer): New class extracted + from evrp_dom_walker class. Various methods moved into new class. + (evrp_range_analyzer::evrp_range_analyzer): Constructor for new class. + (evrp_range_analyzer::enter): New method. + (evrp_range_analyzer::leave): New method. + (evrp_dom_walker): Remove delegators no longer needed by this class. + Replace vr_values data member with evrp_range_analyzer + * gimple-ssa-evrp.c (evrp_dom_walker::record_ranges_from_phis): New method extracted from evrp_dom_walker::before_dom_children. (evrp_dom_walker::record_ranges_from_stmt): Likewise. diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index c2ba904b4b8..76eeb13c63e 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -55,6 +55,69 @@ evrp_folder::get_value (tree op) return vr_values->op_with_constant_singleton_value_range (op); } +class evrp_range_analyzer +{ + public: + evrp_range_analyzer (void); + ~evrp_range_analyzer (void) { stack.release (); } + + void enter (basic_block); + void leave (basic_block); + void record_ranges_from_stmt (gimple *); + + class vr_values vr_values; + + private: + DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer); + 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); + void record_ranges_from_incoming_edge (basic_block); + void record_ranges_from_phis (basic_block); + + /* 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); } +}; + +evrp_range_analyzer::evrp_range_analyzer () : stack (10) +{ + edge e; + edge_iterator ei; + basic_block bb; + + FOR_EACH_BB_FN (bb, cfun) + { + bb->flags &= ~BB_VISITED; + FOR_EACH_EDGE (e, ei, bb->preds) + e->flags |= EDGE_EXECUTABLE; + } +} + + /* evrp_dom_walker visits the basic blocks in the dominance order and set the Value Ranges (VR) for SSA_NAMEs in the scope. Use this VR to discover more VRs. */ @@ -62,8 +125,7 @@ evrp_folder::get_value (tree op) class evrp_dom_walker : public dom_walker { public: - evrp_dom_walker () - : dom_walker (CDI_DOMINATORS), stack (10) + evrp_dom_walker () : dom_walker (CDI_DOMINATORS) { need_eh_cleanup = BITMAP_ALLOC (NULL); } @@ -77,58 +139,33 @@ public: private: DISABLE_COPY_AND_ASSIGN (evrp_dom_walker); - 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); - - void record_ranges_from_incoming_edge (basic_block); - void record_ranges_from_phis (basic_block); - void record_ranges_from_stmt (gimple *); - - /* STACK holds the old VR. */ - auto_vec > stack; bitmap need_eh_cleanup; auto_vec stmts_to_fixup; auto_vec stmts_to_remove; - class vr_values vr_values; + class evrp_range_analyzer evrp_range_analyzer; /* 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 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); } - 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); } + { return evrp_range_analyzer.vr_values.get_value_range (op); } tree op_with_constant_singleton_value_range (tree op) - { return vr_values.op_with_constant_singleton_value_range (op); } - 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 simplify_cond_using_ranges_2 (gcond *stmt) - { vr_values.simplify_cond_using_ranges_2 (stmt); } + { return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); } void vrp_visit_cond_stmt (gcond *cond, edge *e) - { vr_values.vrp_visit_cond_stmt (cond, e); } + { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); } }; -/* Find new range for NAME such that (OP CODE LIMIT) is true. */ +void +evrp_range_analyzer::enter (basic_block bb) +{ + stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL)); + record_ranges_from_incoming_edge (bb); + record_ranges_from_phis (bb); +} +/* Find new range for NAME such that (OP CODE LIMIT) is true. */ value_range * -evrp_dom_walker::try_find_new_range (tree name, - tree op, tree_code code, tree limit) +evrp_range_analyzer::try_find_new_range (tree name, + tree op, tree_code code, tree limit) { value_range vr = VR_INITIALIZER; value_range *old_vr = get_value_range (name); @@ -155,10 +192,8 @@ evrp_dom_walker::try_find_new_range (tree name, then derive ranges implied by traversing that edge. */ void -evrp_dom_walker::record_ranges_from_incoming_edge (basic_block bb) +evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb) { -/* See if there is any new scope is entered with new VR and set that VR to - ssa_name before visiting the statements in the scope. */ edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false); if (pred_e) { @@ -207,10 +242,8 @@ evrp_dom_walker::record_ranges_from_incoming_edge (basic_block bb) } } -/* Record ranges from any PHI nodes at the start of basic block BB. */ - void -evrp_dom_walker::record_ranges_from_phis (basic_block bb) +evrp_range_analyzer::record_ranges_from_phis (basic_block bb) { /* Visit PHI stmts and discover any new VRs possible. */ bool has_unvisited_preds = false; @@ -231,15 +264,10 @@ evrp_dom_walker::record_ranges_from_phis (basic_block bb) tree lhs = PHI_RESULT (phi); if (virtual_operand_p (lhs)) continue; + value_range vr_result = VR_INITIALIZER; bool interesting = stmt_interesting_for_vrp (phi); - if (interesting && dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Visiting PHI node "); - print_gimple_stmt (dump_file, phi, 0); - } - if (!has_unvisited_preds - && interesting) + if (!has_unvisited_preds && interesting) extract_range_from_phi_node (phi, &vr_result); else { @@ -252,7 +280,7 @@ evrp_dom_walker::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); + adjust_range_with_scev (&vr_result, l, phi, lhs); } update_value_range (lhs, &vr_result); @@ -281,7 +309,7 @@ evrp_dom_walker::record_ranges_from_phis (basic_block bb) /* Record any ranges created by statement STMT. */ void -evrp_dom_walker::record_ranges_from_stmt (gimple *stmt) +evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt) { tree output = NULL_TREE; @@ -300,8 +328,8 @@ evrp_dom_walker::record_ranges_from_stmt (gimple *stmt) if (INTEGRAL_TYPE_P (TREE_TYPE (output))) { if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE) - && (TREE_CODE (vr.min) == INTEGER_CST) - && (TREE_CODE (vr.max) == INTEGER_CST)) + && (TREE_CODE (vr.min) == INTEGER_CST) + && (TREE_CODE (vr.max) == INTEGER_CST)) set_range_info (output, vr.type, wi::to_wide (vr.min), wi::to_wide (vr.max)); @@ -372,9 +400,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Visiting BB%d\n", bb->index); - stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL)); - record_ranges_from_incoming_edge (bb); - record_ranges_from_phis (bb); + evrp_range_analyzer.enter (bb); for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi); gsi_next (&gpi)) @@ -411,7 +437,8 @@ evrp_dom_walker::before_dom_children (basic_block bb) print_gimple_stmt (dump_file, stmt, 0); } - record_ranges_from_stmt (stmt); + evrp_range_analyzer.record_ranges_from_stmt (stmt); + if (gcond *cond = dyn_cast (stmt)) { vrp_visit_cond_stmt (cond, &taken_edge); @@ -432,10 +459,10 @@ evrp_dom_walker::before_dom_children (basic_block bb) output = get_output_for_vrp (stmt); if (output) { + tree val; vr = *get_value_range (output); /* Mark stmts whose output we fully propagate for removal. */ - tree val; if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE) && (val = op_with_constant_singleton_value_range (output)) && may_propagate_copy (output, val) @@ -450,7 +477,7 @@ 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 = &vr_values; + 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) @@ -508,10 +535,16 @@ evrp_dom_walker::before_dom_children (basic_block bb) return taken_edge; } +void +evrp_dom_walker::after_dom_children (basic_block bb) +{ + evrp_range_analyzer.leave (bb); +} + /* Restore/pop VRs valid only for BB when we leave BB. */ void -evrp_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) +evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED) { gcc_checking_assert (!stack.is_empty ()); while (stack.last ().first != NULL_TREE) @@ -522,7 +555,7 @@ evrp_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) /* Push the Value Range of VAR to the stack and update it with new VR. */ void -evrp_dom_walker::push_value_range (tree var, value_range *vr) +evrp_range_analyzer::push_value_range (tree var, value_range *vr) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -539,7 +572,7 @@ evrp_dom_walker::push_value_range (tree var, value_range *vr) /* Pop the Value Range from the vrp_stack and update VAR with it. */ value_range * -evrp_dom_walker::pop_value_range (tree var) +evrp_range_analyzer::pop_value_range (tree var) { value_range *vr = stack.last ().second; gcc_checking_assert (var == stack.last ().first); @@ -564,7 +597,7 @@ evrp_dom_walker::cleanup (void) if (dump_file) { fprintf (dump_file, "\nValue ranges after Early VRP:\n\n"); - vr_values.dump_all_value_ranges (dump_file); + evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file); fprintf (dump_file, "\n"); } @@ -610,10 +643,6 @@ evrp_dom_walker::cleanup (void) static unsigned int execute_early_vrp () { - edge e; - edge_iterator ei; - basic_block bb; - /* Ideally this setup code would move into the ctor for the dominator walk. However, this setup can change the number of blocks which invalidates the internal arrays that are set up by the dominator @@ -622,12 +651,6 @@ execute_early_vrp () rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); scev_initialize (); calculate_dominance_info (CDI_DOMINATORS); - FOR_EACH_BB_FN (bb, cfun) - { - bb->flags &= ~BB_VISITED; - FOR_EACH_EDGE (e, ei, bb->preds) - e->flags |= EDGE_EXECUTABLE; - } /* Walk stmts in dominance order and propagate VRP. */ evrp_dom_walker walker; -- 2.30.2