aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-live.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-live.c')
-rw-r--r--gcc/tree-ssa-live.c1375
1 files changed, 233 insertions, 1142 deletions
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 277e276..2049e43 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -24,44 +24,107 @@ Boston, MA 02110-1301, USA. */
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "flags.h"
-#include "basic-block.h"
-#include "function.h"
#include "diagnostic.h"
#include "bitmap.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
-#include "tree-inline.h"
-#include "varray.h"
-#include "timevar.h"
-#include "hashtab.h"
#include "tree-dump.h"
#include "tree-ssa-live.h"
#include "toplev.h"
-#include "vecprim.h"
-
-static void live_worklist (tree_live_info_p);
-static tree_live_info_p new_tree_live_info (var_map);
-static inline void set_if_valid (var_map, bitmap, tree);
-static inline void add_conflicts_if_valid (tpa_p, conflict_graph,
- var_map, bitmap, tree);
-static partition_pair_p find_partition_pair (coalesce_list_p, int, int, bool);
+
#ifdef ENABLE_CHECKING
static void verify_live_on_entry (tree_live_info_p);
#endif
-/* This is where the mapping from SSA version number to real storage variable
- is tracked.
- All SSA versions of the same variable may not ultimately be mapped back to
- the same real variable. In that instance, we need to detect the live
- range overlap, and give one of the variable new storage. The vector
- 'partition_to_var' tracks which partition maps to which variable.
+/* VARMAP maintains a mapping from SSA version number to real variables.
+
+ All SSA_NAMES are divided into partitions. Initially each ssa_name is the
+ only member of it's own partition. Coalescing will attempt to group any
+ ssa_names which occur in a copy or in a PHI node into the same partition.
+
+ At the end of out-of-ssa, each partition becomes a "real" variable and is
+ rewritten as a compiler variable.
+
+ The var_map datat structure is used to manage these partitions. It allows
+ partitions to be combined, and determines which partition belongs to what
+ ssa_name or variable, and vice versa. */
+
+
+/* This routine will initialize the basevar fields of MAP. */
+
+static void
+var_map_base_init (var_map map)
+{
+ int x, num_part, num;
+ tree var;
+ var_ann_t ann;
+
+ num = 0;
+ num_part = num_var_partitions (map);
+
+ /* If a base table already exists, clear it, otherwise create it. */
+ if (map->partition_to_base_index != NULL)
+ {
+ free (map->partition_to_base_index);
+ VEC_truncate (tree, map->basevars, 0);
+ }
+ else
+ map->basevars = VEC_alloc (tree, heap, MAX (40, (num_part / 10)));
+
+ map->partition_to_base_index = (int *) xmalloc (sizeof (int) * num_part);
+
+ /* Build the base variable list, and point partitions at their bases. */
+ for (x = 0; x < num_part; x++)
+ {
+ var = partition_to_var (map, x);
+ if (TREE_CODE (var) == SSA_NAME)
+ var = SSA_NAME_VAR (var);
+ ann = var_ann (var);
+ /* If base variable hasn't been seen, set it up. */
+ if (!ann->base_var_processed)
+ {
+ ann->base_var_processed = 1;
+ VAR_ANN_BASE_INDEX (ann) = num++;
+ VEC_safe_push (tree, heap, map->basevars, var);
+ }
+ map->partition_to_base_index[x] = VAR_ANN_BASE_INDEX (ann);
+ }
- Given a VAR, it is sometimes desirable to know which partition that VAR
- represents. There is an additional field in the variable annotation to
- track that information. */
+ map->num_basevars = num;
+ /* Now clear the processed bit. */
+ for (x = 0; x < num; x++)
+ {
+ var = VEC_index (tree, map->basevars, x);
+ var_ann (var)->base_var_processed = 0;
+ }
+
+#ifdef ENABLE_CHECKING
+ for (x = 0; x < num_part; x++)
+ {
+ tree var2;
+ var = SSA_NAME_VAR (partition_to_var (map, x));
+ var2 = VEC_index (tree, map->basevars, basevar_index (map, x));
+ gcc_assert (var == var2);
+ }
+#endif
+}
+
+
+/* Remove the base table in MAP. */
+
+static void
+var_map_base_fini (var_map map)
+{
+ /* Free the basevar info if it is present. */
+ if (map->partition_to_base_index != NULL)
+ {
+ VEC_free (tree, heap, map->basevars);
+ free (map->partition_to_base_index);
+ map->partition_to_base_index = NULL;
+ map->num_basevars = 0;
+ }
+}
/* Create a variable partition map of SIZE, initialize and return it. */
var_map
@@ -75,10 +138,13 @@ init_var_map (int size)
= (tree *)xmalloc (size * sizeof (tree));
memset (map->partition_to_var, 0, size * sizeof (tree));
- map->partition_to_compact = NULL;
- map->compact_to_partition = NULL;
+ map->partition_to_view = NULL;
+ map->view_to_partition = NULL;
map->num_partitions = size;
map->partition_size = size;
+ map->num_basevars = 0;
+ map->partition_to_base_index = NULL;
+ map->basevars = NULL;
return map;
}
@@ -88,12 +154,13 @@ init_var_map (int size)
void
delete_var_map (var_map map)
{
+ var_map_base_fini (map);
free (map->partition_to_var);
partition_delete (map->var_partition);
- if (map->partition_to_compact)
- free (map->partition_to_compact);
- if (map->compact_to_partition)
- free (map->compact_to_partition);
+ if (map->partition_to_view)
+ free (map->partition_to_view);
+ if (map->view_to_partition)
+ free (map->view_to_partition);
free (map);
}
@@ -109,17 +176,17 @@ var_union (var_map map, tree var1, tree var2)
tree root_var = NULL_TREE;
tree other_var = NULL_TREE;
- /* This is independent of partition_to_compact. If partition_to_compact is
+ /* This is independent of partition_to_view. If partition_to_view is
on, then whichever one of these partitions is absorbed will never have a
- dereference into the partition_to_compact array any more. */
+ dereference into the partition_to_view array any more. */
if (TREE_CODE (var1) == SSA_NAME)
p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1));
else
{
p1 = var_to_partition (map, var1);
- if (map->compact_to_partition)
- p1 = map->compact_to_partition[p1];
+ if (map->view_to_partition)
+ p1 = map->view_to_partition[p1];
root_var = var1;
}
@@ -128,8 +195,8 @@ var_union (var_map map, tree var1, tree var2)
else
{
p2 = var_to_partition (map, var2);
- if (map->compact_to_partition)
- p2 = map->compact_to_partition[p2];
+ if (map->view_to_partition)
+ p2 = map->view_to_partition[p2];
/* If there is no root_var set, or it's not a user variable, set the
root_var to this one. */
@@ -150,8 +217,8 @@ var_union (var_map map, tree var1, tree var2)
else
p3 = partition_union (map->var_partition, p1, p2);
- if (map->partition_to_compact)
- p3 = map->partition_to_compact[p3];
+ if (map->partition_to_view)
+ p3 = map->partition_to_view[p3];
if (root_var)
change_partition_var (map, root_var, p3);
@@ -161,12 +228,12 @@ var_union (var_map map, tree var1, tree var2)
return p3;
}
-
+
/* Compress the partition numbers in MAP such that they fall in the range
0..(num_partitions-1) instead of wherever they turned out during
the partitioning exercise. This removes any references to unused
partitions, thereby allowing bitmaps and other vectors to be much
- denser. Compression type is controlled by FLAGS.
+ denser.
This is implemented such that compaction doesn't affect partitioning.
Ie., once partitions are created and possibly merged, running one
@@ -179,96 +246,140 @@ var_union (var_map map, tree var1, tree var2)
definitions, and then 'recompact' later to include all the single
definitions for assignment to program variables. */
-void
-compact_var_map (var_map map, int flags)
+
+/* Set MAP back to the initial state of having no partition view. Return a
+ bitmap which has a bit set for each partition number which is in use in the
+ varmap. */
+
+static bitmap
+partition_view_init (var_map map)
{
- sbitmap used;
- int tmp, root, root_i;
- unsigned int x, limit, count;
- tree var;
- root_var_p rv = NULL;
+ bitmap used;
+ int tmp;
+ unsigned int x;
- limit = map->partition_size;
- used = sbitmap_alloc (limit);
- sbitmap_zero (used);
+ used = BITMAP_ALLOC (NULL);
- /* Already compressed? Abandon the old one. */
- if (map->partition_to_compact)
+ /* Already in a view? Abandon the old one. */
+ if (map->partition_to_view)
{
- free (map->partition_to_compact);
- map->partition_to_compact = NULL;
+ free (map->partition_to_view);
+ map->partition_to_view = NULL;
}
- if (map->compact_to_partition)
+ if (map->view_to_partition)
{
- free (map->compact_to_partition);
- map->compact_to_partition = NULL;
+ free (map->view_to_partition);
+ map->view_to_partition = NULL;
}
- map->num_partitions = map->partition_size;
-
- if (flags & VARMAP_NO_SINGLE_DEFS)
- rv = root_var_init (map);
-
- map->partition_to_compact = (int *)xmalloc (limit * sizeof (int));
- memset (map->partition_to_compact, 0xff, (limit * sizeof (int)));
-
/* Find out which partitions are actually referenced. */
- count = 0;
- for (x = 0; x < limit; x++)
+ for (x = 0; x < map->partition_size; x++)
{
tmp = partition_find (map->var_partition, x);
- if (!TEST_BIT (used, tmp) && map->partition_to_var[tmp] != NULL_TREE)
- {
- /* It is referenced, check to see if there is more than one version
- in the root_var table, if one is available. */
- if (rv)
- {
- root = root_var_find (rv, tmp);
- root_i = root_var_first_partition (rv, root);
- /* If there is only one, don't include this in the compaction. */
- if (root_var_next_partition (rv, root_i) == ROOT_VAR_NONE)
- continue;
- }
- SET_BIT (used, tmp);
- count++;
- }
+ if (map->partition_to_var[tmp] != NULL_TREE && !bitmap_bit_p (used, tmp))
+ bitmap_set_bit (used, tmp);
}
- /* Build a compacted partitioning. */
- if (count != limit)
+ map->num_partitions = map->partition_size;
+ return used;
+}
+
+
+/* This routine will finalize the view data for MAP based on the partitions
+ set in SELECTED. This is either the same bitmap returned from
+ partition_view_init, or a trimmed down version if some of those partitions
+ were not desired in this view. SELECTED is freed before returning. */
+
+static void
+partition_view_fini (var_map map, bitmap selected)
+{
+ bitmap_iterator bi;
+ unsigned count, i, x, limit;
+ tree var;
+
+ gcc_assert (selected);
+
+ count = bitmap_count_bits (selected);
+ limit = map->partition_size;
+
+ /* If its a one-to-one ratio, we don't need any view compaction. */
+ if (count < limit)
{
- sbitmap_iterator sbi;
+ map->partition_to_view = (int *)xmalloc (limit * sizeof (int));
+ memset (map->partition_to_view, 0xff, (limit * sizeof (int)));
+ map->view_to_partition = (int *)xmalloc (count * sizeof (int));
- map->compact_to_partition = (int *)xmalloc (count * sizeof (int));
- count = 0;
- /* SSA renaming begins at 1, so skip 0 when compacting. */
- EXECUTE_IF_SET_IN_SBITMAP (used, 1, x, sbi)
+ i = 0;
+ /* Give each selected partition an index. */
+ EXECUTE_IF_SET_IN_BITMAP (selected, 0, x, bi)
{
- map->partition_to_compact[x] = count;
- map->compact_to_partition[count] = x;
+ map->partition_to_view[x] = i;
+ map->view_to_partition[i] = x;
var = map->partition_to_var[x];
+ /* If any one of the members of a partition is not an SSA_NAME, make
+ sure it is the representative. */
if (TREE_CODE (var) != SSA_NAME)
- change_partition_var (map, var, count);
- count++;
+ change_partition_var (map, var, i);
+ i++;
}
+ gcc_assert (i == count);
+ map->num_partitions = i;
}
+
+ BITMAP_FREE (selected);
+}
+
+
+/* Create a partition view which includes all the used partitions in MAP. If
+ WANT_BASES is true, create the base variable map as well. */
+
+extern void
+partition_view_normal (var_map map, bool want_bases)
+{
+ bitmap used;
+
+ used = partition_view_init (map);
+ partition_view_fini (map, used);
+
+ if (want_bases)
+ var_map_base_init (map);
else
+ var_map_base_fini (map);
+}
+
+
+/* Create a partition view in MAP which includes just partitions which occur in
+ the bitmap ONLY. If WANT_BASES is true, create the base variable map
+ as well. */
+
+extern void
+partition_view_bitmap (var_map map, bitmap only, bool want_bases)
+{
+ bitmap used;
+ bitmap new_partitions = BITMAP_ALLOC (NULL);
+ unsigned x, p;
+ bitmap_iterator bi;
+
+ used = partition_view_init (map);
+ EXECUTE_IF_SET_IN_BITMAP (only, 0, x, bi)
{
- free (map->partition_to_compact);
- map->partition_to_compact = NULL;
+ p = partition_find (map->var_partition, x);
+ gcc_assert (bitmap_bit_p (used, p));
+ bitmap_set_bit (new_partitions, p);
}
+ partition_view_fini (map, new_partitions);
- map->num_partitions = count;
-
- if (rv)
- root_var_delete (rv);
- sbitmap_free (used);
+ BITMAP_FREE (used);
+ if (want_bases)
+ var_map_base_init (map);
+ else
+ var_map_base_fini (map);
}
/* This function is used to change the representative variable in MAP for VAR's
- partition from an SSA_NAME variable to a regular variable. This allows
- partitions to be mapped back to real variables. */
+ partition to a regular non-ssa variable. This allows partitions to be
+ mapped back to real variables. */
void
change_partition_var (var_map map, tree var, int part)
@@ -280,10 +391,11 @@ change_partition_var (var_map map, tree var, int part)
ann = var_ann (var);
ann->out_of_ssa_tag = 1;
VAR_ANN_PARTITION (ann) = part;
- if (map->compact_to_partition)
- map->partition_to_var[map->compact_to_partition[part]] = var;
+ if (map->view_to_partition)
+ map->partition_to_var[map->view_to_partition[part]] = var;
}
+
static inline void mark_all_vars_used (tree *);
/* Helper function for mark_all_vars_used, called via walk_tree. */
@@ -319,6 +431,7 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees,
return NULL;
}
+
/* Mark all VAR_DECLS under *EXPR_P as used, so that they won't be
eliminated during the tree->rtl conversion process. */
@@ -394,102 +507,6 @@ remove_unused_locals (void)
}
}
-/* This function looks through the program and uses FLAGS to determine what
- SSA versioned variables are given entries in a new partition table. This
- new partition map is returned. */
-
-var_map
-create_ssa_var_map (void)
-{
- block_stmt_iterator bsi;
- basic_block bb;
- tree var;
- tree stmt;
- var_map map;
- ssa_op_iter iter;
-#ifdef ENABLE_CHECKING
- bitmap used_in_real_ops;
- bitmap used_in_virtual_ops;
-#endif
-
- map = init_var_map (num_ssa_names + 1);
-
-#ifdef ENABLE_CHECKING
- used_in_real_ops = BITMAP_ALLOC (NULL);
- used_in_virtual_ops = BITMAP_ALLOC (NULL);
-#endif
-
- FOR_EACH_BB (bb)
- {
- tree phi, arg;
-
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- {
- int i;
- register_ssa_partition (map, PHI_RESULT (phi));
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
- {
- arg = PHI_ARG_DEF (phi, i);
- if (TREE_CODE (arg) == SSA_NAME)
- register_ssa_partition (map, arg);
-
- mark_all_vars_used (&PHI_ARG_DEF_TREE (phi, i));
- }
- }
-
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- stmt = bsi_stmt (bsi);
-
- /* Register USE and DEF operands in each statement. */
- FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, (SSA_OP_DEF|SSA_OP_USE))
- {
- register_ssa_partition (map, var);
-
-#ifdef ENABLE_CHECKING
- bitmap_set_bit (used_in_real_ops, DECL_UID (SSA_NAME_VAR (var)));
-#endif
- }
-
-#ifdef ENABLE_CHECKING
- /* Validate that virtual ops don't get used in funny ways. */
- FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter,
- SSA_OP_VIRTUAL_USES | SSA_OP_VMUSTDEF)
- {
- bitmap_set_bit (used_in_virtual_ops,
- DECL_UID (SSA_NAME_VAR (var)));
- }
-
-#endif /* ENABLE_CHECKING */
-
- mark_all_vars_used (bsi_stmt_ptr (bsi));
- }
- }
-
-#if defined ENABLE_CHECKING
- {
- unsigned i;
- bitmap both = BITMAP_ALLOC (NULL);
- bitmap_and (both, used_in_real_ops, used_in_virtual_ops);
- if (!bitmap_empty_p (both))
- {
- bitmap_iterator bi;
-
- EXECUTE_IF_SET_IN_BITMAP (both, 0, i, bi)
- fprintf (stderr, "Variable %s used in real and virtual operands\n",
- get_name (referenced_var (i)));
- internal_error ("SSA corruption");
- }
-
- BITMAP_FREE (used_in_real_ops);
- BITMAP_FREE (used_in_virtual_ops);
- BITMAP_FREE (both);
- }
-#endif
-
- return map;
-}
-
/* Allocate and return a new live range information object base on MAP. */
@@ -541,7 +558,7 @@ delete_tree_live_info (tree_live_info_p live)
}
-/* Visit basic block BB, and propogate any required live on entry bits from
+/* Visit basic block BB and propogate any required live on entry bits from
LIVE into the predecessors. VISITED is the bitmap of visited blocks.
TMP is a temporary work bitmap which is passed in to avoid reallocting
it each time. */
@@ -565,8 +582,8 @@ loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited,
pred_bb = e->src;
if (pred_bb == ENTRY_BLOCK_PTR)
continue;
- /* tmp is vars live-=on-entry from BB that aren't defined in the
- pred. block. This should be the live on entry vars to pred.
+ /* TMP is variables live-on-entry from BB that aren't defined in the
+ predecessor block. This should be the live on entry vars to pred.
Note that liveout is the DEFs in a block while live on entry is
being calculated. */
bitmap_and_compl (tmp, loe, live->liveout[pred_bb->index]);
@@ -636,7 +653,7 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
if (stmt)
{
def_bb = bb_for_stmt (stmt);
- /* Mark defs in liveout bitmap for now. */
+ /* Mark defs in liveout bitmap temporarily. */
if (def_bb)
bitmap_set_bit (live->liveout[def_bb->index], p);
}
@@ -698,7 +715,7 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
edge e;
edge_iterator ei;
- /* live on entry calculations used the liveouit vector for defs. */
+ /* live on entry calculations used liveout vectors for defs, clear them. */
FOR_EACH_BB (bb)
bitmap_clear (liveinfo->liveout[bb->index]);
@@ -720,7 +737,7 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
bitmap_set_bit (liveinfo->liveout[e->src->index], p);
}
- /* add each successors live on entry to this bock live on exit. */
+ /* Add each successors live on entry to this bock live on exit. */
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->dest != EXIT_BLOCK_PTR)
bitmap_ior_into (liveinfo->liveout[bb->index],
@@ -728,6 +745,7 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
}
}
+
/* Given partition map MAP, calculate all the live on entry bitmaps for
each partition. Return a new live info object. */
@@ -757,936 +775,6 @@ calculate_live_ranges (var_map map)
}
-/* Initialize a tree_partition_associator object using MAP. */
-
-static tpa_p
-tpa_init (var_map map)
-{
- tpa_p tpa;
- int num_partitions = num_var_partitions (map);
- int x;
-
- if (num_partitions == 0)
- return NULL;
-
- tpa = (tpa_p) xmalloc (sizeof (struct tree_partition_associator_d));
- tpa->num_trees = 0;
- tpa->uncompressed_num = -1;
- tpa->map = map;
- tpa->next_partition = (int *)xmalloc (num_partitions * sizeof (int));
- memset (tpa->next_partition, TPA_NONE, num_partitions * sizeof (int));
-
- tpa->partition_to_tree_map = (int *)xmalloc (num_partitions * sizeof (int));
- memset (tpa->partition_to_tree_map, TPA_NONE, num_partitions * sizeof (int));
-
- x = MAX (40, (num_partitions / 20));
- tpa->trees = VEC_alloc (tree, heap, x);
- tpa->first_partition = VEC_alloc (int, heap, x);
-
- return tpa;
-
-}
-
-
-/* Remove PARTITION_INDEX from TREE_INDEX's list in the tpa structure TPA. */
-
-void
-tpa_remove_partition (tpa_p tpa, int tree_index, int partition_index)
-{
- int i;
-
- i = tpa_first_partition (tpa, tree_index);
- if (i == partition_index)
- {
- VEC_replace (int, tpa->first_partition, tree_index,
- tpa->next_partition[i]);
- }
- else
- {
- for ( ; i != TPA_NONE; i = tpa_next_partition (tpa, i))
- {
- if (tpa->next_partition[i] == partition_index)
- {
- tpa->next_partition[i] = tpa->next_partition[partition_index];
- break;
- }
- }
- }
-}
-
-
-/* Free the memory used by tree_partition_associator object TPA. */
-
-void
-tpa_delete (tpa_p tpa)
-{
- if (!tpa)
- return;
-
- VEC_free (tree, heap, tpa->trees);
- VEC_free (int, heap, tpa->first_partition);
- free (tpa->partition_to_tree_map);
- free (tpa->next_partition);
- free (tpa);
-}
-
-
-/* This function will remove any tree entries from TPA which have only a single
- element. This will help keep the size of the conflict graph down. The
- function returns the number of remaining tree lists. */
-
-int
-tpa_compact (tpa_p tpa)
-{
- int last, x, y, first, swap_i;
- tree swap_t;
-
- /* Find the last list which has more than 1 partition. */
- for (last = tpa->num_trees - 1; last > 0; last--)
- {
- first = tpa_first_partition (tpa, last);
- if (tpa_next_partition (tpa, first) != NO_PARTITION)
- break;
- }
-
- x = 0;
- while (x < last)
- {
- first = tpa_first_partition (tpa, x);
-
- /* If there is not more than one partition, swap with the current end
- of the tree list. */
- if (tpa_next_partition (tpa, first) == NO_PARTITION)
- {
- swap_t = VEC_index (tree, tpa->trees, last);
- swap_i = VEC_index (int, tpa->first_partition, last);
-
- /* Update the last entry. Since it is known to only have one
- partition, there is nothing else to update. */
- VEC_replace (tree, tpa->trees, last,
- VEC_index (tree, tpa->trees, x));
- VEC_replace (int, tpa->first_partition, last,
- VEC_index (int, tpa->first_partition, x));
- tpa->partition_to_tree_map[tpa_first_partition (tpa, last)] = last;
-
- /* Since this list is known to have more than one partition, update
- the list owner entries. */
- VEC_replace (tree, tpa->trees, x, swap_t);
- VEC_replace (int, tpa->first_partition, x, swap_i);
- for (y = tpa_first_partition (tpa, x);
- y != NO_PARTITION;
- y = tpa_next_partition (tpa, y))
- tpa->partition_to_tree_map[y] = x;
-
- /* Ensure last is a list with more than one partition. */
- last--;
- for (; last > x; last--)
- {
- first = tpa_first_partition (tpa, last);
- if (tpa_next_partition (tpa, first) != NO_PARTITION)
- break;
- }
- }
- x++;
- }
-
- first = tpa_first_partition (tpa, x);
- if (tpa_next_partition (tpa, first) != NO_PARTITION)
- x++;
- tpa->uncompressed_num = tpa->num_trees;
- tpa->num_trees = x;
- return last;
-}
-
-
-/* Initialize a root_var object with SSA partitions from MAP which are based
- on each root variable. */
-
-root_var_p
-root_var_init (var_map map)
-{
- root_var_p rv;
- int num_partitions = num_var_partitions (map);
- int x, p;
- tree t;
- var_ann_t ann;
- sbitmap seen;
-
- rv = tpa_init (map);
- if (!rv)
- return NULL;
-
- seen = sbitmap_alloc (num_partitions);
- sbitmap_zero (seen);
-
- /* Start at the end and work towards the front. This will provide a list
- that is ordered from smallest to largest. */
- for (x = num_partitions - 1; x >= 0; x--)
- {
- t = partition_to_var (map, x);
-
- /* The var map may not be compacted yet, so check for NULL. */
- if (!t)
- continue;
-
- p = var_to_partition (map, t);
-
- gcc_assert (p != NO_PARTITION);
-
- /* Make sure we only put coalesced partitions into the list once. */
- if (TEST_BIT (seen, p))
- continue;
- SET_BIT (seen, p);
- if (TREE_CODE (t) == SSA_NAME)
- t = SSA_NAME_VAR (t);
- ann = var_ann (t);
- if (ann->root_var_processed)
- {
- rv->next_partition[p] = VEC_index (int, rv->first_partition,
- VAR_ANN_ROOT_INDEX (ann));
- VEC_replace (int, rv->first_partition, VAR_ANN_ROOT_INDEX (ann), p);
- }
- else
- {
- ann->root_var_processed = 1;
- VAR_ANN_ROOT_INDEX (ann) = rv->num_trees++;
- VEC_safe_push (tree, heap, rv->trees, t);
- VEC_safe_push (int, heap, rv->first_partition, p);
- }
- rv->partition_to_tree_map[p] = VAR_ANN_ROOT_INDEX (ann);
- }
-
- /* Reset the out_of_ssa_tag flag on each variable for later use. */
- for (x = 0; x < rv->num_trees; x++)
- {
- t = VEC_index (tree, rv->trees, x);
- var_ann (t)->root_var_processed = 0;
- }
-
- sbitmap_free (seen);
- return rv;
-}
-
-
-/* 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 equivalent 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;
-
- 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->num_sorted = 0;
- return list;
-}
-
-
-/* Delete coalesce list CL. */
-
-void
-delete_coalesce_list (coalesce_list_p cl)
-{
- htab_delete (cl->list);
- if (cl->sorted)
- free (cl->sorted);
- gcc_assert (cl->num_sorted == 0);
- free (cl);
-}
-
-
-/* Find a matching coalesce pair object in CL for partitions P1 and P2. If
- one isn't found, return NULL if CREATE is false, otherwise create a new
- coalesce pair object and return it. */
-
-static partition_pair_p
-find_partition_pair (coalesce_list_p cl, int p1, int p2, bool create)
-{
- struct partition_pair p, *pair;
- void **slot;
- unsigned int hash;
-
- /* normalize so that p1 is the smaller value. */
- if (p2 < p1)
- {
- p.first_partition = p2;
- p.second_partition = p1;
- }
- else
- {
- 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 pair;
-}
-
-/* Return cost of execution of copy instruction with FREQUENCY
- possibly on CRITICAL edge and in HOT basic block. */
-int
-coalesce_cost (int frequency, bool hot, bool critical)
-{
- /* Base costs on BB frequencies bounded by 1. */
- int cost = frequency;
-
- if (!cost)
- cost = 1;
- if (optimize_size || hot)
- cost = 1;
- /* Inserting copy on critical edge costs more
- than inserting it elsewhere. */
- if (critical)
- cost *= 2;
- return cost;
-}
-
-/* Add a potential coalesce between P1 and P2 in CL with a cost of VALUE. */
-
-void
-add_coalesce (coalesce_list_p cl, int p1, int p2,
- int value)
-{
- partition_pair_p node;
-
- gcc_assert (cl->add_mode);
-
- if (p1 == p2)
- return;
-
- node = find_partition_pair (cl, p1, p2, true);
-
- node->cost += value;
-}
-
-
-/* Comparison function to allow qsort to sort P1 and P2 in Ascending order. */
-
-static
-int compare_pairs (const void *p1, const void *p2)
-{
- 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. */
-
-void
-sort_coalesce_list (coalesce_list_p cl)
-{
- unsigned x, num;
- partition_pair_p p;
- partition_pair_iterator ppi;
-
- gcc_assert (cl->add_mode);
-
- cl->add_mode = false;
-
- /* 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)
- qsort (cl->sorted, num, sizeof (partition_pair_p), compare_pairs);
-}
-
-
-/* Retrieve the best remaining pair to coalesce from CL. Returns the 2
- partitions via P1 and P2. Their calculated cost is returned by the function.
- NO_BEST_COALESCE is returned if the coalesce list is empty. */
-
-static int
-pop_best_coalesce (coalesce_list_p cl, int *p1, int *p2)
-{
- partition_pair_p node;
- int ret;
-
- gcc_assert (!cl->add_mode);
-
- if (cl->num_sorted == 0)
- return NO_BEST_COALESCE;
-
- node = cl->sorted[--(cl->num_sorted)];
-
- *p1 = node->first_partition;
- *p2 = node->second_partition;
- ret = node->cost;
- free (node);
-
- return ret;
-}
-
-
-/* If variable VAR is in a partition in MAP, add a conflict in GRAPH between
- VAR and any other live partitions in VEC which are associated via TPA.
- Reset the live bit in VEC. */
-
-static inline void
-add_conflicts_if_valid (tpa_p tpa, conflict_graph graph,
- var_map map, bitmap vec, tree var)
-{
- int p, y, first;
- p = var_to_partition (map, var);
- if (p != NO_PARTITION)
- {
- bitmap_clear_bit (vec, p);
- first = tpa_find_tree (tpa, p);
- /* If find returns nothing, this object isn't interesting. */
- if (first == TPA_NONE)
- return;
- /* Only add interferences between objects in the same list. */
- for (y = tpa_first_partition (tpa, first);
- y != TPA_NONE;
- y = tpa_next_partition (tpa, y))
- {
- if (bitmap_bit_p (vec, y))
- conflict_graph_add (graph, p, y);
- }
- }
-}
-
-
-/* If VAR is in a partition of MAP, set the bit for that partition in VEC. */
-
-static inline void
-set_if_valid (var_map map, bitmap vec, tree var)
-{
- int p = var_to_partition (map, var);
- if (p != NO_PARTITION)
- bitmap_set_bit (vec, p);
-}
-
-/* Return a conflict graph for the information contained in LIVE_INFO. Only
- conflicts between items in the same TPA list are added. If optional
- coalesce list CL is passed in, any copies encountered are added. */
-
-conflict_graph
-build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
- coalesce_list_p cl)
-{
- conflict_graph graph;
- var_map map;
- bitmap live;
- unsigned x, y, i;
- basic_block bb;
- int *partition_link, *tpa_nodes;
- VEC(int,heap) *tpa_to_clear;
- unsigned l;
- ssa_op_iter iter;
- bitmap_iterator bi;
-
- map = live_var_map (liveinfo);
- graph = conflict_graph_new (num_var_partitions (map));
-
- if (tpa_num_trees (tpa) == 0)
- return graph;
-
- live = BITMAP_ALLOC (NULL);
-
- partition_link = XCNEWVEC (int, num_var_partitions (map) + 1);
- tpa_nodes = XCNEWVEC (int, tpa_num_trees (tpa));
- tpa_to_clear = VEC_alloc (int, heap, 50);
-
- FOR_EACH_BB (bb)
- {
- block_stmt_iterator bsi;
- tree phi;
- int idx;
-
- /* Start with live on exit temporaries. */
- bitmap_copy (live, live_on_exit (liveinfo, bb));
-
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
- {
- bool is_a_copy = false;
- tree stmt = bsi_stmt (bsi);
-
- /* A copy between 2 partitions does not introduce an interference
- by itself. If they did, you would never be able to coalesce
- two things which are copied. If the two variables really do
- conflict, they will conflict elsewhere in the program.
-
- This is handled specially here since we may also be interested
- in copies between real variables and SSA_NAME variables. We may
- be interested in trying to coalesce SSA_NAME variables with
- root variables in some cases. */
-
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- {
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- int p1, p2;
- int bit;
-
- if (DECL_P (lhs) || TREE_CODE (lhs) == SSA_NAME)
- p1 = var_to_partition (map, lhs);
- else
- p1 = NO_PARTITION;
-
- if (DECL_P (rhs) || TREE_CODE (rhs) == SSA_NAME)
- p2 = var_to_partition (map, rhs);
- else
- p2 = NO_PARTITION;
-
- if (p1 != NO_PARTITION && p2 != NO_PARTITION)
- {
- is_a_copy = true;
- bit = bitmap_bit_p (live, p2);
- /* If the RHS is live, make it not live while we add
- the conflicts, then make it live again. */
- if (bit)
- bitmap_clear_bit (live, p2);
- add_conflicts_if_valid (tpa, graph, map, live, lhs);
- if (bit)
- bitmap_set_bit (live, p2);
- if (cl)
- add_coalesce (cl, p1, p2,
- coalesce_cost (bb->frequency,
- maybe_hot_bb_p (bb), false));
- set_if_valid (map, live, rhs);
- }
- }
-
- if (!is_a_copy)
- {
- tree var;
- FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
- {
- add_conflicts_if_valid (tpa, graph, map, live, var);
- }
-
- FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
- {
- set_if_valid (map, live, var);
- }
- }
- }
-
- /* If result of a PHI is unused, then the loops over the statements
- will not record any conflicts. However, since the PHI node is
- going to be translated out of SSA form we must record a conflict
- between the result of the PHI and any variables with are live.
- Otherwise the out-of-ssa translation may create incorrect code. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- {
- tree result = PHI_RESULT (phi);
- int p = var_to_partition (map, result);
-
- if (p != NO_PARTITION && ! bitmap_bit_p (live, p))
- add_conflicts_if_valid (tpa, graph, map, live, result);
- }
-
- /* Anything which is still live at this point interferes.
- In order to implement this efficiently, only conflicts between
- partitions which have the same TPA root need be added.
- TPA roots which have been seen are tracked in 'tpa_nodes'. A nonzero
- entry points to an index into 'partition_link', which then indexes
- into itself forming a linked list of partitions sharing a tpa root
- which have been seen as live up to this point. Since partitions start
- at index zero, all entries in partition_link are (partition + 1).
-
- Conflicts are added between the current partition and any already seen.
- tpa_clear contains all the tpa_roots processed, and these are the only
- entries which need to be zero'd out for a clean restart. */
-
- EXECUTE_IF_SET_IN_BITMAP (live, 0, x, bi)
- {
- i = tpa_find_tree (tpa, x);
- if (i != (unsigned)TPA_NONE)
- {
- int start = tpa_nodes[i];
- /* If start is 0, a new root reference list is being started.
- Register it to be cleared. */
- if (!start)
- VEC_safe_push (int, heap, tpa_to_clear, i);
-
- /* Add interferences to other tpa members seen. */
- for (y = start; y != 0; y = partition_link[y])
- conflict_graph_add (graph, x, y - 1);
- tpa_nodes[i] = x + 1;
- partition_link[x + 1] = start;
- }
- }
-
- /* Now clear the used tpa root references. */
- for (l = 0; VEC_iterate (int, tpa_to_clear, l, idx); l++)
- tpa_nodes[idx] = 0;
- VEC_truncate (int, tpa_to_clear, 0);
- }
-
- free (tpa_nodes);
- free (partition_link);
- VEC_free (int, heap, tpa_to_clear);
- BITMAP_FREE (live);
- return graph;
-}
-
-
-/* This routine will attempt to coalesce the elements in TPA subject to the
- conflicts found in GRAPH. If optional coalesce_list CL is provided,
- only coalesces specified within the coalesce list are attempted. Otherwise
- an attempt is made to coalesce as many partitions within each TPA grouping
- as possible. If DEBUG 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);
- }
-
- w = tpa_find_tree (tpa, x);
- z = tpa_find_tree (tpa, y);
- if (w != z || w == TPA_NONE || z == TPA_NONE)
- {
- if (debug)
- {
- if (w != z)
- fprintf (debug, ": Fail, Non-matching TPA's\n");
- if (w == 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 cannot 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;
- }
-
- /* The root variable of the partition may be changed
- now. */
- var = partition_to_var (map, p1);
-
- if (debug)
- fprintf (debug, ": Success -> %d\n", v);
- }
- else
- if (debug)
- fprintf (debug, ": Fail, Conflict\n");
- }
- }
- }
-}
-
-
-/* Send debug info for coalesce list CL to file F. */
-
-void
-dump_coalesce_list (FILE *f, coalesce_list_p cl)
-{
- partition_pair_p node;
- partition_pair_iterator ppi;
- int x;
- tree var;
-
- if (cl->add_mode)
- {
- fprintf (f, "Coalesce List:\n");
- FOR_EACH_PARTITION_PAIR (node, ppi, cl)
- {
- 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 (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, " <-> ");
- var = partition_to_var (cl->map, node->second_partition);
- print_generic_expr (f, var, TDF_SLIM);
- fprintf (f, "\n");
- }
- }
-}
-
-
-/* Output tree_partition_associator object TPA to file F.. */
-
-void
-tpa_dump (FILE *f, tpa_p tpa)
-{
- int x, i;
-
- if (!tpa)
- return;
-
- for (x = 0; x < tpa_num_trees (tpa); x++)
- {
- print_generic_expr (f, tpa_tree (tpa, x), TDF_SLIM);
- fprintf (f, " : (");
- for (i = tpa_first_partition (tpa, x);
- 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
- if (tpa_find_tree (tpa, i) != x)
- fprintf (f, "**find tree incorrectly set** ");
-#endif
-
- }
- fprintf (f, ")\n");
- }
- fflush (f);
-}
-
-
/* Output partition map MAP to file F. */
void
@@ -1700,8 +788,8 @@ dump_var_map (FILE *f, var_map map)
for (x = 0; x < map->num_partitions; x++)
{
- if (map->compact_to_partition != NULL)
- p = map->compact_to_partition[x];
+ if (map->view_to_partition != NULL)
+ p = map->view_to_partition[x];
else
p = x;
@@ -1712,8 +800,8 @@ dump_var_map (FILE *f, var_map map)
for (y = 1; y < num_ssa_names; y++)
{
p = partition_find (map->var_partition, y);
- if (map->partition_to_compact)
- p = map->partition_to_compact[p];
+ if (map->partition_to_view)
+ p = map->partition_to_view[p];
if (p == (int)x)
{
if (t++ == 0)
@@ -1771,7 +859,10 @@ dump_live_info (FILE *f, tree_live_info_p live, int flag)
}
}
+
#ifdef ENABLE_CHECKING
+/* Verify that SSA_VAR is a non-virtual SSA_NAME. */
+
void
register_ssa_partition_check (tree ssa_var)
{
@@ -1787,6 +878,7 @@ register_ssa_partition_check (tree ssa_var)
/* Verify that the info in LIVE matches the current cfg. */
+
static void
verify_live_on_entry (tree_live_info_p live)
{
@@ -1802,7 +894,6 @@ verify_live_on_entry (tree_live_info_p live)
/* Check for live on entry partitions and report those with a DEF in
the program. This will typically mean an optimization has done
something wrong. */
-
bb = ENTRY_BLOCK_PTR;
num = 0;
FOR_EACH_EDGE (e, ei, bb->succs)