OSDN Git Service

PR/51443
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2011 17:49:55 +0000 (17:49 +0000)
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2011 17:49:55 +0000 (17:49 +0000)
        * trans-mem.c (struct diagnose_tm): Remove saw_unsafe.
        (diagnose_tm_1): Same.
        (ipa_tm_execute): Do not test tm_may_enter_irr before we set it.
        (ipa_tm_scan_irr_function): Return gracefully when no
        DECL_STRUCT_FUNCTION.
        (ipa_tm_scan_irr_block): Believe the user on TM attributes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182290 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/g++.dg/tm/asm-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tm/asm-1.c [new file with mode: 0644]
gcc/trans-mem.c

index a9022e0..6043551 100644 (file)
@@ -1,3 +1,13 @@
+2011-12-13  Aldy Hernandez  <aldyh@redhat.com>
+
+       PR/51443
+       * trans-mem.c (struct diagnose_tm): Remove saw_unsafe.
+       (diagnose_tm_1): Same.
+       (ipa_tm_execute): Do not test tm_may_enter_irr before we set it.
+       (ipa_tm_scan_irr_function): Return gracefully when no
+       DECL_STRUCT_FUNCTION.
+       (ipa_tm_scan_irr_block): Believe the user on TM attributes.
+
 2011-12-13  Martin Jambor  <mjambor@suse.cz>
 
        PR middle-end/50628
 2011-12-13  Martin Jambor  <mjambor@suse.cz>
 
        PR middle-end/50628
diff --git a/gcc/testsuite/g++.dg/tm/asm-1.c b/gcc/testsuite/g++.dg/tm/asm-1.c
new file mode 100644 (file)
index 0000000..3c8ebd2
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-do compile }
+// { dg-options "-fgnu-tm -O1" }
+
+template<class T> class shared_ptr {
+public:
+    shared_ptr()  {
+      __asm__ ("");
+    }
+};
+template<typename _Tp> class deque {
+public:
+    void push_back() {
+      ::new _Tp();
+    }
+};
+class Bar {
+  __attribute__((transaction_callable)) void push();
+  deque<shared_ptr<int> > events;
+};
+void Bar::push() {
+  events.push_back();
+}
diff --git a/gcc/testsuite/gcc.dg/tm/asm-1.c b/gcc/testsuite/gcc.dg/tm/asm-1.c
new file mode 100644 (file)
index 0000000..a3826e2
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O1" } */
+
+static inline void asmfunc()
+{
+__asm__("");
+}
+
+__attribute__((transaction_callable))
+void push()
+{
+        asmfunc();
+}
index c32aee6..9506e79 100644 (file)
@@ -544,7 +544,6 @@ struct diagnose_tm
   unsigned int summary_flags : 8;
   unsigned int block_flags : 8;
   unsigned int func_flags : 8;
   unsigned int summary_flags : 8;
   unsigned int block_flags : 8;
   unsigned int func_flags : 8;
-  unsigned int saw_unsafe : 1;
   unsigned int saw_volatile : 1;
   gimple stmt;
 };
   unsigned int saw_volatile : 1;
   gimple stmt;
 };
@@ -695,8 +694,6 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
       else if (d->func_flags & DIAG_TM_SAFE)
        error_at (gimple_location (stmt),
                  "asm not allowed in %<transaction_safe%> function");
       else if (d->func_flags & DIAG_TM_SAFE)
        error_at (gimple_location (stmt),
                  "asm not allowed in %<transaction_safe%> function");
-      else
-       d->saw_unsafe = true;
       break;
 
     case GIMPLE_TRANSACTION:
       break;
 
     case GIMPLE_TRANSACTION:
@@ -711,8 +708,6 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
            else if (d->func_flags & DIAG_TM_SAFE)
              error_at (gimple_location (stmt),
                        "relaxed transaction in %<transaction_safe%> function");
            else if (d->func_flags & DIAG_TM_SAFE)
              error_at (gimple_location (stmt),
                        "relaxed transaction in %<transaction_safe%> function");
-           else
-             d->saw_unsafe = true;
            inner_flags = DIAG_TM_RELAXED;
          }
        else if (gimple_transaction_subcode (stmt) & GTMA_IS_OUTER)
            inner_flags = DIAG_TM_RELAXED;
          }
        else if (gimple_transaction_subcode (stmt) & GTMA_IS_OUTER)
@@ -727,8 +722,6 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
            else if (d->func_flags & DIAG_TM_SAFE)
              error_at (gimple_location (stmt),
                        "outer transaction in %<transaction_safe%> function");
            else if (d->func_flags & DIAG_TM_SAFE)
              error_at (gimple_location (stmt),
                        "outer transaction in %<transaction_safe%> function");
