Patchwork 19/n: trans-mem: middle end/misc patches (LAST PATCH)

login
register
mail settings
Submitter Aldy Hernandez
Date Nov. 7, 2011, 5:03 p.m.
Message ID <4EB80F56.4000007@redhat.com>
Download mbox | patch
Permalink /patch/124142/
State New
Headers show

Comments

Aldy Hernandez - Nov. 7, 2011, 5:03 p.m.
>> Notice I am hijacking the alias_pair object, because it has everything we
>> need, though the DECL_UID goes in a field called emitted_diags.  I am
>> avoiding having to create an exact same object with the exact same fields.
>>   I can change duplicate this, if it's a big eye sore.
>
> Yes, please duplicate this - alias_pairs are going away (hopefully for 4.7).
> And in that light, simply use a heap allocated vector - it's
> short-lived after all.
>
>
> Otherwise ok.

I have made the changes you suggested, and I also renamed tm_clone_pairs 
to tm_clone_hash to avoid confusion with the vector table.  We have too 
many tm_clone_* tables :).

Are you still OK with this patch? (Tests still going).

Patch

Index: ChangeLog.tm-merge
===================================================================
--- ChangeLog.tm-merge	(revision 181067)
+++ ChangeLog.tm-merge	(working copy)
@@ -120,7 +120,7 @@ 
 	(GTFILES): Add trans-mem.c.
 	* omp-low.c (WALK_SUBSTMTS): Add GIMPLE_TRANSACTION.
 	* output.h (record_tm_clone_pair, finish_tm_clone_pairs,
-	finish_tm_clone_pairs_1, get_tm_clone_pair): Declare.
+	get_tm_clone_pair): Declare.
 	* params.def (PARAM_TM_MAX_AGGREGATE_SIZE): New.
 	* passes.c (init_optimization_passes): Place transactional memory
 	passes.
@@ -189,6 +189,7 @@ 
 	(build_tm_abort_call, is_tm_safe, is_tm_pure,
 	is_tm_may_cancel_outer, is_tm_ending_fndecl, record_tm_replacement,
 	tm_malloc_replacement): Declare.
-	* varasm.c (tm_clone_pairs): New.
-	(record_tm_clone_pair, finish_tm_clone_pairs, finish_tm_clone_pairs_1,
-	get_tm_clone_pair): New.
+	* varasm.c (tm_clone_hash): New.
+	(record_tm_clone_pair, finish_tm_clone_pairs, get_tm_clone_pair,
+	dump_tm_clone_to_vec, dump_tm_clone_pairs, tm_alias_pair_cmp): New.
+	(struct tm_alias_pair): New.  Declare VEC types for object.
Index: varasm.c
===================================================================
--- varasm.c	(revision 181028)
+++ varasm.c	(working copy)
@@ -5864,15 +5864,15 @@  assemble_alias (tree decl, tree target)
    considered to be their own clone.  */
 
 static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
