diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 25241277ed4..1afd8c03b61 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-11-14 Tom de Vries + + * trans-mem.c (is_tm_ending): New function. + * gimple.h (is_tm_ending): Declare. + * tree-ssa-tail-merge.c (gimple_equal_p): Remove test on + BUILT_IN_TM_COMMIT. + (find_duplicate): Use is_tm_ending instead of is_tm_ending_fndecl. + 2013-11-14 Tom de Vries * tree-ssa-tail-merge.c (gimple_equal_p): Remove equal variable. diff --git a/gcc/gimple.h b/gcc/gimple.h index db24800b43a..9ed323899a8 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -957,6 +957,7 @@ extern bool infer_nonnull_range (gimple, tree); /* In trans-mem.c. */ extern void diagnose_tm_safe_errors (tree); extern void compute_transaction_bits (void); +extern bool is_tm_ending (gimple); /* In tree-nested.c. */ extern void lower_nested_functions (tree); diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 195380bee4d..748fd5edf60 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -323,6 +323,22 @@ is_tm_ending_fndecl (tree fndecl) return false; } +/* Return true if STMT is a built in function call that "ends" a + transaction. */ + +bool +is_tm_ending (gimple stmt) +{ + tree fndecl; + + if (gimple_code (stmt) != GIMPLE_CALL) + return false; + + fndecl = gimple_call_fndecl (stmt); + return (fndecl != NULL_TREE + && is_tm_ending_fndecl (fndecl)); +} + /* Return true if STMT is a TM load. */ static bool diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c index 406897755fc..09670857a59 100644 --- a/gcc/tree-ssa-tail-merge.c +++ b/gcc/tree-ssa-tail-merge.c @@ -1100,14 +1100,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); @@ -1221,15 +1213,14 @@ 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)) + /* What could be better than to this this here is to blacklist the bb + containing the stmt, when encountering the stmt f.i. in + same_succ_hash. */ + if (is_tm_ending (stmt1) + || is_tm_ending (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);