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.

From-SVN: r119378
This commit is contained in:
Andrew MacLeod 2006-11-30 21:36:32 +00:00 committed by Andrew Macleod
parent f7b410e0fb
commit 9fa2efcd3d
3 changed files with 188 additions and 132 deletions

View File

@ -1,3 +1,25 @@
2006-11-30 Andrew Macleod <amacleod@redhat.com>
* 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.
2006-11-30 Jan Hubicka <jh@suse.cz>
PR middle-end/30028

View File

@ -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;
}
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)
{
if (node->second_partition == p2)
return node;
else
if (node->second_partition > p2)
break;
tmp = node;
}
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;
p.first_partition = p2;
p.second_partition = p1;
}
else
{
/* This is now the first node in the list. */
node->next = cl->list[p1];
cl->list[p1] = 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 && !pair)
{
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,15 +1280,56 @@ 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
to least important. */
@ -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);
/* 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);
if (num == 1)
return;
if (num == 2)
{
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)
{
list = XNEWVEC (partition_pair_p, num);
count = 0;
for (p = chain; p != NULL; p = p->next)
list[count++] = p;
gcc_assert (count == num);
qsort (list, count, sizeof (partition_pair_p), compare_pairs);
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
{
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;
}
}
}
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");

View File

@ -147,7 +147,7 @@ var_to_partition (var_map map, tree var)
else
{
ann = var_ann (var);
if (ann->out_of_ssa_tag)
if (ann && ann->out_of_ssa_tag)
part = VAR_ANN_PARTITION (ann);
else
part = NO_PARTITION;
@ -671,31 +671,26 @@ type_var_decompact (type_var_p tv)
all desired information has been collected, the object can be used to
order the pairs for processing. */
/* This structure defines a pair for coalescing. */
/* This structure defines a pair entry. */
typedef struct partition_pair_d
typedef struct partition_pair
{
int first_partition;
int second_partition;
int cost;
struct partition_pair_d *next;
} *partition_pair_p;
} * partition_pair_p;
/* This structure maintains the list of coalesce pairs.
When add_mode is true, list is a triangular shaped list of coalesce pairs.
The smaller partition number is used to index the list, and the larger is
index is located in a partition_pair_p object. These lists are sorted from
smallest to largest by 'second_partition'. New coalesce pairs are allowed
to be added in this mode.
When add_mode is false, the lists have all been merged into list[0]. The
rest of the lists are not used. list[0] is ordered from most desirable
coalesce to least desirable. pop_best_coalesce() retrieves the pairs
one at a time. */
extern unsigned int partition_pair_map_hash (const void *);
extern int partition_pair_map_eq (const void *, const void *);
/* This structure maintains the list of coalesce pairs. */
typedef struct coalesce_list_d
{
var_map map;
partition_pair_p *list;
htab_t list;
partition_pair_p *sorted;
int num_sorted;
bool add_mode;
} *coalesce_list_p;