diff options
author | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-30 21:36:32 +0000 |
---|---|---|
committer | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-30 21:36:32 +0000 |
commit | c3292d4288f004e58355d00106c0022fb3972cac (patch) | |
tree | 846178c38c493762bf802c9fd5ce7f67e1f92d30 /gcc/tree-ssa-live.c | |
parent | b4fc673b1af63ac26fd65a6ae59a5e0fd44634a7 (diff) | |
download | gcc-c3292d4288f004e58355d00106c0022fb3972cac.tar.gz |
Implement coalesce list with hash table instead of linked list.
* tree-ssa-live.c (create_coalesce_list): Create a hash table.
(COALESCE_HASH_FN): New. Define hash function.
(partition_pair_map_hash): New. Hash value for a partition pair.
(partition_pair_map_eq): New. Equality for hash pairs.
(create_coalesce_list): Create hash table.
(delete_coalesce_list): Free hash table.
(find_partition_pair): Find/create pairs in hash table.
(compare_pairs): Sort pairs in ascending order now.
(num_coalesce_pairs): New. Number of pairs in hash table.
(struct partition_pair_iterator): Iterator struct for pair table.
(first_partition_pair): Iterator function for first pair.
(end_partition_pair_p): Iterator function for end of iteration.
(next_partition_pair): Iterator function for next pair.
(FOR_EACH_PARTITION_PAIR): Macro for iterating over pairs.
(sort_coalesce_list): Sort pairs from hash table into an array.
(pop_best_coalesce): Take pairs from the array.
(dump_coalesce_list): Update to use hash table or sorted array.
* tree-ssa-live.h (struct partition_pair_d): Remove next field.
(struct coalesce_list_d): Add hash table related fields.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119378 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-live.c')
-rw-r--r-- | gcc/tree-ssa-live.c | 261 |
1 files changed, 150 insertions, 111 deletions
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index b34190f219f..e1525c1d003 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -1136,19 +1136,54 @@ type_var_init (var_map map) } +/* Hash function for 2 integer coalesce pairs. */ +#define COALESCE_HASH_FN(R1, R2) ((R2) * ((R2) - 1) / 2 + (R1)) + + +/* Return hash value for partition pair PAIR. */ + +unsigned int +partition_pair_map_hash (const void *pair) +{ + hashval_t a = (hashval_t)(((partition_pair_p)pair)->first_partition); + hashval_t b = (hashval_t)(((partition_pair_p)pair)->second_partition); + + return COALESCE_HASH_FN (a,b); +} + + +/* Return TRUE if PAIR1 is equivilent to PAIR2. */ + +int +partition_pair_map_eq (const void *pair1, const void *pair2) +{ + partition_pair_p p1 = (partition_pair_p) pair1; + partition_pair_p p2 = (partition_pair_p) pair2; + + return (p1->first_partition == p2->first_partition + && p1->second_partition == p2->second_partition); +} + + /* Create a new coalesce list object from MAP and return it. */ coalesce_list_p create_coalesce_list (var_map map) { coalesce_list_p list; + unsigned size = num_ssa_names * 3; - list = (coalesce_list_p) xmalloc (sizeof (struct coalesce_list_d)); + if (size < 40) + size = 40; + + list = xmalloc (sizeof (struct coalesce_list_d)); + list->list = htab_create (size, partition_pair_map_hash, + partition_pair_map_eq, NULL); list->map = map; + list->sorted = NULL; list->add_mode = true; - list->list = (partition_pair_p *) xcalloc (num_var_partitions (map), - sizeof (struct partition_pair_d)); + list->num_sorted = 0; return list; } @@ -1158,7 +1193,10 @@ create_coalesce_list (var_map map) void delete_coalesce_list (coalesce_list_p cl) { - free (cl->list); + htab_delete (cl->list); + if (cl->sorted) + free (cl->sorted); + gcc_assert (cl->num_sorted == 0); free (cl); } @@ -1170,52 +1208,38 @@ delete_coalesce_list (coalesce_list_p cl) static partition_pair_p find_partition_pair (coalesce_list_p cl, int p1, int p2, bool create) { - partition_pair_p node, tmp; - int s; + struct partition_pair p, *pair; + void **slot; + unsigned int hash; - /* Normalize so that p1 is the smaller value. */ + /* normalize so that p1 is the smaller value. */ if (p2 < p1) { - s = p1; - p1 = p2; - p2 = s; + p.first_partition = p2; + p.second_partition = p1; } - - tmp = NULL; - - /* The list is sorted such that if we find a value greater than p2, - p2 is not in the list. */ - for (node = cl->list[p1]; node; node = node->next) + else { - if (node->second_partition == p2) - return node; - else - if (node->second_partition > p2) - break; - tmp = node; + p.first_partition = p1; + p.second_partition = p2; } + + + hash = partition_pair_map_hash (&p); + pair = (struct partition_pair *) htab_find_with_hash (cl->list, &p, hash); - if (!create) - return NULL; - - node = (partition_pair_p) xmalloc (sizeof (struct partition_pair_d)); - node->first_partition = p1; - node->second_partition = p2; - node->cost = 0; - - if (tmp != NULL) - { - node->next = tmp->next; - tmp->next = node; - } - else + if (create && !pair) { - /* This is now the first node in the list. */ - node->next = cl->list[p1]; - cl->list[p1] = node; + gcc_assert (cl->add_mode); + pair = xmalloc (sizeof (struct partition_pair)); + pair->first_partition = p.first_partition; + pair->second_partition = p.second_partition; + pair->cost = 0; + slot = htab_find_slot_with_hash (cl->list, pair, hash, INSERT); + *(struct partition_pair **)slot = pair; } - return node; + return pair; } /* Return cost of execution of copy instruction with FREQUENCY @@ -1256,14 +1280,55 @@ add_coalesce (coalesce_list_p cl, int p1, int p2, } -/* Comparison function to allow qsort to sort P1 and P2 in descending order. */ +/* Comparison function to allow qsort to sort P1 and P2 in Ascendiong order. */ static int compare_pairs (const void *p1, const void *p2) { - return (*(partition_pair_p *)p2)->cost - (*(partition_pair_p *)p1)->cost; + return (*(partition_pair_p *)p1)->cost - (*(partition_pair_p *)p2)->cost; +} + + +static inline int +num_coalesce_pairs (coalesce_list_p cl) +{ + return htab_elements (cl->list); +} + +typedef struct +{ + htab_iterator hti; +} partition_pair_iterator; + +static inline partition_pair_p +first_partition_pair (coalesce_list_p cl, partition_pair_iterator *iter) +{ + partition_pair_p pair; + + pair = (partition_pair_p) first_htab_element (&(iter->hti), cl->list); + return pair; +} + +static inline bool +end_partition_pair_p (partition_pair_iterator *iter) +{ + return end_htab_p (&(iter->hti)); +} + +static inline partition_pair_p +next_partition_pair (partition_pair_iterator *iter) +{ + partition_pair_p pair; + + pair = (partition_pair_p) next_htab_element (&(iter->hti)); + return pair; } +#define FOR_EACH_PARTITION_PAIR(PAIR, ITER, CL) \ + for ((PAIR) = first_partition_pair ((CL), &(ITER)); \ + !end_partition_pair_p (&(ITER)); \ + (PAIR) = next_partition_pair (&(ITER))) + /* Prepare CL for removal of preferred pairs. When finished, list element 0 has all the coalesce pairs, sorted in order from most important coalesce @@ -1272,64 +1337,45 @@ int compare_pairs (const void *p1, const void *p2) void sort_coalesce_list (coalesce_list_p cl) { - unsigned x, num, count; - partition_pair_p chain, p; - partition_pair_p *list; + unsigned x, num; + partition_pair_p p; + partition_pair_iterator ppi; gcc_assert (cl->add_mode); cl->add_mode = false; - /* Compact the array of lists to a single list, and count the elements. */ - num = 0; - chain = NULL; - for (x = 0; x < num_var_partitions (cl->map); x++) - if (cl->list[x] != NULL) - { - for (p = cl->list[x]; p->next != NULL; p = p->next) - num++; - num++; - p->next = chain; - chain = cl->list[x]; - cl->list[x] = NULL; - } + /* allocate a vector for the pair pointers. */ + num = num_coalesce_pairs (cl); + cl->num_sorted = num; + if (num == 0) + return; + cl->sorted = XNEWVEC (partition_pair_p, num); - /* Only call qsort if there are more than 2 items. */ - if (num > 2) - { - list = XNEWVEC (partition_pair_p, num); - count = 0; - for (p = chain; p != NULL; p = p->next) - list[count++] = p; + /* Populate the vector with pointers to the partition pairs. */ + + x = 0; + FOR_EACH_PARTITION_PAIR (p, ppi, cl) + cl->sorted[x++] = p; + gcc_assert (x == num); - gcc_assert (count == num); - - qsort (list, count, sizeof (partition_pair_p), compare_pairs); + if (num == 1) + return; - p = list[0]; - for (x = 1; x < num; x++) - { - p->next = list[x]; - p = list[x]; - } - p->next = NULL; - cl->list[0] = list[0]; - free (list); - } - else + if (num == 2) { - cl->list[0] = chain; - if (num == 2) - { - /* Simply swap the two elements if they are in the wrong order. */ - if (chain->cost < chain->next->cost) - { - cl->list[0] = chain->next; - cl->list[0]->next = chain; - chain->next = NULL; - } + if (cl->sorted[0]->cost > cl->sorted[1]->cost) + { + p = cl->sorted[0]; + cl->sorted[0] = cl->sorted[1]; + cl->sorted[1] = p; } + return; } + + /* Only call qsort if there are more than 2 items. */ + if (num > 2) + qsort (cl->sorted, num, sizeof (partition_pair_p), compare_pairs); } @@ -1345,11 +1391,10 @@ pop_best_coalesce (coalesce_list_p cl, int *p1, int *p2) gcc_assert (!cl->add_mode); - node = cl->list[0]; - if (!node) + if (cl->num_sorted == 0) return NO_BEST_COALESCE; - cl->list[0] = node->next; + node = cl->sorted[--(cl->num_sorted)]; *p1 = node->first_partition; *p2 = node->second_partition; @@ -1729,40 +1774,34 @@ void dump_coalesce_list (FILE *f, coalesce_list_p cl) { partition_pair_p node; - int x, num; + partition_pair_iterator ppi; + int x; tree var; if (cl->add_mode) { fprintf (f, "Coalesce List:\n"); - num = num_var_partitions (cl->map); - for (x = 0; x < num; x++) + FOR_EACH_PARTITION_PAIR (node, ppi, cl) { - node = cl->list[x]; - if (node) - { - fprintf (f, "["); - print_generic_expr (f, partition_to_var (cl->map, x), TDF_SLIM); - fprintf (f, "] - "); - for ( ; node; node = node->next) - { - var = partition_to_var (cl->map, node->second_partition); - print_generic_expr (f, var, TDF_SLIM); - fprintf (f, "(%1d), ", node->cost); - } - fprintf (f, "\n"); - } + tree var1 = partition_to_var (cl->map, node->first_partition); + tree var2 = partition_to_var (cl->map, node->second_partition); + print_generic_expr (f, var1, TDF_SLIM); + fprintf (f, " <-> "); + print_generic_expr (f, var2, TDF_SLIM); + fprintf (f, " (%1d), ", node->cost); + fprintf (f, "\n"); } } else { fprintf (f, "Sorted Coalesce list:\n"); - for (node = cl->list[0]; node; node = node->next) + for (x = cl->num_sorted - 1 ; x >=0; x--) { + node = cl->sorted[x]; fprintf (f, "(%d) ", node->cost); var = partition_to_var (cl->map, node->first_partition); print_generic_expr (f, var, TDF_SLIM); - fprintf (f, " : "); + fprintf (f, " <-> "); var = partition_to_var (cl->map, node->second_partition); print_generic_expr (f, var, TDF_SLIM); fprintf (f, "\n"); |