Commit 594ec92f by Aldy Hernandez Committed by Aldy Hernandez

re PR middle-end/51516 ([trans-mem] problem with TM clone aliases)

        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.


Co-Authored-By: Patrick Marlier <patrick.marlier@gmail.com>

From-SVN: r183070
parent aee15221
2012-01-10 Aldy Hernandez <aldyh@redhat.com>
Patrick Marlier <patrick.marlier@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.
2012-01-10 Richard Guenther <rguenther@suse.de> 2012-01-10 Richard Guenther <rguenther@suse.de>
PR middle-end/51806 PR middle-end/51806
......
/* { 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" } } */
...@@ -3522,18 +3522,24 @@ DEF_VEC_ALLOC_P (cgraph_node_p, heap); ...@@ -3522,18 +3522,24 @@ DEF_VEC_ALLOC_P (cgraph_node_p, heap);
typedef VEC (cgraph_node_p, heap) *cgraph_node_queue; typedef VEC (cgraph_node_p, heap) *cgraph_node_queue;
/* Return the ipa data associated with NODE, allocating zeroed memory /* 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 * 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) if (d == NULL)
{ {
d = (struct tm_ipa_cg_data *) d = (struct tm_ipa_cg_data *)
obstack_alloc (&tm_obstack.obstack, sizeof (*d)); obstack_alloc (&tm_obstack.obstack, sizeof (*d));
node->aux = (void *) d; (*node)->aux = (void *) d;
memset (d, 0, sizeof (*d)); memset (d, 0, sizeof (*d));
} }
...@@ -3582,7 +3588,7 @@ ipa_tm_scan_calls_block (cgraph_node_queue *callees_p, ...@@ -3582,7 +3588,7 @@ ipa_tm_scan_calls_block (cgraph_node_queue *callees_p,
node = cgraph_get_node (fndecl); node = cgraph_get_node (fndecl);
gcc_assert (node != NULL); gcc_assert (node != NULL);
d = get_cg_data (node); d = get_cg_data (&node, true);
pcallers = (for_clone ? &d->tm_callers_clone pcallers = (for_clone ? &d->tm_callers_clone
: &d->tm_callers_normal); : &d->tm_callers_normal);
...@@ -3643,7 +3649,7 @@ static void ...@@ -3643,7 +3649,7 @@ static void
ipa_tm_note_irrevocable (struct cgraph_node *node, ipa_tm_note_irrevocable (struct cgraph_node *node,
cgraph_node_queue *worklist_p) 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; struct cgraph_edge *e;
d->is_irrevocable = true; d->is_irrevocable = true;
...@@ -3651,6 +3657,7 @@ ipa_tm_note_irrevocable (struct cgraph_node *node, ...@@ -3651,6 +3657,7 @@ ipa_tm_note_irrevocable (struct cgraph_node *node,
for (e = node->callers; e ; e = e->next_caller) for (e = node->callers; e ; e = e->next_caller)
{ {
basic_block bb; basic_block bb;
struct cgraph_node *caller;
/* Don't examine recursive calls. */ /* Don't examine recursive calls. */
if (e->caller == node) if (e->caller == node)
...@@ -3660,7 +3667,8 @@ ipa_tm_note_irrevocable (struct cgraph_node *node, ...@@ -3660,7 +3667,8 @@ ipa_tm_note_irrevocable (struct cgraph_node *node,
if (is_tm_safe_or_pure (e->caller->decl)) if (is_tm_safe_or_pure (e->caller->decl))
continue; 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, /* Check if the callee is in a transactional region. If so,
schedule the function for normal re-scan as well. */ schedule the function for normal re-scan as well. */
...@@ -3670,7 +3678,7 @@ ipa_tm_note_irrevocable (struct cgraph_node *node, ...@@ -3670,7 +3678,7 @@ ipa_tm_note_irrevocable (struct cgraph_node *node,
&& bitmap_bit_p (d->transaction_blocks_normal, bb->index)) && bitmap_bit_p (d->transaction_blocks_normal, bb->index))
d->want_irr_scan_normal = true; 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) ...@@ -3704,6 +3712,7 @@ ipa_tm_scan_irr_block (basic_block bb)
if (TREE_CODE (fn) == ADDR_EXPR) if (TREE_CODE (fn) == ADDR_EXPR)
{ {
struct tm_ipa_cg_data *d; struct tm_ipa_cg_data *d;
struct cgraph_node *node;
fn = TREE_OPERAND (fn, 0); fn = TREE_OPERAND (fn, 0);
if (is_tm_ending_fndecl (fn)) if (is_tm_ending_fndecl (fn))
...@@ -3711,7 +3720,8 @@ ipa_tm_scan_irr_block (basic_block bb) ...@@ -3711,7 +3720,8 @@ ipa_tm_scan_irr_block (basic_block bb)
if (find_tm_replacement_function (fn)) if (find_tm_replacement_function (fn))
break; 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 /* Return true if irrevocable, but above all, believe
the user. */ the user. */
...@@ -3869,13 +3879,16 @@ ipa_tm_decrement_clone_counts (basic_block bb, bool for_clone) ...@@ -3869,13 +3879,16 @@ ipa_tm_decrement_clone_counts (basic_block bb, bool for_clone)
{ {
struct tm_ipa_cg_data *d; struct tm_ipa_cg_data *d;
unsigned *pcallers; unsigned *pcallers;
struct cgraph_node *tnode;
if (is_tm_ending_fndecl (fndecl)) if (is_tm_ending_fndecl (fndecl))
continue; continue;
if (find_tm_replacement_function (fndecl)) if (find_tm_replacement_function (fndecl))
continue; 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 pcallers = (for_clone ? &d->tm_callers_clone
: &d->tm_callers_normal); : &d->tm_callers_normal);
...@@ -3909,7 +3922,7 @@ ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone) ...@@ -3909,7 +3922,7 @@ ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
push_cfun (DECL_STRUCT_FUNCTION (node->decl)); push_cfun (DECL_STRUCT_FUNCTION (node->decl));
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
d = get_cg_data (node); d = get_cg_data (&node, true);
queue = VEC_alloc (basic_block, heap, 10); queue = VEC_alloc (basic_block, heap, 10);
new_irr = BITMAP_ALLOC (&tm_obstack); new_irr = BITMAP_ALLOC (&tm_obstack);
...@@ -3988,9 +4001,13 @@ ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone) ...@@ -3988,9 +4001,13 @@ ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
static bool static bool
ipa_tm_mayenterirr_function (struct cgraph_node *node) ipa_tm_mayenterirr_function (struct cgraph_node *node)
{ {
struct tm_ipa_cg_data *d = get_cg_data (node); struct tm_ipa_cg_data *d;
tree decl = node->decl; tree decl;
unsigned flags = flags_from_decl_or_type (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 /* Handle some TM builtins. Ordinarily these aren't actually generated
at this point, but handling these functions when written in by the at this point, but handling these functions when written in by the
...@@ -4244,7 +4261,8 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data) ...@@ -4244,7 +4261,8 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl); new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
new_node->tm_clone = true; 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); record_tm_clone_pair (old_decl, new_decl);
...@@ -4280,7 +4298,7 @@ ipa_tm_create_version (struct cgraph_node *old_node) ...@@ -4280,7 +4298,7 @@ ipa_tm_create_version (struct cgraph_node *old_node)
new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL); new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL);
new_node->lowered = true; new_node->lowered = true;
new_node->tm_clone = 1; 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) if (cgraph_function_body_availability (old_node) >= AVAIL_OVERWRITABLE)
{ {
...@@ -4498,7 +4516,10 @@ ipa_tm_transform_calls_redirect (struct cgraph_node *node, ...@@ -4498,7 +4516,10 @@ ipa_tm_transform_calls_redirect (struct cgraph_node *node,
} }
else 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; new_node = d->clone;
/* As we've already skipped pure calls and appropriate builtins, /* As we've already skipped pure calls and appropriate builtins,
...@@ -4599,10 +4620,12 @@ ipa_tm_transform_calls (struct cgraph_node *node, struct tm_region *region, ...@@ -4599,10 +4620,12 @@ ipa_tm_transform_calls (struct cgraph_node *node, struct tm_region *region,
static void static void
ipa_tm_transform_transaction (struct cgraph_node *node) 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; struct tm_region *region;
bool need_ssa_rename = false; bool need_ssa_rename = false;
d = get_cg_data (&node, true);
current_function_decl = node->decl; current_function_decl = node->decl;
push_cfun (DECL_STRUCT_FUNCTION (node->decl)); push_cfun (DECL_STRUCT_FUNCTION (node->decl));
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
...@@ -4636,9 +4659,11 @@ ipa_tm_transform_transaction (struct cgraph_node *node) ...@@ -4636,9 +4659,11 @@ ipa_tm_transform_transaction (struct cgraph_node *node)
static void static void
ipa_tm_transform_clone (struct cgraph_node *node) 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; bool need_ssa_rename;
d = get_cg_data (&node, true);
/* If this function makes no calls and has no irrevocable blocks, /* If this function makes no calls and has no irrevocable blocks,
then there's nothing to do. */ then there's nothing to do. */
/* ??? Remove non-aborting top-level transactions. */ /* ??? Remove non-aborting top-level transactions. */
...@@ -4685,7 +4710,7 @@ ipa_tm_execute (void) ...@@ -4685,7 +4710,7 @@ ipa_tm_execute (void)
if (is_tm_callable (node->decl) if (is_tm_callable (node->decl)
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE) && 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); maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
} }
...@@ -4711,7 +4736,7 @@ ipa_tm_execute (void) ...@@ -4711,7 +4736,7 @@ ipa_tm_execute (void)
tm_region_init (NULL); tm_region_init (NULL);
if (all_tm_regions) if (all_tm_regions)
{ {
d = get_cg_data (node); d = get_cg_data (&node, true);
/* Scan for calls that are in each transaction. */ /* Scan for calls that are in each transaction. */
ipa_tm_scan_calls_transaction (d, &tm_callees); ipa_tm_scan_calls_transaction (d, &tm_callees);
...@@ -4734,7 +4759,7 @@ ipa_tm_execute (void) ...@@ -4734,7 +4759,7 @@ ipa_tm_execute (void)
{ {
node = VEC_index (cgraph_node_p, tm_callees, i); node = VEC_index (cgraph_node_p, tm_callees, i);
a = cgraph_function_body_availability (node); 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 /* Put it in the worklist so we can scan the function later
(ipa_tm_scan_irr_function) and mark the irrevocable (ipa_tm_scan_irr_function) and mark the irrevocable
...@@ -4759,7 +4784,7 @@ ipa_tm_execute (void) ...@@ -4759,7 +4784,7 @@ ipa_tm_execute (void)
if (node->alias) if (node->alias)
{ {
node = cgraph_get_node (node->thunk.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); maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
continue; continue;
} }
...@@ -4785,7 +4810,7 @@ ipa_tm_execute (void) ...@@ -4785,7 +4810,7 @@ ipa_tm_execute (void)
} }
node = VEC_index (cgraph_node_p, irr_worklist, i); node = VEC_index (cgraph_node_p, irr_worklist, i);
d = get_cg_data (node); d = get_cg_data (&node, true);
d->in_worklist = false; d->in_worklist = false;
if (d->want_irr_scan_normal) if (d->want_irr_scan_normal)
...@@ -4805,7 +4830,7 @@ ipa_tm_execute (void) ...@@ -4805,7 +4830,7 @@ ipa_tm_execute (void)
node = VEC_index (cgraph_node_p, tm_callees, i); node = VEC_index (cgraph_node_p, tm_callees, i);
if (ipa_tm_mayenterirr_function (node)) if (ipa_tm_mayenterirr_function (node))
{ {
d = get_cg_data (node); d = get_cg_data (&node, true);
gcc_assert (d->in_worklist == false); gcc_assert (d->in_worklist == false);
maybe_push_queue (node, &irr_worklist, &d->in_worklist); maybe_push_queue (node, &irr_worklist, &d->in_worklist);
} }
...@@ -4826,7 +4851,7 @@ ipa_tm_execute (void) ...@@ -4826,7 +4851,7 @@ ipa_tm_execute (void)
} }
node = VEC_index (cgraph_node_p, irr_worklist, i); node = VEC_index (cgraph_node_p, irr_worklist, i);
d = get_cg_data (node); d = get_cg_data (&node, true);
d->in_worklist = false; d->in_worklist = false;
node->local.tm_may_enter_irr = true; node->local.tm_may_enter_irr = true;
...@@ -4837,7 +4862,7 @@ ipa_tm_execute (void) ...@@ -4837,7 +4862,7 @@ ipa_tm_execute (void)
if (!is_tm_safe_or_pure (caller->decl) if (!is_tm_safe_or_pure (caller->decl)
&& !caller->local.tm_may_enter_irr) && !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); maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
} }
} }
...@@ -4849,7 +4874,8 @@ ipa_tm_execute (void) ...@@ -4849,7 +4874,8 @@ ipa_tm_execute (void)
if (ref->use == IPA_REF_ALIAS if (ref->use == IPA_REF_ALIAS
&& !caller->local.tm_may_enter_irr) && !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); maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
} }
} }
...@@ -4861,7 +4887,7 @@ ipa_tm_execute (void) ...@@ -4861,7 +4887,7 @@ ipa_tm_execute (void)
if (node->reachable && node->lowered if (node->reachable && node->lowered
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE) && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
{ {
d = get_cg_data (node); d = get_cg_data (&node, true);
if (is_tm_safe (node->decl)) if (is_tm_safe (node->decl))
ipa_tm_diagnose_tm_safe (node); ipa_tm_diagnose_tm_safe (node);
else if (d->all_tm_regions) else if (d->all_tm_regions)
...@@ -4880,7 +4906,7 @@ ipa_tm_execute (void) ...@@ -4880,7 +4906,7 @@ ipa_tm_execute (void)
continue; continue;
a = cgraph_function_body_availability (node); a = cgraph_function_body_availability (node);
d = get_cg_data (node); d = get_cg_data (&node, true);
if (a <= AVAIL_NOT_AVAILABLE) if (a <= AVAIL_NOT_AVAILABLE)
doit = is_tm_callable (node->decl); doit = is_tm_callable (node->decl);
...@@ -4900,7 +4926,7 @@ ipa_tm_execute (void) ...@@ -4900,7 +4926,7 @@ ipa_tm_execute (void)
node = VEC_index (cgraph_node_p, tm_callees, i); node = VEC_index (cgraph_node_p, tm_callees, i);
if (node->analyzed) if (node->analyzed)
{ {
d = get_cg_data (node); d = get_cg_data (&node, true);
if (d->clone) if (d->clone)
ipa_tm_transform_clone (node); ipa_tm_transform_clone (node);
} }
...@@ -4909,7 +4935,7 @@ ipa_tm_execute (void) ...@@ -4909,7 +4935,7 @@ ipa_tm_execute (void)
if (node->reachable && node->lowered if (node->reachable && node->lowered
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE) && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
{ {
d = get_cg_data (node); d = get_cg_data (&node, true);
if (d->all_tm_regions) if (d->all_tm_regions)
ipa_tm_transform_transaction (node); ipa_tm_transform_transaction (node);
} }
......
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