aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2011-12-13 17:49:55 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2011-12-13 17:49:55 +0000
commit80fd8eba8ed7cc70a89e4f31931a5da28464357a (patch)
tree89273e22c9ce249019e6e3514fc2903fb218f70a /gcc
parentd370518679f55fa676afe6010301945b9ccc7053 (diff)
downloadgcc-80fd8eba8ed7cc70a89e4f31931a5da28464357a.zip
gcc-80fd8eba8ed7cc70a89e4f31931a5da28464357a.tar.gz
gcc-80fd8eba8ed7cc70a89e4f31931a5da28464357a.tar.bz2
trans-mem.c (struct diagnose_tm): Remove saw_unsafe.
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. From-SVN: r182290
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/g++.dg/tm/asm-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/tm/asm-1.c13
-rw-r--r--gcc/trans-mem.c47
4 files changed, 64 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a9022e0..6043551 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/tm/asm-1.c b/gcc/testsuite/g++.dg/tm/asm-1.c
new file mode 100644
index 0000000..3c8ebd2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/asm-1.c
@@ -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
index 0000000..a3826e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/asm-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O1" } */
+
+static inline void asmfunc()
+{
+__asm__("");
+}
+
+__attribute__((transaction_callable))
+void push()
+{
+ asmfunc();
+}
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index c32aee6..9506e79 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -544,7 +544,6 @@ struct diagnose_tm
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;
};
@@ -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
- d->saw_unsafe = true;
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
- d->saw_unsafe = true;
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
- d->saw_unsafe = true;
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);
-
- d->saw_unsafe |= d_inner.saw_unsafe;
}
}
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);
- /* 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;
}
@@ -3696,7 +3682,11 @@ ipa_tm_scan_irr_block (basic_block bb)
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;
@@ -3880,6 +3870,11 @@ ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
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);
@@ -4689,14 +4684,11 @@ ipa_tm_execute (void)
/* 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 ();
@@ -4712,11 +4704,10 @@ ipa_tm_execute (void)
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. */