Patchwork patch ping^2: PR 51516 (TM clone aliases)

login
register
mail settings
Submitter Aldy Hernandez
Date Jan. 6, 2012, 6:47 p.m.
Message ID <4F0741AD.2090906@redhat.com>
Download mbox | patch
Permalink /patch/134687/
State New
Headers show

Comments

Aldy Hernandez - Jan. 6, 2012, 6:47 p.m.
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.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.
Richard Henderson - Jan. 10, 2012, 5:38 a.m.
On 01/07/2012 05:47 AM, Aldy Hernandez wrote:
> 	    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.

Ok.


r~

Patch

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);
       }