diff mbox

Prevent sharing of commit calls among transactions.

Message ID 1323548437.4159.6975.camel@triegel.csb
State New
Headers show

Commit Message

Torvald Riegel Dec. 10, 2011, 8:20 p.m. UTC
Without this patch, transaction commits of different transactions get
potentially merged, which breaks how we handle transactional regions.
Patch provided by Richard Henderson.

OK for trunk?
commit 48d236d4c40fdb7111308fe88844068603e235eb
Author: Torvald Riegel <triegel@redhat.com>
Date:   Thu Dec 8 11:57:05 2011 +0100

    Prevent sharing of commit calls among transactions.
    
    	gcc/
    	* tree-ssa-tail-merge.c (gimple_equal_p): Don't treat transaction
    	commits as equal.
    
    	gcc/testsuite/
    	* c-c++-common/tm/20111206.c: New test.

Comments

Richard Henderson Dec. 10, 2011, 8:52 p.m. UTC | #1
On 12/10/2011 12:20 PM, Torvald Riegel wrote:
>     Prevent sharing of commit calls among transactions.
>     
>     	gcc/
>     	* tree-ssa-tail-merge.c (gimple_equal_p): Don't treat transaction
>     	commits as equal.
>     
>     	gcc/testsuite/
>     	* c-c++-common/tm/20111206.c: New test.

Ok.


r~
diff mbox

Patch

diff --git a/gcc/testsuite/c-c++-common/tm/20111206.c b/gcc/testsuite/c-c++-common/tm/20111206.c
new file mode 100644
index 0000000..74a5519
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tm/20111206.c
@@ -0,0 +1,53 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O2" } */
+/* This test case triggered block sharing between the two transactions.  */
+
+void func1 (void) __attribute__ ((transaction_callable, used));
+long func2 (void) __attribute__ ((transaction_callable, used));
+unsigned long rand (void);
+
+void client_run (void)
+{
+  long types[100];
+  long i;
+
+  for (i = 0; i < 100; i++)
+    {
+      long action = rand ();
+
+      switch (action)
+	{
+	case 0:
+	  {
+	    __transaction_relaxed
+	    {
+	      long bill = func2 ();
+	      if (bill >= 0)
+		{
+		  func1 ();
+		}
+	    }
+	    break;
+	  }
+
+	case 1:
+	  {
+	    long n;
+	    __transaction_relaxed
+	    {
+	      for (n = 0; n < 100; n++)
+		{
+		  long t = types[n];
+		  switch (t)
+		    {
+		    case 0:
+		      func1 ();
+		      break;
+		    }
+		}
+	    }
+	    break;
+	  }
+	}
+    }
+}
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index a501b07..7452266 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -1051,6 +1051,14 @@  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;
+
       equal = true;
       for (i = 0; i < gimple_call_num_args (s1); ++i)
 	{