aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-propagate.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-05-05 13:45:39 +0200
committerAldy Hernandez <aldyh@redhat.com>2020-06-10 15:09:37 +0200
commit1396fa5b91cfa0b3708ec9df33c0bb84386081d6 (patch)
treed5eb6c1149ef54835dcc6b0d2d7be8fa28de1d03 /gcc/tree-ssa-propagate.c
parent8b6731e674c76cb48a417f2eef74ced92a17f469 (diff)
downloadgcc-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.c113
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;
}