diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2012-10-17 21:18:16 +0000 |
---|---|---|
committer | Aldy Hernandez <aldyh@gcc.gnu.org> | 2012-10-17 21:18:16 +0000 |
commit | a3770d3b7d86f1be758db337631be9b52530c173 (patch) | |
tree | 436fa541fe71a62886a30c7ffde759985c66668b | |
parent | a7b159a4dcca7e45fdf2b57a865dd2a91148eefb (diff) | |
download | gcc-a3770d3b7d86f1be758db337631be9b52530c173.zip gcc-a3770d3b7d86f1be758db337631be9b52530c173.tar.gz gcc-a3770d3b7d86f1be758db337631be9b52530c173.tar.bz2 |
re PR middle-end/54893 (unable to access volatile variable within relaxed transaction)
PR middle-end/54893
* trans-mem.c (diagnose_tm_1_op): Allow volatiles inside relaxed
transactions.
From-SVN: r192549
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tm/pr54893.c | 16 | ||||
-rw-r--r-- | gcc/trans-mem.c | 87 |
3 files changed, 76 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c6a1d9..b9d99e5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 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 * ifcvt.c (noce_can_store_speculate_p): Call memory_must_be_modified_in_insn_p. diff --git a/gcc/testsuite/c-c++-common/tm/pr54893.c b/gcc/testsuite/c-c++-common/tm/pr54893.c new file mode 100644 index 0000000..8967f38 --- /dev/null +++ b/gcc/testsuite/c-c++-common/tm/pr54893.c @@ -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" } } */ diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index ef384ac..211c45e 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 |