summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-07 19:11:18 +0000
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-07 19:11:18 +0000
commite3a677c673623b2773eec7bcd2639014cd03299f (patch)
treecf0902ba9a2f29ec55ad2aa6b2470807ffa2f936
parent91a00b3201b5b22613e193664a79149bd8a3fa06 (diff)
downloadgcc-e3a677c673623b2773eec7bcd2639014cd03299f.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/transactional-memory@181108 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.tm-merge9
-rw-r--r--gcc/output.h1
-rw-r--r--gcc/varasm.c143
3 files changed, 106 insertions, 47 deletions
diff --git a/gcc/ChangeLog.tm-merge b/gcc/ChangeLog.tm-merge
index d27ccec6d9a..0be6264d7e6 100644
--- a/gcc/ChangeLog.tm-merge
+++ b/gcc/ChangeLog.tm-merge
@@ -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.
diff --git a/gcc/output.h b/gcc/output.h
index 9c539559a18..e47eddf2735 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -608,7 +608,6 @@ extern void output_section_asm_op (const void *);
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 *);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 8662b8fe396..ed27dce7b0a 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -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);
}