Richard, This patch factors out gimple_dont_merge_p from gimple_equal_p and find_duplicate.
Bootstrapped and regtested on x86_64. OK for trunk? Thanks, - Tom 2013-11-06 Tom de Vries <t...@codesourcery.com> * tree-ssa-tail-merge.c (gimple_dont_merge_p): Factor function out of ... (gimple_equal_p): ... here, and ... (find_duplicate): ... here. Use gimple_dont_merge_p.
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c index 00dd071..4223094 100644 --- a/gcc/tree-ssa-tail-merge.c +++ b/gcc/tree-ssa-tail-merge.c @@ -1075,6 +1075,38 @@ set_cluster (basic_block bb1, basic_block bb2) gcc_unreachable (); } +/* Return true if tail-merge should refrain from merging STMT with another + stmt. */ + +static bool +gimple_dont_merge_p (gimple stmt) +{ + switch (gimple_code (stmt)) + { + case GIMPLE_CALL: + /* Eventually, we'll significantly complicate the CFG by adding + back edges to properly model the effects of transaction restart. + For the bulk of optimization this does not matter, but what we + cannot recover from is tail merging blocks between two separate + transactions. Avoid that by making commit not match. */ + if (gimple_call_builtin_p (stmt, BUILT_IN_TM_COMMIT)) + return true; + + /* We cannot tail-merge the builtins that end transactions. + ??? The alternative being unsharing of BBs in the tm_init pass. */ + if (flag_tm + && (gimple_call_flags (stmt) & ECF_TM_BUILTIN) + && is_tm_ending_fndecl (gimple_call_fndecl (stmt))) + return true; + + break; + default: + break; + } + + return false; +} + /* Return true if gimple statements S1 and S2 are equal. Gimple_bb (s1) and gimple_bb (s2) are members of SAME_SUCC. */ @@ -1099,14 +1131,6 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2) if (!gimple_call_same_target_p (s1, s2)) return false; - /* Eventually, we'll significantly complicate the CFG by adding - back edges to properly model the effects of transaction restart. - For the bulk of optimization this does not matter, but what we - cannot recover from is tail merging blocks between two separate - transactions. Avoid that by making commit not match. */ - if (gimple_call_builtin_p (s1, BUILT_IN_TM_COMMIT)) - return false; - for (i = 0; i < gimple_call_num_args (s1); ++i) { t1 = gimple_call_arg (s1, i); @@ -1220,15 +1244,15 @@ find_duplicate (same_succ same_succ, basic_block bb1, basic_block bb2) gimple stmt1 = gsi_stmt (gsi1); gimple stmt2 = gsi_stmt (gsi2); - if (!gimple_equal_p (same_succ, stmt1, stmt2)) + /* This should be tested also on local statements, but given the current + content of gimple_dont_merge_p, that's not necessary atm. What could + be better is to blacklist the bb containing the stmt, when encountering + the stmt f.i. in same_succ_hash. */ + if (gimple_dont_merge_p (stmt1) + || gimple_dont_merge_p (stmt2)) return; - // We cannot tail-merge the builtins that end transactions. - // ??? The alternative being unsharing of BBs in the tm_init pass. - if (flag_tm - && is_gimple_call (stmt1) - && (gimple_call_flags (stmt1) & ECF_TM_BUILTIN) - && is_tm_ending_fndecl (gimple_call_fndecl (stmt1))) + if (!gimple_equal_p (same_succ, stmt1, stmt2)) return; gsi_prev_nondebug (&gsi1);