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
This commit is contained in:
parent
aee1522197
commit
594ec92f50
3 changed files with 97 additions and 32 deletions
|
@ -1,3 +1,20 @@
|
|||
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>
|
||||
|
||||
PR middle-end/51806
|
||||
|
|
22
gcc/testsuite/g++.dg/tm/pr51516.C
Normal file
22
gcc/testsuite/g++.dg/tm/pr51516.C
Normal file
|
@ -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" } } */
|
|
@ -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_queue *callees_p,
|
|||
|
||||
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_node *node,
|
|||
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_node *node,
|
|||
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_node *node,
|
|||
&& 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_block bb, bool for_clone)
|
|||
{
|
||||
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_node *node, bool for_clone)
|
|||
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_node *node, bool for_clone)
|
|||
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 cgraph_node *node, void *data)
|
|||
|
||||
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_node *old_node)
|
|||
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 cgraph_node *node,
|
|||
}
|
||||
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_node *node, struct tm_region *region,
|
|||
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 cgraph_node *node)
|
|||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue