aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-propagate.c
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
commita926878ddbd5a98b272c22171ce58663fc04c3e0 (patch)
tree86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/tree-ssa-propagate.c
parent542730f087133690b47e036dfd43eb0db8a650ce (diff)
parent07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff)
downloadgcc-devel/autopar_devel.zip
gcc-devel/autopar_devel.tar.gz
gcc-devel/autopar_devel.tar.bz2
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/tree-ssa-propagate.c')
-rw-r--r--gcc/tree-ssa-propagate.c121
1 files changed, 103 insertions, 18 deletions
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 2fad247..1e05728 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,72 @@ 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);
+ }
+}
+
+bool
+substitute_and_fold_engine::propagate_into_phi_args (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+ bool propagated = false;
+
+ /* 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
+ && is_gimple_min_invariant (val)
+ && may_propagate_copy (arg, val))
+ {
+ propagate_value (use_p, val);
+ propagated = true;
+ }
+ }
+ }
+ return propagated;
+}
+
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 +1063,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 +1097,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 +1120,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 +1134,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 +1141,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 +1164,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 +1195,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 +1235,9 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
fprintf (dump_file, "Not folded\n");
}
}
+
+ something_changed |= substitute_and_fold_engine->propagate_into_phi_args (bb);
+
return NULL;
}