This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] SSA->Normal coalescing patch
- From: Andrew MacLeod <amacleod at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: 11 Feb 2004 10:01:35 -0500
- Subject: [tree-ssa] SSA->Normal coalescing patch
Although the SSA->normal pass has been capable of using a coalesce list
for a while, we havent really been making use of it, and it hadnt been
strenuously tested. This patch remedies that.
Along the way, I encountered a couple of minor bugs in the coalescing,
which were real bears to track down. To that end, there is more verbose
debugging information now which can help to figure out exactly what is
going on.
Previously when we coalesced, we first coalesced everything that *had*
to be coalesced, such as parameters to the first use and things across
abnormal edges. Then we simply started merging remaining partitions
which didnt conflict. The right way to do that would be to coalesce them
in order of significance. If there is a copy in an inner loop, thats
much more important to coalesce than a copy at the outer level.
At the moment, the execution costs of edges and blocks aren't set, so we
don't use those values, but it'll be trivial to add. Right now its just
a straight count of the number of coalesces.
Coalescing now has 2 phases. You can ask for coalescing via sorted
coalesce list, or simply by partition like we use to. Or you can do
both, coalesce by list first to make sure the important ones are
coalesced, and then coalesce everything else.
One advantage of using *just* the coalesce list is that anything which
is related via a copy is coalesced, and you get automatic splitting of
live ranges since all the other ssa versions of that variable will get
unique variables. Doesn't do much for debugging, but it can have some
interesting benefits. GAP jumps from 582 spec marks to 594. Of course,
the opposite can be true, since PERL drops from 618 to 542. Blah.
Anyway, this bootstraps on x86 and produces no new failures. The
default I currently have set uses the coalesce list first, and then
coalesces the rest of the partitions. SPEC2000 is pretty much
unchanged, although there is some minor variation from benchmark to
benchmark. I had a drop from 444 to 443, so its not significant. GAP was
the big loser, so Im going to take a look at why it dropped. GZIP showed
a nice improvement, so we must be getting a useful coalesce there.
Compile time is marginally increased, some of that due to the coalesce
list, and some due to fixing the bugs I encountered. A compilation of
all gcc files increased the SSA->normal pass time from 4.1 seconds to
about 4.5. Overall compile time was about 556 seconds for both... so its
nothing significant. (ie, tree optimizers were .5 seconds slower,
overall compile time was .5 seconds faster..)
I'm planning to check this in shortly.
Andrew
* tree-ssa-live.c (compare_pairs): New. Coalesce list cost function.
(sort_coalesce_list): Use qsort() to sort list by cost.
(coalesce_tpa_members): Use correct partition representatives. Add
more debug information. Allow coalesce by list, root_var, or both.
(tpa_dump): Show partition index.
* tree-ssa-live.h (SSANORM_COALESCE_PARTITIONS): New flag.
(SSANORM_USE_COALESCE_LIST): New flag.
* tree-ssa.c (create_temp): Don't mark as used when created.
(coalesce_ssa_name): Create coalesce list if requested. Add more
debug output.
(assign_vars): Add additional debug info.
(remove_ssa_form): Perform TER after assign_vars().
(rewrite_vars_out_of_ssa): Pass coalesce partitions flag to
remove_ssa_form.
(rewrite_out_of_ssa): Add coalesce list flag to remove_ssa_form call.
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.c,v
retrieving revision 1.1.2.34
diff -c -p -r1.1.2.34 tree-ssa-live.c
*** tree-ssa-live.c 15 Jan 2004 15:38:26 -0000 1.1.2.34
--- tree-ssa-live.c 11 Feb 2004 13:12:59 -0000
*************** add_coalesce (coalesce_list_p cl, int p1
*** 1175,1180 ****
--- 1175,1187 ----
node->cost += value;
}
+ /* Comparison function for qsort to sort in descending order. */
+
+ static
+ int compare_pairs (const void *p1, const void *p2)
+ {
+ return (*(partition_pair_p *)p2)->cost - (*(partition_pair_p *)p1)->cost;
+ }
/* Prepare the coalesce list for removal of preferred pairs. When finished,
list element 0 has all the coalesce pairs, sorted in order from most
*************** add_coalesce (coalesce_list_p cl, int p1
*** 1183,1261 ****
void
sort_coalesce_list (coalesce_list_p cl)
{
! int x, num, last, val, odd;
! partition_pair_p n1, n1_prev ,n2, n2_end, n2_last;
if (!cl->add_mode)
abort();
cl->add_mode = false;
- last = 0;
! /* Compact the list so we know how many lists there are. */
! num = num_var_partitions (cl->map);
! for (x = 0; x < num; x++)
if (cl->list[x] != NULL)
{
! if (x != last)
! cl->list[last] = cl->list[x];
! last++;
}
! if (last == 0)
! return;
!
! num = last / 2;
! odd = last % 2;
! /* While there is more than one list, merge lists in pairs until only
! 1 list remains. */
! while (num >= 1)
{
! last = 0;
! for (x = 0; x < num; x++)
! {
! n1 = cl->list[x * 2];
! n2 = cl->list[x * 2 + 1];
! for (n1_prev = NULL; n1 && n2; n1 = n1->next)
{
! val = n1->second_partition;
! if (n2->second_partition <= val)
! {
! n2_last = n2;
! /* Merge as many as will fit before n1. */
! for (n2_end = n2; n2_end; n2_end = n2_end->next)
! {
! if (n2_end->second_partition > val)
! break;
! n2_last = n2_end;
! }
! if (n1_prev)
! {
! n2_last->next = n1;
! n1_prev->next = n2;
! }
! else
! {
! n2_last->next = n1;
! cl->list[x * 2] = n2;
! }
! n2 = n2_end;
! }
! n1_prev = n1;
}
- /* Append anything left over should be appended to the end. */
- if (n2)
- n1_prev->next = n2;
- cl->list[last++] = cl->list[x * 2];
}
-
- /* If there were an odd number of lists, move the last one up as well. */
- if (odd)
- cl->list[last++] = cl->list[num * 2];
-
- num = last / 2;
- odd = last % 2;
}
}
--- 1190,1256 ----
void
sort_coalesce_list (coalesce_list_p cl)
{
! int x, num, count;
! partition_pair_p chain, p;
! partition_pair_p *list;
if (!cl->add_mode)
abort();
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;
}
! /* Only call qsort if there are more than 2 items. */
! if (num > 2)
! {
! list = xmalloc (sizeof (partition_pair_p) * num);
! count = 0;
! for (p = chain; p != NULL; p = p->next)
! list[count++] = p;
!
! #ifdef ENABLE_CHECKING
! if (count != num)
! abort ();
! #endif
!
! 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;
}
}
}
}
*************** build_tree_conflict_graph (tree_live_inf
*** 1486,1572 ****
/* This routine will attempt to coalesce the elements in a TPA list.
! If a coalesce_list is provided, those coalesces are attempted first.
! If a file pointer is provided, debug output will be sent there. */
void
coalesce_tpa_members (tpa_p tpa, conflict_graph graph, var_map map,
coalesce_list_p cl, FILE *debug)
{
! int x, y, z;
tree var, tmp;
! /* Attempt to coalesce any items in a coalesce list first. */
if (cl)
{
while (pop_best_coalesce (cl, &x, &y) != NO_BEST_COALESCE)
{
if (!conflict_graph_conflict_p (graph, x, y))
{
- if (tpa_find_tree (tpa, x) == TPA_NONE
- || tpa_find_tree (tpa, y) == TPA_NONE)
- continue;
- var = partition_to_var (map, x);
- tmp = partition_to_var (map, y);
z = var_union (map, var, tmp);
if (z == NO_PARTITION)
! continue;
! conflict_graph_merge_regs (graph, x, y);
/* z is the new combined partition. We need to remove the other
partition from the list. Set x to be that other partition. */
if (z == x)
- x = y;
- z = tpa_find_tree (tpa, x);
- tpa_remove_partition (tpa, z, x);
- if (debug)
{
! fprintf (debug, "Coalesce (list): ");
! print_generic_expr (debug, var, TDF_SLIM);
! fprintf (debug, " and ");
! print_generic_expr (debug, tmp, TDF_SLIM);
! fprintf (debug, "\n");
}
}
}
!
}
for (x = 0; x < tpa_num_trees (tpa); x++)
{
while (tpa_first_partition (tpa, x) != TPA_NONE)
{
! /* Coalesce first partition with everything that doesn't conflict. */
y = tpa_first_partition (tpa, x);
tpa_remove_partition (tpa, x, y);
var = partition_to_var (map, y);
for (z = tpa_next_partition (tpa, y);
z != TPA_NONE;
z = tpa_next_partition (tpa, z))
{
tmp = partition_to_var (map, z);
! /* If partitions are already merged, don't check for conflict. */
! if (tmp == var)
! tpa_remove_partition (tpa, x, z);
! else if (!conflict_graph_conflict_p (graph, y, z))
{
! if (tpa_find_tree (tpa, y) == TPA_NONE
! || tpa_find_tree (tpa, z) == TPA_NONE)
! continue;
! if (var_union (map, var, tmp) == NO_PARTITION)
! continue;
tpa_remove_partition (tpa, x, z);
- conflict_graph_merge_regs (graph, y, z);
if (debug)
! {
! fprintf (debug, "Coalesce : ");
! print_generic_expr (debug, var, TDF_SLIM);
! fprintf (debug, " and ");
! print_generic_expr (debug, tmp, TDF_SLIM);
! fprintf (debug, "\n");
! }
}
}
}
}
--- 1481,1640 ----
/* This routine will attempt to coalesce the elements in a TPA list.
! If a coalesce_list is provided, those coalesces are attempted. Otherwise
! an attempt is made to coalesce as many elements within a partition as
! possible. If a file pointer is provided, debug output will be sent
! there. */
void
coalesce_tpa_members (tpa_p tpa, conflict_graph graph, var_map map,
coalesce_list_p cl, FILE *debug)
{
! int x, y, z, w;
tree var, tmp;
! /* Attempt to coalesce any items in a coalesce list. */
if (cl)
{
while (pop_best_coalesce (cl, &x, &y) != NO_BEST_COALESCE)
{
+ if (debug)
+ {
+ fprintf (debug, "Coalesce list: (%d)", x);
+ print_generic_expr (debug, partition_to_var (map, x), TDF_SLIM);
+ fprintf (debug, " & (%d)", y);
+ print_generic_expr (debug, partition_to_var (map, y), TDF_SLIM);
+ }
+
+ if (tpa_find_tree (tpa, x) == TPA_NONE
+ || tpa_find_tree (tpa, y) == TPA_NONE)
+ {
+ if (debug)
+ {
+ if (tpa_find_tree (tpa, x) == TPA_NONE)
+ fprintf (debug, ": Fail %d non TPA.\n", x);
+ else
+ fprintf (debug, ": Fail %d non TPA.\n", y);
+ }
+ continue;
+ }
+ var = partition_to_var (map, x);
+ tmp = partition_to_var (map, y);
+ x = var_to_partition (map, var);
+ y = var_to_partition (map, tmp);
+ if (debug)
+ fprintf (debug, " [map: %d, %d] ", x, y);
+ if (x == y)
+ {
+ if (debug)
+ fprintf (debug, ": Already Coalesced.\n");
+ continue;
+ }
if (!conflict_graph_conflict_p (graph, x, y))
{
z = var_union (map, var, tmp);
if (z == NO_PARTITION)
! {
! if (debug)
! fprintf (debug, ": Unable to perform partition union.\n");
! continue;
! }
/* z is the new combined partition. We need to remove the other
partition from the list. Set x to be that other partition. */
if (z == x)
{
! conflict_graph_merge_regs (graph, x, y);
! w = tpa_find_tree (tpa, y);
! tpa_remove_partition (tpa, w, y);
}
+ else
+ {
+ conflict_graph_merge_regs (graph, y, x);
+ w = tpa_find_tree (tpa, x);
+ tpa_remove_partition (tpa, w, x);
+ }
+
+ if (debug)
+ fprintf (debug, ": Success -> %d\n", z);
}
+ else
+ if (debug)
+ fprintf (debug, ": Fail due to conflict\n");
}
! /* If using a coalesce list, don't try to coalesce anything else. */
! return;
}
for (x = 0; x < tpa_num_trees (tpa); x++)
{
while (tpa_first_partition (tpa, x) != TPA_NONE)
{
! int p1, p2;
! /* Coalesce first partition with anything that doesn't conflict. */
y = tpa_first_partition (tpa, x);
tpa_remove_partition (tpa, x, y);
+
var = partition_to_var (map, y);
+ /* p1 is the partition representative to which y belongs. */
+ p1 = var_to_partition (map, var);
+
for (z = tpa_next_partition (tpa, y);
z != TPA_NONE;
z = tpa_next_partition (tpa, z))
{
tmp = partition_to_var (map, z);
! /* p2 is the partition representative to which z belongs. */
! p2 = var_to_partition (map, tmp);
! if (debug)
{
! fprintf (debug, "Coalesce : ");
! print_generic_expr (debug, var, TDF_SLIM);
! fprintf (debug, " &");
! print_generic_expr (debug, tmp, TDF_SLIM);
! fprintf (debug, " (%d ,%d)", p1, p2);
! }
+ /* If partitions are already merged, don't check for conflict. */
+ if (tmp == var)
+ {
tpa_remove_partition (tpa, x, z);
if (debug)
! fprintf (debug, ": Already coalesced\n");
}
+ else
+ if (!conflict_graph_conflict_p (graph, p1, p2))
+ {
+ int v;
+ if (tpa_find_tree (tpa, y) == TPA_NONE
+ || tpa_find_tree (tpa, z) == TPA_NONE)
+ {
+ if (debug)
+ fprintf (debug, ": Fail Non TPA member\n");
+ continue;
+ }
+ if ((v = var_union (map, var, tmp)) == NO_PARTITION)
+ {
+ if (debug)
+ fprintf (debug, ": Fail Unable to combine partitions\n");
+ continue;
+ }
+
+ tpa_remove_partition (tpa, x, z);
+ if (v == p1)
+ conflict_graph_merge_regs (graph, v, z);
+ else
+ {
+ /* Update the first partition's representative. */
+ conflict_graph_merge_regs (graph, v, y);
+ p1 = v;
+ }
+ if (debug)
+ fprintf (debug, ": Success -> %d\n", v);
+ }
+ else
+ if (debug)
+ fprintf (debug, ": Fail, Conflict\n");
}
}
}
*************** tpa_dump (FILE *f, tpa_p tpa)
*** 1636,1641 ****
--- 1704,1710 ----
i != TPA_NONE;
i = tpa_next_partition (tpa, i))
{
+ fprintf (f, "(%d)",i);
print_generic_expr (f, partition_to_var (tpa->map, i), TDF_SLIM);
fprintf (f, " ");
#ifdef ENABLE_CHECKING
Index: tree-ssa-live.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.h,v
retrieving revision 1.1.2.15
diff -c -p -r1.1.2.15 tree-ssa-live.h
*** tree-ssa-live.h 29 Jan 2004 21:11:50 -0000 1.1.2.15
--- tree-ssa-live.h 11 Feb 2004 13:12:59 -0000
*************** typedef struct _var_map
*** 61,66 ****
--- 61,68 ----
#define SSANORM_PERFORM_TER 0x1
#define SSANORM_COMBINE_TEMPS 0x2
#define SSANORM_REMOVE_ALL_PHIS 0x4
+ #define SSANORM_COALESCE_PARTITIONS 0x8
+ #define SSANORM_USE_COALESCE_LIST 0x10
extern var_map init_var_map (int);
extern void delete_var_map (var_map);
*************** typedef struct partition_pair_d
*** 599,606 ****
/* 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. Each of these lists are sorted
! from smallest to largest 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
--- 601,608 ----
/* 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
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.192
diff -c -p -r1.1.4.192 tree-ssa.c
*** tree-ssa.c 9 Feb 2004 02:03:48 -0000 1.1.4.192
--- tree-ssa.c 11 Feb 2004 13:12:59 -0000
*************** static int elim_unvisited_predecessor (e
*** 205,211 ****
static void elim_backward (elim_graph, int);
static void elim_create (elim_graph, int);
static void eliminate_phi (edge, int, elim_graph);
! static tree_live_info_p coalesce_ssa_name (var_map, int flags);
static void assign_vars (var_map);
static bool replace_variable (var_map, tree *, tree *);
static void eliminate_virtual_phis (void);
--- 205,211 ----
static void elim_backward (elim_graph, int);
static void elim_create (elim_graph, int);
static void eliminate_phi (edge, int, elim_graph);
! static tree_live_info_p coalesce_ssa_name (var_map, int);
static void assign_vars (var_map);
static bool replace_variable (var_map, tree *, tree *);
static void eliminate_virtual_phis (void);
*************** create_temp (tree t)
*** 953,961 ****
tmp = create_tmp_var (type, name);
add_referenced_tmp_var (tmp);
- /* Mark the new variable as used. */
- set_is_used (tmp);
-
/* add_referenced_tmp_var will create the annotation and set up some
of the flags in the annotation. However, some flags we need to
inherit from our original variable. */
--- 953,958 ----
*************** coalesce_abnormal_edges (var_map map, co
*** 1466,1481 ****
static tree_live_info_p
coalesce_ssa_name (var_map map, int flags)
{
! int num, x;
sbitmap live;
! tree var;
root_var_p rv;
tree_live_info_p liveinfo;
var_ann_t ann;
conflict_graph graph;
if (num_var_partitions (map) <= 1)
return NULL;
liveinfo = calculate_live_on_entry (map);
calculate_live_on_exit (liveinfo);
--- 1463,1484 ----
static tree_live_info_p
coalesce_ssa_name (var_map map, int flags)
{
! int num, x, i;
sbitmap live;
! tree var, phi;
root_var_p rv;
tree_live_info_p liveinfo;
var_ann_t ann;
conflict_graph graph;
+ basic_block bb;
+ coalesce_list_p cl = NULL;
if (num_var_partitions (map) <= 1)
return NULL;
+
+ /* If no preference given, use cheap coalescing of all partitions. */
+ if ((flags & (SSANORM_COALESCE_PARTITIONS | SSANORM_USE_COALESCE_LIST)) == 0)
+ flags |= SSANORM_COALESCE_PARTITIONS;
liveinfo = calculate_live_on_entry (map);
calculate_live_on_exit (liveinfo);
*************** coalesce_ssa_name (var_map map, int flag
*** 1484,1503 ****
/* Remove single element variable from the list. */
root_var_compact (rv);
/* Build a conflict graph. */
! graph = build_tree_conflict_graph (liveinfo, rv, NULL);
/* Put the single element variables back in. */
root_var_decompact (rv);
/* First, coalesce all live on entry variables to their root variable.
! This will ensure the first use is coming from the right memory location. */
live = sbitmap_alloc (num_var_partitions (map));
sbitmap_zero (live);
/* Set 'live' vector to indicate live on entry partitions. */
-
num = num_var_partitions (map);
for (x = 0 ; x < num; x++)
{
--- 1487,1570 ----
/* Remove single element variable from the list. */
root_var_compact (rv);
+ if (flags & SSANORM_USE_COALESCE_LIST)
+ {
+ cl = create_coalesce_list (map);
+
+ /* Add all potential copies via PHI arguments to the list. */
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree res = PHI_RESULT (phi);
+ int p = var_to_partition (map, res);
+ if (p == NO_PARTITION)
+ continue;
+ for (x = 0; x < PHI_NUM_ARGS (phi); x++)
+ {
+ tree arg = PHI_ARG_DEF (phi, x);
+ int p2;
+
+ if (TREE_CODE (arg) != SSA_NAME)
+ continue;
+ if (SSA_NAME_VAR (res) != SSA_NAME_VAR (arg))
+ continue;
+ p2 = var_to_partition (map, PHI_ARG_DEF (phi, x));
+ if (p2 != NO_PARTITION)
+ add_coalesce (cl, p, p2, 1);
+ }
+ }
+ }
+
+ /* Coalesce all the result decls together. */
+ var = NULL_TREE;
+ i = 0;
+ for (x = 0; x < num_var_partitions (map); x++)
+ {
+ tree p = partition_to_var (map, x);
+ if (TREE_CODE (SSA_NAME_VAR(p)) == RESULT_DECL)
+ {
+ if (var == NULL_TREE)
+ {
+ var = p;
+ i = x;
+ }
+ else
+ add_coalesce (cl, i, x, 1);
+ }
+ }
+ }
+
/* Build a conflict graph. */
! graph = build_tree_conflict_graph (liveinfo, rv, cl);
!
! if (cl)
! {
! if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
! {
! fprintf (tree_dump_file, "Before sorting:\n");
! dump_coalesce_list (tree_dump_file, cl);
! }
!
! sort_coalesce_list (cl);
!
! if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
! {
! fprintf (tree_dump_file, "\nAfter sorting:\n");
! dump_coalesce_list (tree_dump_file, cl);
! }
! }
/* Put the single element variables back in. */
root_var_decompact (rv);
/* First, coalesce all live on entry variables to their root variable.
! This will ensure the first use is coming from the correct location. */
live = sbitmap_alloc (num_var_partitions (map));
sbitmap_zero (live);
/* Set 'live' vector to indicate live on entry partitions. */
num = num_var_partitions (map);
for (x = 0 ; x < num; x++)
{
*************** coalesce_ssa_name (var_map map, int flag
*** 1545,1556 ****
coalesce_abnormal_edges (map, graph, rv);
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
! dump_var_map (tree_dump_file, map);
! /* Coalesce partitions of a root variable wherever possible. */
! coalesce_tpa_members (rv, graph, map, NULL,
! ((tree_dump_flags & TDF_DETAILS) ? tree_dump_file : NULL));
root_var_delete (rv);
conflict_graph_delete (graph);
--- 1612,1634 ----
coalesce_abnormal_edges (map, graph, rv);
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
! {
! dump_var_map (tree_dump_file, map);
! }
! /* Coalesce partitions. */
! if (flags & SSANORM_USE_COALESCE_LIST)
! coalesce_tpa_members (rv, graph, map, cl,
! ((tree_dump_flags & TDF_DETAILS) ? tree_dump_file
! : NULL));
+
+ if (flags & SSANORM_COALESCE_PARTITIONS)
+ coalesce_tpa_members (rv, graph, map, NULL,
+ ((tree_dump_flags & TDF_DETAILS) ? tree_dump_file
+ : NULL));
+ if (cl)
+ delete_coalesce_list (cl);
root_var_delete (rv);
conflict_graph_delete (graph);
*************** assign_vars (var_map map)
*** 1608,1625 ****
if (t == var || TREE_CODE (t) != SSA_NAME)
continue;
-
- rep = var_to_partition (map, t);
if (!ann->out_of_ssa_tag)
{
change_partition_var (map, var, rep);
continue;
}
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
! print_exprs (tree_dump_file, "Overlap : '", t, "' conflicts with '",
! var, "");
var = create_temp (t);
change_partition_var (map, var, rep);
--- 1686,1705 ----
if (t == var || TREE_CODE (t) != SSA_NAME)
continue;
+ rep = var_to_partition (map, t);
+
if (!ann->out_of_ssa_tag)
{
+ if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
+ print_exprs (tree_dump_file, "", t, " --> ", var, "\n");
change_partition_var (map, var, rep);
continue;
}
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
! print_exprs (tree_dump_file, "", t, " not coalesced with ", var,
! "");
var = create_temp (t);
change_partition_var (map, var, rep);
*************** assign_vars (var_map map)
*** 1627,1633 ****
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
{
! fprintf (tree_dump_file, "' New temp: '");
print_generic_expr (tree_dump_file, var, TDF_SLIM);
fprintf (tree_dump_file, "'\n");
}
--- 1707,1713 ----
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
{
! fprintf (tree_dump_file, " --> New temp: '");
print_generic_expr (tree_dump_file, var, TDF_SLIM);
fprintf (tree_dump_file, "'\n");
}
*************** remove_ssa_form (FILE *dump, var_map map
*** 2507,2521 ****
liveinfo = coalesce_ssa_name (map, flags);
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
{
fprintf (tree_dump_file, "After Coalescing:\n");
dump_var_map (tree_dump_file, map);
}
! /* Make sure even single occurrence variables are in the list now. */
! if ((flags & SSANORM_COMBINE_TEMPS) == 0)
! compact_var_map (map, VARMAP_NORMAL);
/* Assign real variables to the partitions now. */
assign_vars (map);
--- 2587,2608 ----
liveinfo = coalesce_ssa_name (map, flags);
+ /* Make sure even single occurrence variables are in the list now. */
+ if ((flags & SSANORM_COMBINE_TEMPS) == 0)
+ compact_var_map (map, VARMAP_NORMAL);
+
if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
{
fprintf (tree_dump_file, "After Coalescing:\n");
dump_var_map (tree_dump_file, map);
}
! if (flags & SSANORM_PERFORM_TER)
! {
! values = find_replaceable_exprs (map);
! if (values && tree_dump_file && (tree_dump_flags & TDF_DETAILS))
! dump_replaceable_exprs (tree_dump_file, values);
! }
/* Assign real variables to the partitions now. */
assign_vars (map);
*************** remove_ssa_form (FILE *dump, var_map map
*** 2526,2538 ****
dump_var_map (tree_dump_file, map);
}
- if (flags & SSANORM_PERFORM_TER)
- {
- values = find_replaceable_exprs (map);
- if (values && tree_dump_file && (tree_dump_flags & TDF_DETAILS))
- dump_replaceable_exprs (tree_dump_file, values);
- }
-
if ((flags & SSANORM_COMBINE_TEMPS) && liveinfo)
{
coalesce_vars (map, liveinfo);
--- 2613,2618 ----
*************** rewrite_vars_out_of_ssa (bitmap vars)
*** 2662,2671 ****
/* Now that we have all the partitions registered, translate the
appropriate variables out of SSA form. */
if (flag_tree_combine_temps)
! ssa_flags = SSANORM_COMBINE_TEMPS;
! else
! ssa_flags = 0;
remove_ssa_form (tree_dump_file, map, ssa_flags);
/* And finally, reset the out_of_ssa flag for each of the vars
--- 2742,2750 ----
/* Now that we have all the partitions registered, translate the
appropriate variables out of SSA form. */
+ ssa_flags = SSANORM_COALESCE_PARTITIONS;
if (flag_tree_combine_temps)
! ssa_flags |= SSANORM_COMBINE_TEMPS;
remove_ssa_form (tree_dump_file, map, ssa_flags);
/* And finally, reset the out_of_ssa flag for each of the vars
*************** rewrite_out_of_ssa (void)
*** 2688,2694 ****
{
var_map map;
int var_flags = 0;
! int ssa_flags = SSANORM_REMOVE_ALL_PHIS;
eliminate_virtual_phis ();
--- 2767,2774 ----
{
var_map map;
int var_flags = 0;
! int ssa_flags = (SSANORM_REMOVE_ALL_PHIS | SSANORM_USE_COALESCE_LIST
! | SSANORM_COALESCE_PARTITIONS);
eliminate_virtual_phis ();