-     htab_t tm_clone_pairs;
+     htab_t tm_clone_hash;
 
 void
 record_tm_clone_pair (tree o, tree n)
 {
   struct tree_map **slot, *h;
 
-  if (tm_clone_pairs == NULL)
-    tm_clone_pairs = htab_create_ggc (32, tree_map_hash, tree_map_eq, 0);
+  if (tm_clone_hash == NULL)
+    tm_clone_hash = htab_create_ggc (32, tree_map_hash, tree_map_eq, 0);
 
   h = ggc_alloc_tree_map ();
   h->hash = htab_hash_pointer (o);
@@ -5880,20 +5880,20 @@  record_tm_clone_pair (tree o, tree n)
   h->to = n;
 
   slot = (struct tree_map **)
-    htab_find_slot_with_hash (tm_clone_pairs, h, h->hash, INSERT);
+    htab_find_slot_with_hash (tm_clone_hash, h, h->hash, INSERT);
   *slot = h;
 }
 
 tree
 get_tm_clone_pair (tree o)
 {
-  if (tm_clone_pairs)
+  if (tm_clone_hash)
     {
       struct tree_map *h, in;
 
       in.base.from = o;
       in.hash = htab_hash_pointer (o);
-      h = (struct tree_map *) htab_find_with_hash (tm_clone_pairs,
+      h = (struct tree_map *) htab_find_with_hash (tm_clone_hash,
 						   &in, in.hash);
       if (h)
 	return h->to;
@@ -5901,58 +5901,117 @@  get_tm_clone_pair (tree o)
   return NULL_TREE;
 }
 
-/* Helper function for finish_tm_clone_pairs.  Dump the clone table.  */
+typedef struct tm_alias_pair
+{
+  unsigned int uid;
+  tree from;
+  tree to;
+} tm_alias_pair;
 
-int
-finish_tm_clone_pairs_1 (void **slot, void *info ATTRIBUTE_UNUSED)
+DEF_VEC_O(tm_alias_pair);
+DEF_VEC_ALLOC_O(tm_alias_pair,heap);
+
+/* Helper function for finish_tm_clone_pairs.  Dump a hash table entry
+   into a VEC in INFO.  */
+
+static int
+dump_tm_clone_to_vec (void **slot, void *info)
 {
   struct tree_map *map = (struct tree_map *) *slot;
-  bool *switched = (bool *) info;
-  tree src = map->base.from;
-  tree dst = map->to;
-  struct cgraph_node *src_n = cgraph_get_node (src);
-  struct cgraph_node *dst_n = cgraph_get_node (dst);
-
-  /* The function ipa_tm_create_version() marks the clone as needed if
-     the original function was needed.  But we also mark the clone as
-     needed if we ever called the clone indirectly through
-     TM_GETTMCLONE.  If neither of these are true, we didn't generate
-     a clone, and we didn't call it indirectly... no sense keeping it
-     in the clone table.  */
-  if (!dst_n || !dst_n->needed)
-    return 1;
+  VEC(tm_alias_pair,heap) **tm_alias_pairs
+    = (VEC(tm_alias_pair, heap) **) info;
+  tm_alias_pair *p;
+
+  p = VEC_safe_push (tm_alias_pair, heap, *tm_alias_pairs, NULL);
+  p->from = map->base.from;
+  p->to = map->to;
+  p->uid = DECL_UID (p->from);
+  return 1;
+}
 
-  /* This covers the case where we have optimized the original
-     function away, and only access the transactional clone.  */
-  if (!src_n || !src_n->needed)
-    return 1;
+/* Dump the actual pairs to the .tm_clone_table section.  */
+
+static void
+dump_tm_clone_pairs (VEC(tm_alias_pair,heap) *tm_alias_pairs)
+{
+  unsigned i;
+  tm_alias_pair *p;
+  bool switched = false;
 
-  if (!*switched)
+  FOR_EACH_VEC_ELT (tm_alias_pair, tm_alias_pairs, i, p)
     {
-      switch_to_section (get_named_section (NULL, ".tm_clone_table", 3));
-      assemble_align (POINTER_SIZE);
-      *switched = true;
+      tree src = p->from;
+      tree dst = p->to;
+      struct cgraph_node *src_n = cgraph_get_node (src);
+      struct cgraph_node *dst_n = cgraph_get_node (dst);
+
+      /* The function ipa_tm_create_version() marks the clone as needed if
+	 the original function was needed.  But we also mark the clone as
+	 needed if we ever called the clone indirectly through
+	 TM_GETTMCLONE.  If neither of these are true, we didn't generate
+	 a clone, and we didn't call it indirectly... no sense keeping it
+	 in the clone table.  */
+      if (!dst_n || !dst_n->needed)
+	continue;
+
+      /* This covers the case where we have optimized the original
+	 function away, and only access the transactional clone.  */
+      if (!src_n || !src_n->needed)
+	continue;
+
+      if (!switched)
+	{
+	  switch_to_section (get_named_section (NULL, ".tm_clone_table", 3));
+	  assemble_align (POINTER_SIZE);
+	  switched = true;
+	}
+
+      assemble_integer (XEXP (DECL_RTL (src), 0),
+			POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+      assemble_integer (XEXP (DECL_RTL (dst), 0),
+			POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
     }
+}
 
-  assemble_integer (XEXP (DECL_RTL (src), 0),
-		    POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
-  assemble_integer (XEXP (DECL_RTL (dst), 0),
-		    POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
-  return 1;
+/* Helper comparison function for qsorting by the DECL_UID stored in
+   alias_pair->emitted_diags.  */
+
+static int
+tm_alias_pair_cmp (const void *x, const void *y)
+{
+  const tm_alias_pair *p1 = (const tm_alias_pair *) x;
+  const tm_alias_pair *p2 = (const tm_alias_pair *) y;
+  if (p1->uid < p2->uid)
+    return -1;
+  if (p1->uid > p2->uid)
+    return 1;
+  return 0;
 }
 
 void
 finish_tm_clone_pairs (void)
 {
-  bool switched = false;
+  VEC(tm_alias_pair,heap) *tm_alias_pairs = NULL;
 
-  if (tm_clone_pairs == NULL)
+  if (tm_clone_hash == NULL)
     return;
 
-  htab_traverse_noresize (tm_clone_pairs, finish_tm_clone_pairs_1,
-			  (void *) &switched);
-  htab_delete (tm_clone_pairs);
-  tm_clone_pairs = NULL;
+  /* We need a determenistic order for the .tm_clone_table, otherwise
+     we will get bootstrap comparison failures, so dump the hash table
+     to a vector, sort it, and dump the vector.  */
+
+  /* Dump the hashtable to a vector.  */
+  htab_traverse_noresize (tm_clone_hash, dump_tm_clone_to_vec,
+			  (void *) &tm_alias_pairs);
+  /* Sort it.  */
+  VEC_qsort (tm_alias_pair, tm_alias_pairs, tm_alias_pair_cmp);
+
+  /* Dump it.  */
+  dump_tm_clone_pairs (tm_alias_pairs);
+
+  htab_delete (tm_clone_hash);
+  tm_clone_hash = NULL;
+  VEC_free (tm_alias_pair, heap, tm_alias_pairs);
 }
 
 
Index: output.h
===================================================================
--- output.h	(revision 181028)
+++ output.h	(working copy)
@@ -608,7 +608,6 @@  extern void output_section_asm_op (const
 
 extern void record_tm_clone_pair (tree, tree);
 extern void finish_tm_clone_pairs (void);
-extern int finish_tm_clone_pairs_1 (void **, void *);
 extern tree get_tm_clone_pair (tree);
 
 extern void default_asm_output_source_filename (FILE *, const char *);