aboutsummaryrefslogtreecommitdiff
path: root/gcc/trans-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/trans-mem.c')
-rw-r--r--gcc/trans-mem.c87
1 files changed, 54 insertions, 33 deletions
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index ef384acd7dc..211c45e48fb 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -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