From e3a677c673623b2773eec7bcd2639014cd03299f Mon Sep 17 00:00:00 2001 From: aldyh Date: Mon, 7 Nov 2011 19:11:18 +0000 Subject: 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 --- gcc/ChangeLog.tm-merge | 9 ++-- gcc/output.h | 1 - gcc/varasm.c | 143 ++++++++++++++++++++++++++++++++++--------------- 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); } -- cgit v1.2.1