]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/54893 (unable to access volatile variable within relaxed transaction)
authorAldy Hernandez <aldyh@redhat.com>
Wed, 17 Oct 2012 21:18:16 +0000 (21:18 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Wed, 17 Oct 2012 21:18:16 +0000 (21:18 +0000)
PR middle-end/54893
        * trans-mem.c (diagnose_tm_1_op): Allow volatiles inside relaxed
        transactions.

From-SVN: r192549

gcc/ChangeLog
gcc/testsuite/c-c++-common/tm/pr54893.c [new file with mode: 0644]
gcc/trans-mem.c

index 9c6a1d96edc0de1fd290b950e5be9443e2ff7552..b9d99e51dd75a1b1a12b16db2a24c1d3f0dcd098 100644 (file)
@@ -1,3 +1,9 @@
+2012-10-17  Aldy Hernandez  <aldyh@redhat.com>
+
+       PR middle-end/54893
+        * trans-mem.c (diagnose_tm_1_op): Allow volatiles inside relaxed
+        transactions.
+
 2012-10-17  Aldy Hernandez  <aldyh@redhat.com>
 
        PR rtl-optimization/54900
diff --git a/gcc/testsuite/c-c++-common/tm/pr54893.c b/gcc/testsuite/c-c++-common/tm/pr54893.c
new file mode 100644 (file)
index 0000000..8967f38
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-ipa-tmipa" } */
+
+/* Test that volatiles are allowed inside relaxed transactions.  */
+
+volatile int test_var = 0;
+
+int main()
+{
+  __transaction_relaxed {
+    test_var++;
+  }
+}
+
+/* { dg-final { scan-ipa-dump "GTMA_DOES_GO_IRREVOCABLE" "tmipa" } } */
+/* { dg-final { cleanup-ipa-dump "tmipa" } } */
index ef384acd7dc5784e4f0dde5794ec29b01df99819..211c45e48fb70d2c4a216c6ae77b8854c4b810c5 100644 (file)
@@ -548,6 +548,15 @@ struct diagnose_tm
   gimple stmt;
 };
 
+/* Return true if T is a volatile variable of some kind.  */
+
+static bool
+volatile_var_p (tree t)
+{
+  return (SSA_VAR_P (t)
+         && TREE_THIS_VOLATILE (TREE_TYPE (t)));
+}
+
 /* Tree callback function for diagnose_tm pass.  */
 
 static tree
@@ -556,13 +565,9 @@ diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
 {
   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
-  enum tree_code code = TREE_CODE (*tp);
 
-  if ((code == VAR_DECL
-       || code == RESULT_DECL
-       || code == PARM_DECL)
-      && d->block_flags & (DIAG_TM_SAFE | DIAG_TM_RELAXED)
-      && TREE_THIS_VOLATILE (TREE_TYPE (*tp))
+  if (volatile_var_p (*tp)
+      && d->block_flags & DIAG_TM_SAFE
       && !d->saw_volatile)
     {
       d->saw_volatile = 1;
@@ -3782,40 +3787,56 @@ ipa_tm_scan_irr_block (basic_block bb)
       gimple stmt = gsi_stmt (gsi);
       switch (gimple_code (stmt))
        {
+       case GIMPLE_ASSIGN:
+         if (gimple_assign_single_p (stmt))
+           {
+             tree lhs = gimple_assign_lhs (stmt);
+             tree rhs = gimple_assign_rhs1 (stmt);
+             if (volatile_var_p (lhs) || volatile_var_p (rhs))
+               return true;
+           }
+         break;
+
        case GIMPLE_CALL:
-         if (is_tm_pure_call (stmt))
-           break;
+         {
+           tree lhs = gimple_call_lhs (stmt);
+           if (lhs && volatile_var_p (lhs))
+             return true;
 
-         fn = gimple_call_fn (stmt);
+           if (is_tm_pure_call (stmt))
+             break;
 
-         /* Functions with the attribute are by definition irrevocable.  */
-         if (is_tm_irrevocable (fn))
-           return true;
+           fn = gimple_call_fn (stmt);
 
-         /* For direct function calls, go ahead and check for replacement
-            functions, or transitive irrevocable functions.  For indirect
-            functions, we'll ask the runtime.  */
-         if (TREE_CODE (fn) == ADDR_EXPR)
-           {
-             struct tm_ipa_cg_data *d;
-             struct cgraph_node *node;
+           /* Functions with the attribute are by definition irrevocable.  */
+           if (is_tm_irrevocable (fn))
+             return true;
 
-             fn = TREE_OPERAND (fn, 0);
-             if (is_tm_ending_fndecl (fn))
-               break;
-             if (find_tm_replacement_function (fn))
-               break;
+           /* For direct function calls, go ahead and check for replacement
+              functions, or transitive irrevocable functions.  For indirect
+              functions, we'll ask the runtime.  */
+           if (TREE_CODE (fn) == ADDR_EXPR)
+             {
+               struct tm_ipa_cg_data *d;
+               struct cgraph_node *node;
 
-             node = cgraph_get_node(fn);
-             d = get_cg_data (&node, true);
+               fn = TREE_OPERAND (fn, 0);
+               if (is_tm_ending_fndecl (fn))
+                 break;
+               if (find_tm_replacement_function (fn))
+                 break;
 
-             /* Return true if irrevocable, but above all, believe
-                the user.  */
-             if (d->is_irrevocable
-                 && !is_tm_safe_or_pure (fn))
-               return true;
-           }
-         break;
+               node = cgraph_get_node(fn);
+               d = get_cg_data (&node, true);
+
+               /* Return true if irrevocable, but above all, believe
+                  the user.  */
+               if (d->is_irrevocable
+                   && !is_tm_safe_or_pure (fn))
+                 return true;
+             }
+           break;
+         }
 
        case GIMPLE_ASM:
          /* ??? The Approved Method of indicating that an inline