diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-05-05 13:45:39 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-10 15:09:37 +0200 |
commit | 1396fa5b91cfa0b3708ec9df33c0bb84386081d6 (patch) | |
tree | d5eb6c1149ef54835dcc6b0d2d7be8fa28de1d03 /gcc/tree-ssa-propagate.c | |
parent | 8b6731e674c76cb48a417f2eef74ced92a17f469 (diff) | |
download | gcc-1396fa5b91cfa0b3708ec9df33c0bb84386081d6.zip gcc-1396fa5b91cfa0b3708ec9df33c0bb84386081d6.tar.gz gcc-1396fa5b91cfa0b3708ec9df33c0bb84386081d6.tar.bz2 |
Merge evrp uses of substitute_and_fold_engine into the engine itself.
This patch merges the evrp uses of the substitute and fold engine into
the engine itself, at least the parts that can be re-used by other
engine uses. It also adds a context parameter to get_value() for
further use.
gcc/
* gimple-loop-versioning.cc (loop_versioning::name_prop::get_value):
Add stmt parameter.
* gimple-ssa-evrp.c (class evrp_folder): New.
(class evrp_dom_walker): Remove.
(execute_early_vrp): Use evrp_folder instead of evrp_dom_walker.
* tree-ssa-ccp.c (ccp_folder::get_value): Add stmt parameter.
* tree-ssa-copy.c (copy_folder::get_value): Same.
* tree-ssa-propagate.c (substitute_and_fold_engine::replace_uses_in):
Pass stmt to get_value.
(substitute_and_fold_engine::replace_phi_args_in): Same.
(substitute_and_fold_dom_walker::after_dom_children): Call
post_fold_bb.
(substitute_and_fold_dom_walker::foreach_new_stmt_in_bb): New.
(substitute_and_fold_dom_walker::propagate_into_phi_args): New.
(substitute_and_fold_dom_walker::before_dom_children): Adjust to
call virtual functions for folding, pre_folding, and post folding.
Call get_value with PHI. Tweak dump.
* tree-ssa-propagate.h (class substitute_and_fold_engine):
New argument to get_value.
New virtual function pre_fold_bb.
New virtual function post_fold_bb.
New virtual function pre_fold_stmt.
New virtual function post_new_stmt.
New function propagate_into_phi_args.
* tree-vrp.c (vrp_folder::get_value): Add stmt argument.
* vr-values.c (vr_values::extract_range_from_stmt): Adjust dump
output.
(vr_values::fold_cond): New.
(vr_values::simplify_cond_using_ranges_1): Call fold_cond.
* vr-values.h (class vr_values): Add
simplify_cond_using_ranges_when_edge_is_known.
gcc/testsuite/
* gcc.dg/tree-ssa/ssa-dse-30.c: Adjust test for folding of
memmove happening later.
Diffstat (limited to 'gcc/tree-ssa-propagate.c')
-rw-r--r-- | gcc/tree-ssa-propagate.c | 113 |
1 files changed, 95 insertions, 18 deletions
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 2fad247..4fda296 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); + tree val = get_value (tuse, stmt); if (val == tuse || val == NULL_TREE) continue; @@ -903,19 +903,13 @@ substitute_and_fold_engine::replace_phi_args_in (gphi *phi) size_t i; bool replaced = false; - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Folding PHI node: "); - print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); - } - for (i = 0; i < gimple_phi_num_args (phi); i++) { tree arg = gimple_phi_arg_def (phi, i); if (TREE_CODE (arg) == SSA_NAME) { - tree val = get_value (arg); + tree val = get_value (arg, phi); if (val && val != arg && may_propagate_copy (arg, val)) { @@ -983,7 +977,10 @@ public: } virtual edge before_dom_children (basic_block); - virtual void after_dom_children (basic_block) {} + virtual void after_dom_children (basic_block bb) + { + substitute_and_fold_engine->post_fold_bb (bb); + } bool something_changed; vec<gimple *> stmts_to_remove; @@ -991,11 +988,64 @@ public: bitmap need_eh_cleanup; class substitute_and_fold_engine *substitute_and_fold_engine; + +private: + void foreach_new_stmt_in_bb (gimple_stmt_iterator old_gsi, + gimple_stmt_iterator new_gsi); }; +/* Call post_new_stmt for each each new statement that has been added + to the current BB. OLD_GSI is the statement iterator before the BB + changes ocurred. NEW_GSI is the iterator which may contain new + statements. */ + +void +substitute_and_fold_dom_walker::foreach_new_stmt_in_bb + (gimple_stmt_iterator old_gsi, + gimple_stmt_iterator new_gsi) +{ + basic_block bb = gsi_bb (new_gsi); + if (gsi_end_p (old_gsi)) + old_gsi = gsi_start_bb (bb); + else + gsi_next (&old_gsi); + while (gsi_stmt (old_gsi) != gsi_stmt (new_gsi)) + { + gimple *stmt = gsi_stmt (old_gsi); + substitute_and_fold_engine->post_new_stmt (stmt); + gsi_next (&old_gsi); + } +} + +void +substitute_and_fold_engine::propagate_into_phi_args (basic_block bb) +{ + edge e; + edge_iterator ei; + /* Visit BB successor PHI nodes and replace PHI args. */ + FOR_EACH_EDGE (e, ei, bb->succs) + { + for (gphi_iterator gpi = gsi_start_phis (e->dest); + !gsi_end_p (gpi); gsi_next (&gpi)) + { + gphi *phi = gpi.phi (); + use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e); + tree arg = USE_FROM_PTR (use_p); + if (TREE_CODE (arg) != SSA_NAME + || virtual_operand_p (arg)) + continue; + tree val = get_value (arg, phi); + if (val && may_propagate_copy (arg, val)) + propagate_value (use_p, val); + } + } +} + edge substitute_and_fold_dom_walker::before_dom_children (basic_block bb) { + substitute_and_fold_engine->pre_fold_bb (bb); + /* Propagate known values into PHI nodes. */ for (gphi_iterator i = gsi_start_phis (bb); !gsi_end_p (i); @@ -1005,13 +1055,24 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) tree res = gimple_phi_result (phi); if (virtual_operand_p (res)) continue; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Folding PHI node: "); + print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); + } if (res && TREE_CODE (res) == SSA_NAME) { - tree sprime = substitute_and_fold_engine->get_value (res); + tree sprime = substitute_and_fold_engine->get_value (res, phi); if (sprime && sprime != res && may_propagate_copy (res, sprime)) { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Queued PHI for removal. Folds to: "); + print_generic_expr (dump_file, sprime); + fprintf (dump_file, "\n"); + } stmts_to_remove.safe_push (phi); continue; } @@ -1028,12 +1089,20 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) bool did_replace; gimple *stmt = gsi_stmt (i); + substitute_and_fold_engine->pre_fold_stmt (stmt); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Folding statement: "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + /* No point propagating into a stmt we have a value for we can propagate into all uses. Mark it for removal instead. */ tree lhs = gimple_get_lhs (stmt); if (lhs && TREE_CODE (lhs) == SSA_NAME) { - tree sprime = substitute_and_fold_engine->get_value (lhs); + tree sprime = substitute_and_fold_engine->get_value (lhs, stmt); if (sprime && sprime != lhs && may_propagate_copy (lhs, sprime) @@ -1043,6 +1112,12 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) && (!is_gimple_assign (stmt) || gimple_assign_rhs_code (stmt) != ASSERT_EXPR)) { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Queued stmt for removal. Folds to: "); + print_generic_expr (dump_file, sprime); + fprintf (dump_file, "\n"); + } stmts_to_remove.safe_push (stmt); continue; } @@ -1051,12 +1126,6 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) /* Replace the statement with its folded version and mark it folded. */ did_replace = false; - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Folding statement: "); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - } - gimple *old_stmt = stmt; bool was_noreturn = (is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)); @@ -1064,6 +1133,9 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) /* Replace real uses in the statement. */ did_replace |= substitute_and_fold_engine->replace_uses_in (stmt); + gimple_stmt_iterator prev_gsi = i; + gsi_prev (&prev_gsi); + /* If we made a replacement, fold the statement. */ if (did_replace) { @@ -1084,7 +1156,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) specific information. Do this before propagating into the stmt to not disturb pass specific information. */ update_stmt_if_modified (stmt); - if (substitute_and_fold_engine->fold_stmt(&i)) + if (substitute_and_fold_engine->fold_stmt (&i)) { did_replace = true; prop_stats.num_stmts_folded++; @@ -1115,6 +1187,8 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) /* Now cleanup. */ if (did_replace) { + foreach_new_stmt_in_bb (prev_gsi, i); + /* If we cleaned up EH information from the statement, remove EH edges. */ if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) @@ -1153,6 +1227,9 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) fprintf (dump_file, "Not folded\n"); } } + + substitute_and_fold_engine->propagate_into_phi_args (bb); + return NULL; } |