-           else
-             d->saw_unsafe = true;
            inner_flags |= DIAG_TM_OUTER;
          }
 
            inner_flags |= DIAG_TM_OUTER;
          }
 
@@ -748,8 +741,6 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 
            walk_gimple_seq (gimple_transaction_body (stmt),
                             diagnose_tm_1, diagnose_tm_1_op, &wi_inner);
 
            walk_gimple_seq (gimple_transaction_body (stmt),
                             diagnose_tm_1, diagnose_tm_1_op, &wi_inner);
-
-           d->saw_unsafe |= d_inner.saw_unsafe;
          }
       }
       break;
          }
       }
       break;
@@ -780,11 +771,6 @@ diagnose_tm_blocks (void)
   walk_gimple_seq (gimple_body (current_function_decl),
                   diagnose_tm_1, diagnose_tm_1_op, &wi);
 
   walk_gimple_seq (gimple_body (current_function_decl),
                   diagnose_tm_1, diagnose_tm_1_op, &wi);
 
-  /* If we saw something other than a call that makes this function
-     unsafe, remember it so that the IPA pass only needs to scan calls.  */
-  if (d.saw_unsafe && !is_tm_safe_or_pure (current_function_decl))
-    cgraph_local_info (current_function_decl)->tm_may_enter_irr = 1;
-
   return 0;
 }
 
   return 0;
 }
 
@@ -3696,7 +3682,11 @@ ipa_tm_scan_irr_block (basic_block bb)
                break;
 
              d = get_cg_data (cgraph_get_node (fn));
                break;
 
              d = get_cg_data (cgraph_get_node (fn));
-             if (d->is_irrevocable)
+
+             /* Return true if irrevocable, but above all, believe
+                the user.  */
+             if (d->is_irrevocable
+                 && !is_tm_safe_or_pure (fn))
                return true;
            }
          break;
                return true;
            }
          break;
@@ -3880,6 +3870,11 @@ ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
   VEC (basic_block, heap) *queue;
   bool ret = false;
 
   VEC (basic_block, heap) *queue;
   bool ret = false;
 
+  /* Builtin operators (operator new, and such).  */
+  if (DECL_STRUCT_FUNCTION (node->decl) == NULL
+      || DECL_STRUCT_FUNCTION (node->decl)->cfg == NULL)
+    return false;
+
   current_function_decl = node->decl;
   push_cfun (DECL_STRUCT_FUNCTION (node->decl));
   calculate_dominance_info (CDI_DOMINATORS);
   current_function_decl = node->decl;
   push_cfun (DECL_STRUCT_FUNCTION (node->decl));
   calculate_dominance_info (CDI_DOMINATORS);
@@ -4689,14 +4684,11 @@ ipa_tm_execute (void)
            /* Scan for calls that are in each transaction.  */
            ipa_tm_scan_calls_transaction (d, &tm_callees);
 
            /* Scan for calls that are in each transaction.  */
            ipa_tm_scan_calls_transaction (d, &tm_callees);
 
-           /* If we saw something that will make us go irrevocable, put it
-              in the worklist so we can scan the function later
-              (ipa_tm_scan_irr_function) and mark the irrevocable blocks.  */
-           if (node->local.tm_may_enter_irr)
-             {
-               maybe_push_queue (node, &irr_worklist, &d->in_worklist);
-               d->want_irr_scan_normal = true;
-             }
+           /* Put it in the worklist so we can scan the function
+              later (ipa_tm_scan_irr_function) and mark the
+              irrevocable blocks.  */
+           maybe_push_queue (node, &irr_worklist, &d->in_worklist);
+           d->want_irr_scan_normal = true;
          }
 
        pop_cfun ();
          }
 
        pop_cfun ();
@@ -4712,11 +4704,10 @@ ipa_tm_execute (void)
       a = cgraph_function_body_availability (node);
       d = get_cg_data (node);
 
       a = cgraph_function_body_availability (node);
       d = get_cg_data (node);
 
-      /* If we saw something that will make us go irrevocable, put it
-        in the worklist so we can scan the function later
-        (ipa_tm_scan_irr_function) and mark the irrevocable blocks.  */
-      if (node->local.tm_may_enter_irr)
-       maybe_push_queue (node, &irr_worklist, &d->in_worklist);
+      /* Put it in the worklist so we can scan the function later
+        (ipa_tm_scan_irr_function) and mark the irrevocable
+        blocks.  */
+      maybe_push_queue (node, &irr_worklist, &d->in_worklist);
 
       /* Some callees cannot be arbitrarily cloned.  These will always be
         irrevocable.  Mark these now, so that we need not scan them.  */
 
       /* Some callees cannot be arbitrarily cloned.  These will always be
         irrevocable.  Mark these now, so that we need not scan them.  */