summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-live.c
diff options
context:
space:
mode:
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-30 21:36:32 +0000
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-30 21:36:32 +0000
commitc3292d4288f004e58355d00106c0022fb3972cac (patch)
tree846178c38c493762bf802c9fd5ce7f67e1f92d30 /gcc/tree-ssa-live.c
parentb4fc673b1af63ac26fd65a6ae59a5e0fd44634a7 (diff)
downloadgcc-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.c261
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");