From 3e426b86d2ef51d0abcee1ec27167a3d9bfe3037 Mon Sep 17 00:00:00 2001 From: aldyh Date: Tue, 10 Jan 2012 16:50:41 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183070 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 17 ++++++++ gcc/testsuite/g++.dg/tm/pr51516.C | 22 ++++++++++ gcc/trans-mem.c | 90 +++++++++++++++++++++++++-------------- 3 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tm/pr51516.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cfd0a864e0b..91e2a65e469 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2012-01-10 Aldy Hernandez + Patrick Marlier + + 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 PR middle-end/51806 diff --git a/gcc/testsuite/g++.dg/tm/pr51516.C b/gcc/testsuite/g++.dg/tm/pr51516.C new file mode 100644 index 00000000000..c13ae47fcb8 --- /dev/null +++ b/gcc/testsuite/g++.dg/tm/pr51516.C @@ -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" } } */ diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index bd4ce3933e6..8780825c58d 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -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); } -- 2.11.0