While thinking about how to implement the rest of the copy prop and makes sure not to introduce some compile time problems, optimize_agr_copyprop should be changed into a forwproping rather than looking backwards.
Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: * tree-ssa-forwprop.cc (optimize_agr_copyprop): Change into a forward looking (looking at vdef's uses) instead of a back looking (vuse's def). Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> --- gcc/tree-ssa-forwprop.cc | 121 +++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 43b1c9d696f..2dc77ccba1d 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -1344,12 +1344,12 @@ optimize_memcpy_to_memset (gimple_stmt_iterator *gsip, tree dest, tree src, tree return true; } /* Optimizes - a = c; - b = a; + DEST = SRC; + DEST2 = DEST; # DEST2 = SRC2; into - a = c; - b = c; - GSIP is the second statement and SRC is the common + DEST = SRC; + DEST2 = SRC; + GSIP is the first statement and SRC is the common between the statements. */ static bool @@ -1365,65 +1365,64 @@ optimize_agr_copyprop (gimple_stmt_iterator *gsip) if (operand_equal_p (dest, src, 0)) return false; - tree vuse = gimple_vuse (stmt); - /* If the vuse is the default definition, then there is no store beforehand. */ - if (SSA_NAME_IS_DEFAULT_DEF (vuse)) - return false; - gimple *defstmt = SSA_NAME_DEF_STMT (vuse); - if (!gimple_assign_load_p (defstmt) - || !gimple_store_p (defstmt)) - return false; - if (gimple_has_volatile_ops (defstmt)) - return false; - - tree dest2 = gimple_assign_lhs (defstmt); - tree src2 = gimple_assign_rhs1 (defstmt); - - /* If the original store is `src2 = src2;` skip over it. */ - if (operand_equal_p (src2, dest2, 0)) - return false; - if (!operand_equal_p (src, dest2, 0)) - return false; - - - /* For 2 memory refences and using a temporary to do the copy, - don't remove the temporary as the 2 memory references might overlap. - Note t does not need to be decl as it could be field. - See PR 22237 for full details. - E.g. - t = *a; - *b = t; - Cannot be convert into - t = *a; - *b = *a; - Though the following is allowed to be done: - t = *a; - *a = t; - And convert it into: - t = *a; - *a = *a; - */ - if (!operand_equal_p (src2, dest, 0) - && !DECL_P (dest) && !DECL_P (src2)) - return false; - - if (dump_file && (dump_flags & TDF_DETAILS)) + tree vdef = gimple_vdef (stmt); + imm_use_iterator iter; + gimple *use_stmt; + bool changed = false; + FOR_EACH_IMM_USE_STMT (use_stmt, iter, vdef) { - fprintf (dump_file, "Simplified\n "); - print_gimple_stmt (dump_file, stmt, 0, dump_flags); - fprintf (dump_file, "after previous\n "); - print_gimple_stmt (dump_file, defstmt, 0, dump_flags); - } - gimple_assign_set_rhs_from_tree (gsip, unshare_expr (src2)); - update_stmt (stmt); + if (!gimple_assign_load_p (use_stmt) + || !gimple_store_p (use_stmt)) + continue; + if (gimple_has_volatile_ops (use_stmt)) + continue; + tree dest2 = gimple_assign_lhs (use_stmt); + tree src2 = gimple_assign_rhs1 (use_stmt); + /* If the new store is `src2 = src2;` skip over it. */ + if (operand_equal_p (src2, dest2, 0)) + continue; + if (!operand_equal_p (dest, src2, 0)) + continue; + /* For 2 memory refences and using a temporary to do the copy, + don't remove the temporary as the 2 memory references might overlap. + Note t does not need to be decl as it could be field. + See PR 22237 for full details. + E.g. + t = *a; #DEST = SRC; + *b = t; #DEST2 = SRC2; + Cannot be convert into + t = *a; + *b = *a; + Though the following is allowed to be done: + t = *a; + *a = t; + And convert it into: + t = *a; + *a = *a; + */ + if (!operand_equal_p (dest2, src, 0) + && !DECL_P (dest2) && !DECL_P (src)) + continue; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Simplified\n "); + print_gimple_stmt (dump_file, use_stmt, 0, dump_flags); + fprintf (dump_file, "after previous\n "); + print_gimple_stmt (dump_file, stmt, 0, dump_flags); + } + gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt); + gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (src)); + update_stmt (use_stmt); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "into\n "); - print_gimple_stmt (dump_file, stmt, 0, dump_flags); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "into\n "); + print_gimple_stmt (dump_file, use_stmt, 0, dump_flags); + } + statistics_counter_event (cfun, "copy prop for aggregate", 1); + changed = true; } - statistics_counter_event (cfun, "copy prop for aggregate", 1); - return true; + return changed; } /* *GSI_P is a GIMPLE_CALL to a builtin function. -- 2.43.0