Commit a3770d3b by Aldy Hernandez Committed by Aldy Hernandez

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
parent a7b159a4
2012-10-17 Aldy Hernandez <aldyh@redhat.com> 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 PR rtl-optimization/54900
* ifcvt.c (noce_can_store_speculate_p): Call * ifcvt.c (noce_can_store_speculate_p): Call
memory_must_be_modified_in_insn_p. memory_must_be_modified_in_insn_p.
/* { 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" } } */
...@@ -548,6 +548,15 @@ struct diagnose_tm ...@@ -548,6 +548,15 @@ struct diagnose_tm
gimple stmt; 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. */ /* Tree callback function for diagnose_tm pass. */
static tree static tree
...@@ -556,13 +565,9 @@ diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, ...@@ -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 walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct diagnose_tm *d = (struct diagnose_tm *) wi->info; struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
enum tree_code code = TREE_CODE (*tp);
if ((code == VAR_DECL if (volatile_var_p (*tp)
|| code == RESULT_DECL && d->block_flags & DIAG_TM_SAFE
|| code == PARM_DECL)
&& d->block_flags & (DIAG_TM_SAFE | DIAG_TM_RELAXED)
&& TREE_THIS_VOLATILE (TREE_TYPE (*tp))
&& !d->saw_volatile) && !d->saw_volatile)
{ {
d->saw_volatile = 1; d->saw_volatile = 1;
...@@ -3782,40 +3787,56 @@ ipa_tm_scan_irr_block (basic_block bb) ...@@ -3782,40 +3787,56 @@ ipa_tm_scan_irr_block (basic_block bb)
gimple stmt = gsi_stmt (gsi); gimple stmt = gsi_stmt (gsi);
switch (gimple_code (stmt)) 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: 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. */ fn = gimple_call_fn (stmt);
if (is_tm_irrevocable (fn))
return true;
/* For direct function calls, go ahead and check for replacement /* Functions with the attribute are by definition irrevocable. */
functions, or transitive irrevocable functions. For indirect if (is_tm_irrevocable (fn))
functions, we'll ask the runtime. */ return true;
if (TREE_CODE (fn) == ADDR_EXPR)
{
struct tm_ipa_cg_data *d;
struct cgraph_node *node;
fn = TREE_OPERAND (fn, 0); /* For direct function calls, go ahead and check for replacement
if (is_tm_ending_fndecl (fn)) functions, or transitive irrevocable functions. For indirect
break; functions, we'll ask the runtime. */
if (find_tm_replacement_function (fn)) if (TREE_CODE (fn) == ADDR_EXPR)
break; {
struct tm_ipa_cg_data *d;
struct cgraph_node *node;
node = cgraph_get_node(fn); fn = TREE_OPERAND (fn, 0);
d = get_cg_data (&node, true); if (is_tm_ending_fndecl (fn))
break;
if (find_tm_replacement_function (fn))
break;
/* Return true if irrevocable, but above all, believe node = cgraph_get_node(fn);
the user. */ d = get_cg_data (&node, true);
if (d->is_irrevocable
&& !is_tm_safe_or_pure (fn)) /* Return true if irrevocable, but above all, believe
return true; the user. */
} if (d->is_irrevocable
break; && !is_tm_safe_or_pure (fn))
return true;
}
break;
}
case GIMPLE_ASM: case GIMPLE_ASM:
/* ??? The Approved Method of indicating that an inline /* ??? The Approved Method of indicating that an inline
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment