On 01/05/12 16:05, Richard Henderson wrote:
On 01/06/2012 12:53 AM, Aldy Hernandez wrote:
http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01088.html
It looks like it would be cleaner to put the .alias dereferencing
directly into get_cg_data.
r~
Arghh, I knew you were going to say that. That was my first thought
when I looked at Patrick's patch.
It looks like everywhere but two places (where we are dealing with the
aliases themselves), we can traverse the aliases.
How does this look?
Tested on x86-64 Linux.
Patrick Marlier <patrick.marl...@gmail.com>
PR middle-end/51516
* trans-mem.c (get_cg_data): Traverse aliases if requested.
(ipa_tm_scan_calls_block): Update parameters to get_cg_data.
(ipa_tm_note_irrevocable): Same.
(ipa_tm_scan_irr_block): Same.
(ipa_tm_decrement_clone_counts): Same.
(ipa_tm_scan_irr_function): Same.
(ipa_tm_create_version_alias): Same.
(ipa_tm_create_version): Same.
(ipa_tm_transform_calls_redirect): Same.
(ipa_tm_transform_calls): Same.
(ipa_tm_transform_transaction): Same.
(ipa_tm_execute): Same.
Index: testsuite/g++.dg/tm/pr51516.C
===================================================================
--- testsuite/g++.dg/tm/pr51516.C (revision 0)
+++ testsuite/g++.dg/tm/pr51516.C (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-optimized" } */
+
+struct C {
+ long l;
+ C():l(0) {}
+};
+
+int main()
+{
+ C* alloc;
+ __transaction_atomic {
+ alloc = new C;
+ }
+ alloc->l = 2;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "_ITM_getTMCloneOrIrrevocable" } } */
+/* { dg-final { scan-tree-dump-times ";; Function C::C" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Index: trans-mem.c
===================================================================
--- trans-mem.c (revision 182958)
+++ trans-mem.c (working copy)
@@ -3522,18 +3522,24 @@ DEF_VEC_ALLOC_P (cgraph_node_p, heap);
typedef VEC (cgraph_node_p, heap) *cgraph_node_queue;
/* Return the ipa data associated with NODE, allocating zeroed memory
- if necessary. */
+ if necessary. TRAVERSE_ALIASES is true if we must traverse aliases
+ and set *NODE accordingly. */
static struct tm_ipa_cg_data *
-get_cg_data (struct cgraph_node *node)
+get_cg_data (struct cgraph_node **node, bool traverse_aliases)
{
- struct tm_ipa_cg_data *d = (struct tm_ipa_cg_data *) node->aux;
+ struct tm_ipa_cg_data *d;
+
+ if (traverse_aliases && (*node)->alias)
+ *node = cgraph_get_node ((*node)->thunk.alias);
+
+ d = (struct tm_ipa_cg_data *) (*node)->aux;
if (d == NULL)
{
d = (struct tm_ipa_cg_data *)
obstack_alloc (&tm_obstack.obstack, sizeof (*d));
- node->aux = (void *) d;
+ (*node)->aux = (void *) d;
memset (d, 0, sizeof (*d));
}
@@ -3582,7 +3588,7 @@ ipa_tm_scan_calls_block (cgraph_node_que
node = cgraph_get_node (fndecl);
gcc_assert (node != NULL);
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
pcallers = (for_clone ? &d->tm_callers_clone
: &d->tm_callers_normal);
@@ -3643,7 +3649,7 @@ static void
ipa_tm_note_irrevocable (struct cgraph_node *node,
cgraph_node_queue *worklist_p)
{
- struct tm_ipa_cg_data *d = get_cg_data (node);
+ struct tm_ipa_cg_data *d = get_cg_data (&node, true);
struct cgraph_edge *e;
d->is_irrevocable = true;
@@ -3651,6 +3657,7 @@ ipa_tm_note_irrevocable (struct cgraph_n
for (e = node->callers; e ; e = e->next_caller)
{
basic_block bb;
+ struct cgraph_node *caller;
/* Don't examine recursive calls. */
if (e->caller == node)
@@ -3660,7 +3667,8 @@ ipa_tm_note_irrevocable (struct cgraph_n
if (is_tm_safe_or_pure (e->caller->decl))
continue;
- d = get_cg_data (e->caller);
+ caller = e->caller;
+ d = get_cg_data (&caller, true);
/* Check if the callee is in a transactional region. If so,
schedule the function for normal re-scan as well. */
@@ -3670,7 +3678,7 @@ ipa_tm_note_irrevocable (struct cgraph_n
&& bitmap_bit_p (d->transaction_blocks_normal, bb->index))
d->want_irr_scan_normal = true;
- maybe_push_queue (e->caller, worklist_p, &d->in_worklist);
+ maybe_push_queue (caller, worklist_p, &d->in_worklist);
}
}
@@ -3704,6 +3712,7 @@ ipa_tm_scan_irr_block (basic_block bb)
if (TREE_CODE (fn) == ADDR_EXPR)
{
struct tm_ipa_cg_data *d;
+ struct cgraph_node *node;
fn = TREE_OPERAND (fn, 0);
if (is_tm_ending_fndecl (fn))
@@ -3711,7 +3720,8 @@ ipa_tm_scan_irr_block (basic_block bb)
if (find_tm_replacement_function (fn))
break;
- d = get_cg_data (cgraph_get_node (fn));
+ node = cgraph_get_node(fn);
+ d = get_cg_data (&node, true);
/* Return true if irrevocable, but above all, believe
the user. */
@@ -3869,13 +3879,16 @@ ipa_tm_decrement_clone_counts (basic_blo
{
struct tm_ipa_cg_data *d;
unsigned *pcallers;
+ struct cgraph_node *tnode;
if (is_tm_ending_fndecl (fndecl))
continue;
if (find_tm_replacement_function (fndecl))
continue;
- d = get_cg_data (cgraph_get_node (fndecl));
+ tnode = cgraph_get_node (fndecl);
+ d = get_cg_data (&tnode, true);
+
pcallers = (for_clone ? &d->tm_callers_clone
: &d->tm_callers_normal);
@@ -3909,7 +3922,7 @@ ipa_tm_scan_irr_function (struct cgraph_
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
calculate_dominance_info (CDI_DOMINATORS);
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
queue = VEC_alloc (basic_block, heap, 10);
new_irr = BITMAP_ALLOC (&tm_obstack);
@@ -3988,9 +4001,13 @@ ipa_tm_scan_irr_function (struct cgraph_
static bool
ipa_tm_mayenterirr_function (struct cgraph_node *node)
{
- struct tm_ipa_cg_data *d = get_cg_data (node);
- tree decl = node->decl;
- unsigned flags = flags_from_decl_or_type (decl);
+ struct tm_ipa_cg_data *d;
+ tree decl;
+ unsigned flags;
+
+ d = get_cg_data (&node, true);
+ decl = node->decl;
+ flags = flags_from_decl_or_type (decl);
/* Handle some TM builtins. Ordinarily these aren't actually generated
at this point, but handling these functions when written in by the
@@ -4244,7 +4261,8 @@ ipa_tm_create_version_alias (struct cgra
new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
new_node->tm_clone = true;
- get_cg_data (node)->clone = new_node;
+ /* ?? Do not traverse aliases here. */
+ get_cg_data (&node, false)->clone = new_node;
record_tm_clone_pair (old_decl, new_decl);
@@ -4280,7 +4298,7 @@ ipa_tm_create_version (struct cgraph_nod
new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL);
new_node->lowered = true;
new_node->tm_clone = 1;
- get_cg_data (old_node)->clone = new_node;
+ get_cg_data (&old_node, true)->clone = new_node;
if (cgraph_function_body_availability (old_node) >= AVAIL_OVERWRITABLE)
{
@@ -4498,7 +4516,10 @@ ipa_tm_transform_calls_redirect (struct
}
else
{
- struct tm_ipa_cg_data *d = get_cg_data (e->callee);
+ struct tm_ipa_cg_data *d;
+ struct cgraph_node *tnode = e->callee;
+
+ d = get_cg_data (&tnode, true);
new_node = d->clone;
/* As we've already skipped pure calls and appropriate builtins,
@@ -4599,10 +4620,12 @@ ipa_tm_transform_calls (struct cgraph_no
static void
ipa_tm_transform_transaction (struct cgraph_node *node)
{
- struct tm_ipa_cg_data *d = get_cg_data (node);
+ struct tm_ipa_cg_data *d;
struct tm_region *region;
bool need_ssa_rename = false;
+ d = get_cg_data (&node, true);
+
current_function_decl = node->decl;
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
calculate_dominance_info (CDI_DOMINATORS);
@@ -4636,9 +4659,11 @@ ipa_tm_transform_transaction (struct cgr
static void
ipa_tm_transform_clone (struct cgraph_node *node)
{
- struct tm_ipa_cg_data *d = get_cg_data (node);
+ struct tm_ipa_cg_data *d;
bool need_ssa_rename;
+ d = get_cg_data (&node, true);
+
/* If this function makes no calls and has no irrevocable blocks,
then there's nothing to do. */
/* ??? Remove non-aborting top-level transactions. */
@@ -4685,7 +4710,7 @@ ipa_tm_execute (void)
if (is_tm_callable (node->decl)
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
{
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
}
@@ -4711,7 +4736,7 @@ ipa_tm_execute (void)
tm_region_init (NULL);
if (all_tm_regions)
{
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
/* Scan for calls that are in each transaction. */
ipa_tm_scan_calls_transaction (d, &tm_callees);
@@ -4734,7 +4759,7 @@ ipa_tm_execute (void)
{
node = VEC_index (cgraph_node_p, tm_callees, i);
a = cgraph_function_body_availability (node);
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
/* Put it in the worklist so we can scan the function later
(ipa_tm_scan_irr_function) and mark the irrevocable
@@ -4759,7 +4784,7 @@ ipa_tm_execute (void)
if (node->alias)
{
node = cgraph_get_node (node->thunk.alias);
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
continue;
}
@@ -4785,7 +4810,7 @@ ipa_tm_execute (void)
}
node = VEC_index (cgraph_node_p, irr_worklist, i);
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
d->in_worklist = false;
if (d->want_irr_scan_normal)
@@ -4805,7 +4830,7 @@ ipa_tm_execute (void)
node = VEC_index (cgraph_node_p, tm_callees, i);
if (ipa_tm_mayenterirr_function (node))
{
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
gcc_assert (d->in_worklist == false);
maybe_push_queue (node, &irr_worklist, &d->in_worklist);
}
@@ -4826,7 +4851,7 @@ ipa_tm_execute (void)
}
node = VEC_index (cgraph_node_p, irr_worklist, i);
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
d->in_worklist = false;
node->local.tm_may_enter_irr = true;
@@ -4837,7 +4862,7 @@ ipa_tm_execute (void)
if (!is_tm_safe_or_pure (caller->decl)
&& !caller->local.tm_may_enter_irr)
{
- d = get_cg_data (caller);
+ d = get_cg_data (&caller, true);
maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
}
}
@@ -4849,7 +4874,8 @@ ipa_tm_execute (void)
if (ref->use == IPA_REF_ALIAS
&& !caller->local.tm_may_enter_irr)
{
- d = get_cg_data (caller);
+ /* ?? Do not traverse aliases here. */
+ d = get_cg_data (&caller, false);
maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
}
}
@@ -4861,7 +4887,7 @@ ipa_tm_execute (void)
if (node->reachable && node->lowered
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
{
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
if (is_tm_safe (node->decl))
ipa_tm_diagnose_tm_safe (node);
else if (d->all_tm_regions)
@@ -4880,7 +4906,7 @@ ipa_tm_execute (void)
continue;
a = cgraph_function_body_availability (node);
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
if (a <= AVAIL_NOT_AVAILABLE)
doit = is_tm_callable (node->decl);
@@ -4900,7 +4926,7 @@ ipa_tm_execute (void)
node = VEC_index (cgraph_node_p, tm_callees, i);
if (node->analyzed)
{
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
if (d->clone)
ipa_tm_transform_clone (node);
}
@@ -4909,7 +4935,7 @@ ipa_tm_execute (void)
if (node->reachable && node->lowered
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
{
- d = get_cg_data (node);
+ d = get_cg_data (&node, true);
if (d->all_tm_regions)
ipa_tm_transform_transaction (node);
}