Commit 32ace6e2 by Andrew MacLeod Committed by Andrew Macleod

Switch live on entry to a per block basis from per variable.

	* tree-outof-ssa.c (coalesce_ssa_name): Use calculate_live_ranges.
	* tree-ssa-live.c (new_tree_live_info, delete_tree_live_info): Update.
	(add_livein_if_notdef): Delete.
	(loe_visit_block): New.  Propogate live on entry info for a block into
	each predecessor.  If it changes, make sure it is visited again.
	(live_worklist): Visit every block and update the live on entry info 
	for preds.  Iterate over any that changed.
	(set_var_live_on_entry): Populate the live on entry blocks with bits
	based on the immediate uses of a var.
	(calculate_live_on_entry): Remove.
	(calculate_live_on_exit): Calculate live on exit based on the newly
	oriented live on entry bits.
	(calculate_live_ranges): Build live on entry and exit vectors.
	(dump_live_info): Use new orientation of live on entry bitmaps.
	(verify_live_on_entry): New.  Split out verification code from old
	calculate_live_on_entry routine.
	* tree-ssa-live.h (struct tree_live_info_d): Add Working stack.
	(live_entry_blocks): Rename to live_on_entry and return bitmap for a
	basic_block instead of for a partition.
	(live_merge_and_clear): Add asserts.
	(make_live_on_entry): Set partition bit in basic block vector.

From-SVN: r119495
parent b9ca5811
2006-12-04 Andrew MacLeod <amacleod@redhat.com>
* tree-outof-ssa.c (coalesce_ssa_name): Use calculate_live_ranges.
* tree-ssa-live.c (new_tree_live_info, delete_tree_live_info): Update.
(add_livein_if_notdef): Delete.
(loe_visit_block): New. Propogate live on entry info for a block into
each predecessor. If it changes, make sure it is visited again.
(live_worklist): Visit every block and update the live on entry info
for preds. Iterate over any that changed.
(set_var_live_on_entry): Populate the live on entry blocks with bits
based on the immediate uses of a var.
(calculate_live_on_entry): Remove.
(calculate_live_on_exit): Calculate live on exit based on the newly
oriented live on entry bits.
(calculate_live_ranges): Build live on entry and exit vectors.
(dump_live_info): Use new orientation of live on entry bitmaps.
(verify_live_on_entry): New. Split out verification code from old
calculate_live_on_entry routine.
* tree-ssa-live.h (struct tree_live_info_d): Add Working stack.
(live_entry_blocks): Rename to live_on_entry and return bitmap for a
basic_block instead of for a partition.
(live_merge_and_clear): Add asserts.
(make_live_on_entry): Set partition bit in basic block vector.
2006-12-04 Jakub Jelinek <jakub@redhat.com> 2006-12-04 Jakub Jelinek <jakub@redhat.com>
PR libgomp/29947 PR libgomp/29947
......
...@@ -822,8 +822,7 @@ coalesce_ssa_name (var_map map, int flags) ...@@ -822,8 +822,7 @@ coalesce_ssa_name (var_map map, int flags)
if (num_var_partitions (map) <= 1) if (num_var_partitions (map) <= 1)
return NULL; return NULL;
liveinfo = calculate_live_on_entry (map); liveinfo = calculate_live_ranges (map);
calculate_live_on_exit (liveinfo);
rv = root_var_init (map); rv = root_var_init (map);
/* Remove single element variable from the list. */ /* Remove single element variable from the list. */
......
...@@ -40,14 +40,15 @@ Boston, MA 02110-1301, USA. */ ...@@ -40,14 +40,15 @@ Boston, MA 02110-1301, USA. */
#include "toplev.h" #include "toplev.h"
#include "vecprim.h" #include "vecprim.h"
static void live_worklist (tree_live_info_p, int *, int); static void live_worklist (tree_live_info_p);
static tree_live_info_p new_tree_live_info (var_map); static tree_live_info_p new_tree_live_info (var_map);
static inline void set_if_valid (var_map, bitmap, tree); static inline void set_if_valid (var_map, bitmap, tree);
static inline void add_livein_if_notdef (tree_live_info_p, bitmap,
tree, basic_block);
static inline void add_conflicts_if_valid (tpa_p, conflict_graph, static inline void add_conflicts_if_valid (tpa_p, conflict_graph,
var_map, bitmap, tree); var_map, bitmap, tree);
static partition_pair_p find_partition_pair (coalesce_list_p, int, int, bool); 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 /* This is where the mapping from SSA version number to real storage variable
is tracked. is tracked.
...@@ -502,14 +503,18 @@ new_tree_live_info (var_map map) ...@@ -502,14 +503,18 @@ new_tree_live_info (var_map map)
live->map = map; live->map = map;
live->num_blocks = last_basic_block; live->num_blocks = last_basic_block;
live->global = BITMAP_ALLOC (NULL); live->livein = (bitmap *)xmalloc (last_basic_block * sizeof (bitmap));
for (x = 0; x < (unsigned)last_basic_block; x++)
live->livein = (bitmap *)xmalloc (num_var_partitions (map) * sizeof (bitmap));
for (x = 0; x < num_var_partitions (map); x++)
live->livein[x] = BITMAP_ALLOC (NULL); live->livein[x] = BITMAP_ALLOC (NULL);
/* liveout is deferred until it is actually requested. */ live->liveout = (bitmap *)xmalloc (last_basic_block * sizeof (bitmap));
live->liveout = NULL; for (x = 0; x < (unsigned)last_basic_block; x++)
live->liveout[x] = BITMAP_ALLOC (NULL);
live->work_stack = XNEWVEC (int, last_basic_block);
live->stack_top = live->work_stack;
live->global = BITMAP_ALLOC (NULL);
return live; return live;
} }
...@@ -520,270 +525,164 @@ void ...@@ -520,270 +525,164 @@ void
delete_tree_live_info (tree_live_info_p live) delete_tree_live_info (tree_live_info_p live)
{ {
int x; int x;
if (live->liveout)
{ BITMAP_FREE (live->global);
free (live->work_stack);
for (x = live->num_blocks - 1; x >= 0; x--) for (x = live->num_blocks - 1; x >= 0; x--)
BITMAP_FREE (live->liveout[x]); BITMAP_FREE (live->liveout[x]);
free (live->liveout); free (live->liveout);
}
if (live->livein) for (x = live->num_blocks - 1; x >= 0; x--)
{
for (x = num_var_partitions (live->map) - 1; x >= 0; x--)
BITMAP_FREE (live->livein[x]); BITMAP_FREE (live->livein[x]);
free (live->livein); free (live->livein);
}
if (live->global)
BITMAP_FREE (live->global);
free (live); free (live);
} }
/* Using LIVE, fill in all the live-on-entry blocks between the defs and uses /* Visit basic block BB, and propogate any required live on entry bits from
for partition I. STACK is a varray used for temporary memory which is LIVE into the predecessors. VISITED is the bitmap of visited blocks.
passed in rather than being allocated on every call. */ TMP is a temporary work bitmap which is passed in to avoid reallocting
it each time. */
static void static void
live_worklist (tree_live_info_p live, int *stack, int i) loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited,
bitmap tmp)
{ {
unsigned b;
tree var;
basic_block def_bb = NULL;
edge e; edge e;
var_map map = live->map; bool change;
edge_iterator ei; edge_iterator ei;
bitmap_iterator bi; basic_block pred_bb;
int *tos = stack; bitmap loe;
gcc_assert (!TEST_BIT (visited, bb->index));
var = partition_to_var (map, i);
if (SSA_NAME_DEF_STMT (var))
def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (var));
EXECUTE_IF_SET_IN_BITMAP (live->livein[i], 0, b, bi)
{
*tos++ = b;
}
while (tos != stack) SET_BIT (visited, bb->index);
{ loe = live_on_entry (live, bb);
b = *--tos;
FOR_EACH_EDGE (e, ei, BASIC_BLOCK (b)->preds) FOR_EACH_EDGE (e, ei, bb->preds)
if (e->src != ENTRY_BLOCK_PTR)
{ {
/* Its not live on entry to the block its defined in. */ pred_bb = e->src;
if (e->src == def_bb) if (pred_bb == ENTRY_BLOCK_PTR)
continue; continue;
if (!bitmap_bit_p (live->livein[i], e->src->index)) /* 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.
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]);
/* Add these bits to live-on-entry for the pred. if there are any
changes, and pred_bb has been visited already, add it to the
revisit stack. */
change = bitmap_ior_into (live_on_entry (live, pred_bb), tmp);
if (TEST_BIT (visited, pred_bb->index) && change)
{ {
bitmap_set_bit (live->livein[i], e->src->index); RESET_BIT (visited, pred_bb->index);
*tos++ = e->src->index; *(live->stack_top)++ = pred_bb->index;
}
} }
} }
} }
/* If VAR is in a partition of MAP, set the bit for that partition in VEC. */ /* Using LIVE, fill in all the live-on-entry blocks between the defs and uses
of all the vairables. */
static inline void static void
set_if_valid (var_map map, bitmap vec, tree var) live_worklist (tree_live_info_p live)
{ {
int p = var_to_partition (map, var); unsigned b;
if (p != NO_PARTITION) basic_block bb;
bitmap_set_bit (vec, p); sbitmap visited = sbitmap_alloc (last_basic_block + 1);
} bitmap tmp = BITMAP_ALLOC (NULL);
sbitmap_zero (visited);
/* If VAR is in a partition and it isn't defined in DEF_VEC, set the livein and /* Visit all the blocks in reverse order and propogate live on entry values
global bit for it in the LIVE object. BB is the block being processed. */ into the predecessors blocks. */
FOR_EACH_BB_REVERSE (bb)
loe_visit_block (live, bb, visited, tmp);
static inline void /* Process any blocks which require further iteration. */
add_livein_if_notdef (tree_live_info_p live, bitmap def_vec, while (live->stack_top != live->work_stack)
tree var, basic_block bb)
{
int p = var_to_partition (live->map, var);
if (p == NO_PARTITION || bb == ENTRY_BLOCK_PTR)
return;
if (!bitmap_bit_p (def_vec, p))
{ {
bitmap_set_bit (live->livein[p], bb->index); b = *--(live->stack_top);
bitmap_set_bit (live->global, p); loe_visit_block (live, BASIC_BLOCK (b), visited, tmp);
} }
BITMAP_FREE (tmp);
sbitmap_free (visited);
} }
/* Given partition map MAP, calculate all the live on entry bitmaps for /* Calulate the initial live on entry vector for SSA_NAME using immediate_use
each basic block. Return a live info object. */ links. Set the live on entry fields in LIVE. Def's are marked temporarily
in the liveout vector. */
tree_live_info_p static void
calculate_live_on_entry (var_map map) set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
{ {
tree_live_info_p live; int p;
unsigned i; tree stmt;
basic_block bb; use_operand_p use;
bitmap saw_def; basic_block def_bb = NULL;
tree phi, var, stmt; imm_use_iterator imm_iter;
tree op; bool global = false;
edge e;
int *stack;
block_stmt_iterator bsi;
ssa_op_iter iter;
bitmap_iterator bi;
#ifdef ENABLE_CHECKING
int num;
edge_iterator ei;
#endif
saw_def = BITMAP_ALLOC (NULL);
live = new_tree_live_info (map);
FOR_EACH_BB (bb)
{
bitmap_clear (saw_def);
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
for (i = 0; i < (unsigned)PHI_NUM_ARGS (phi); i++)
{
var = PHI_ARG_DEF (phi, i);
if (!phi_ssa_name_p (var))
continue;
stmt = SSA_NAME_DEF_STMT (var);
e = EDGE_PRED (bb, i);
/* Any uses in PHIs which either don't have def's or are not
defined in the block from which the def comes, will be live
on entry to that block. */
if (!stmt || e->src != bb_for_stmt (stmt))
add_livein_if_notdef (live, saw_def, var, e->src);
}
}
/* Don't mark PHI results as defined until all the PHI nodes have p = var_to_partition (live->map, ssa_name);
been processed. If the PHI sequence is: if (p == NO_PARTITION)
a_3 = PHI <a_1, a_2> return;
b_3 = PHI <b_1, a_3>
The a_3 referred to in b_3's PHI node is the one incoming on the
edge, *not* the PHI node just seen. */
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) stmt = SSA_NAME_DEF_STMT (ssa_name);
if (stmt)
{ {
var = PHI_RESULT (phi); def_bb = bb_for_stmt (stmt);
set_if_valid (map, saw_def, var); /* Mark defs in liveout bitmap for now. */
if (def_bb)
bitmap_set_bit (live->liveout[def_bb->index], p);
} }
else
def_bb = ENTRY_BLOCK_PTR;
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) /* Visit each use of SSA_NAME and if it isn't in the same block as the def,
add it to the list of live on entry blocks. */
FOR_EACH_IMM_USE_FAST (use, imm_iter, ssa_name)
{ {
stmt = bsi_stmt (bsi); tree use_stmt = USE_STMT (use);
basic_block add_block = NULL;
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) if (TREE_CODE (use_stmt) == PHI_NODE)
{ {
add_livein_if_notdef (live, saw_def, op, bb); /* Uses in PHI's are considered to be live at exit of the SRC block
} as this is where a copy would be inserted. Check to see if it is
defined in that block, or whether its live on entry. */
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF) int index = PHI_ARG_INDEX_FROM_USE (use);
edge e = PHI_ARG_EDGE (use_stmt, index);
if (e->src != ENTRY_BLOCK_PTR)
{ {
set_if_valid (map, saw_def, op); if (e->src != def_bb)
} add_block = e->src;
} }
} }
else
stack = XNEWVEC (int, last_basic_block);
EXECUTE_IF_SET_IN_BITMAP (live->global, 0, i, bi)
{ {
live_worklist (live, stack, i); /* If its not defined in this block, its live on entry. */
basic_block use_bb = bb_for_stmt (use_stmt);
if (use_bb != def_bb)
add_block = use_bb;
} }
free (stack);
#ifdef ENABLE_CHECKING
/* 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)
{
int entry_block = e->dest->index;
if (e->dest == EXIT_BLOCK_PTR)
continue;
for (i = 0; i < (unsigned)num_var_partitions (map); i++)
{
basic_block tmp;
tree d;
var = partition_to_var (map, i);
stmt = SSA_NAME_DEF_STMT (var);
tmp = bb_for_stmt (stmt);
d = gimple_default_def (cfun, SSA_NAME_VAR (var));
if (bitmap_bit_p (live_entry_blocks (live, i), entry_block)) /* If there was a live on entry use, set the bit. */
{ if (add_block)
if (!IS_EMPTY_STMT (stmt))
{
num++;
print_generic_expr (stderr, var, TDF_SLIM);
fprintf (stderr, " is defined ");
if (tmp)
fprintf (stderr, " in BB%d, ", tmp->index);
fprintf (stderr, "by:\n");
print_generic_expr (stderr, stmt, TDF_SLIM);
fprintf (stderr, "\nIt is also live-on-entry to entry BB %d",
entry_block);
fprintf (stderr, " So it appears to have multiple defs.\n");
}
else
{ {
if (d != var) global = true;
{ bitmap_set_bit (live->livein[add_block->index], p);
num++;
print_generic_expr (stderr, var, TDF_SLIM);
fprintf (stderr, " is live-on-entry to BB%d ",entry_block);
if (d)
{
fprintf (stderr, " but is not the default def of ");
print_generic_expr (stderr, d, TDF_SLIM);
fprintf (stderr, "\n");
} }
else
fprintf (stderr, " and there is no default def.\n");
}
}
}
else
if (d == var)
{
/* The only way this var shouldn't be marked live on entry is
if it occurs in a PHI argument of the block. */
int z, ok = 0;
for (phi = phi_nodes (e->dest);
phi && !ok;
phi = PHI_CHAIN (phi))
{
for (z = 0; z < PHI_NUM_ARGS (phi); z++)
if (var == PHI_ARG_DEF (phi, z))
{
ok = 1;
break;
} }
}
if (ok)
continue;
num++;
print_generic_expr (stderr, var, TDF_SLIM);
fprintf (stderr, " is not marked live-on-entry to entry BB%d ",
entry_block);
fprintf (stderr, "but it is a default def so it should be.\n");
}
}
}
gcc_assert (num <= 0);
#endif
BITMAP_FREE (saw_def); /* If SSA_NAME is live on entry to at least one block, fill in all the live
on entry blocks between the def and all the uses. */
return live; if (global)
bitmap_set_bit (live->global, p);
} }
...@@ -792,49 +691,69 @@ calculate_live_on_entry (var_map map) ...@@ -792,49 +691,69 @@ calculate_live_on_entry (var_map map)
void void
calculate_live_on_exit (tree_live_info_p liveinfo) calculate_live_on_exit (tree_live_info_p liveinfo)
{ {
unsigned b; unsigned i;
unsigned i, x; int p;
bitmap *on_exit; tree t, phi;
basic_block bb; basic_block bb;
edge e; edge e;
tree t, phi; edge_iterator ei;
bitmap on_entry;
var_map map = liveinfo->map;
on_exit = (bitmap *)xmalloc (last_basic_block * sizeof (bitmap)); /* live on entry calculations used the liveouit vector for defs. */
for (x = 0; x < (unsigned)last_basic_block; x++) FOR_EACH_BB (bb)
on_exit[x] = BITMAP_ALLOC (NULL); bitmap_clear (liveinfo->liveout[bb->index]);
/* Set all the live-on-exit bits for uses in PHIs. */ /* Set all the live-on-exit bits for uses in PHIs. */
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
/* Mark the PHI arguments which are live on exit to the pred block. */
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
for (i = 0; i < (unsigned)PHI_NUM_ARGS (phi); i++) for (i = 0; i < (unsigned)PHI_NUM_ARGS (phi); i++)
{ {
t = PHI_ARG_DEF (phi, i); t = PHI_ARG_DEF (phi, i);
e = PHI_ARG_EDGE (phi, i); if (TREE_CODE (t) != SSA_NAME)
if (!phi_ssa_name_p (t) || e->src == ENTRY_BLOCK_PTR)
continue; continue;
set_if_valid (map, on_exit[e->src->index], t); p = var_to_partition (liveinfo->map, t);
if (p == NO_PARTITION)
continue;
e = PHI_ARG_EDGE (phi, i);
if (e->src != ENTRY_BLOCK_PTR)
bitmap_set_bit (liveinfo->liveout[e->src->index], p);
} }
/* 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],
live_on_entry (liveinfo, e->dest));
} }
}
/* Set live on exit for all predecessors of live on entry's. */ /* Given partition map MAP, calculate all the live on entry bitmaps for
for (i = 0; i < num_var_partitions (map); i++) each partition. Return a new live info object. */
{
bitmap_iterator bi; tree_live_info_p
calculate_live_ranges (var_map map)
{
tree var;
unsigned i;
tree_live_info_p live;
on_entry = live_entry_blocks (liveinfo, i); live = new_tree_live_info (map);
EXECUTE_IF_SET_IN_BITMAP (on_entry, 0, b, bi) for (i = 0; i < num_var_partitions (map); i++)
{ {
edge_iterator ei; var = partition_to_var (map, i);
FOR_EACH_EDGE (e, ei, BASIC_BLOCK (b)->preds) if (var != NULL_TREE)
if (e->src != ENTRY_BLOCK_PTR) set_var_live_on_entry (var, live);
bitmap_set_bit (on_exit[e->src->index], i);
}
} }
liveinfo->liveout = on_exit; live_worklist (live);
#ifdef ENABLE_CHECKING
verify_live_on_entry (live);
#endif
calculate_live_on_exit (live);
return live;
} }
...@@ -1346,6 +1265,17 @@ add_conflicts_if_valid (tpa_p tpa, conflict_graph graph, ...@@ -1346,6 +1265,17 @@ add_conflicts_if_valid (tpa_p tpa, conflict_graph graph,
} }
} }
/* 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 /* Return a conflict graph for the information contained in LIVE_INFO. Only
conflicts between items in the same TPA list are added. If optional conflicts between items in the same TPA list are added. If optional
coalesce list CL is passed in, any copies encountered are added. */ coalesce list CL is passed in, any copies encountered are added. */
...@@ -1817,14 +1747,11 @@ dump_live_info (FILE *f, tree_live_info_p live, int flag) ...@@ -1817,14 +1747,11 @@ dump_live_info (FILE *f, tree_live_info_p live, int flag)
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
fprintf (f, "\nLive on entry to BB%d : ", bb->index); fprintf (f, "\nLive on entry to BB%d : ", bb->index);
for (i = 0; i < num_var_partitions (map); i++) EXECUTE_IF_SET_IN_BITMAP (live->livein[bb->index], 0, i, bi)
{
if (bitmap_bit_p (live_entry_blocks (live, i), bb->index))
{ {
print_generic_expr (f, partition_to_var (map, i), TDF_SLIM); print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
fprintf (f, " "); fprintf (f, " ");
} }
}
fprintf (f, "\n"); fprintf (f, "\n");
} }
} }
...@@ -1857,4 +1784,103 @@ register_ssa_partition_check (tree ssa_var) ...@@ -1857,4 +1784,103 @@ register_ssa_partition_check (tree ssa_var)
internal_error ("SSA corruption"); internal_error ("SSA corruption");
} }
} }
/* Verify that the info in LIVE matches the current cfg. */
static void
verify_live_on_entry (tree_live_info_p live)
{
unsigned i;
tree var;
tree phi, stmt;
basic_block bb;
edge e;
int num;
edge_iterator ei;
var_map map = live->map;
/* 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)
{
int entry_block = e->dest->index;
if (e->dest == EXIT_BLOCK_PTR)
continue;
for (i = 0; i < (unsigned)num_var_partitions (map); i++)
{
basic_block tmp;
tree d;
bitmap loe;
var = partition_to_var (map, i);
stmt = SSA_NAME_DEF_STMT (var);
tmp = bb_for_stmt (stmt);
d = gimple_default_def (cfun, SSA_NAME_VAR (var));
loe = live_on_entry (live, e->dest);
if (loe && bitmap_bit_p (loe, i))
{
if (!IS_EMPTY_STMT (stmt))
{
num++;
print_generic_expr (stderr, var, TDF_SLIM);
fprintf (stderr, " is defined ");
if (tmp)
fprintf (stderr, " in BB%d, ", tmp->index);
fprintf (stderr, "by:\n");
print_generic_expr (stderr, stmt, TDF_SLIM);
fprintf (stderr, "\nIt is also live-on-entry to entry BB %d",
entry_block);
fprintf (stderr, " So it appears to have multiple defs.\n");
}
else
{
if (d != var)
{
num++;
print_generic_expr (stderr, var, TDF_SLIM);
fprintf (stderr, " is live-on-entry to BB%d ",entry_block);
if (d)
{
fprintf (stderr, " but is not the default def of ");
print_generic_expr (stderr, d, TDF_SLIM);
fprintf (stderr, "\n");
}
else
fprintf (stderr, " and there is no default def.\n");
}
}
}
else
if (d == var)
{
/* The only way this var shouldn't be marked live on entry is
if it occurs in a PHI argument of the block. */
int z, ok = 0;
for (phi = phi_nodes (e->dest);
phi && !ok;
phi = PHI_CHAIN (phi))
{
for (z = 0; z < PHI_NUM_ARGS (phi); z++)
if (var == PHI_ARG_DEF (phi, z))
{
ok = 1;
break;
}
}
if (ok)
continue;
num++;
print_generic_expr (stderr, var, TDF_SLIM);
fprintf (stderr, " is not marked live-on-entry to entry BB%d ",
entry_block);
fprintf (stderr, "but it is a default def so it should be.\n");
}
}
}
gcc_assert (num <= 0);
}
#endif #endif
...@@ -182,9 +182,9 @@ register_ssa_partition (var_map map, tree ssa_var) ...@@ -182,9 +182,9 @@ register_ssa_partition (var_map map, tree ssa_var)
As well, partitions are marked as to whether they are global (live As well, partitions are marked as to whether they are global (live
outside the basic block they are defined in). outside the basic block they are defined in).
The live-on-entry information is per variable. It provide a bitmap for The live-on-entry information is per block. It provide a bitmap for
each variable which has a bit set for each basic block that the variable each block which has a bit set for each partition that is live on entry to
is live on entry to that block. that block.
The live-on-exit information is per block. It provides a bitmap for each The live-on-exit information is per block. It provides a bitmap for each
block indicating which partitions are live on exit from the block. block indicating which partitions are live on exit from the block.
...@@ -218,12 +218,18 @@ typedef struct tree_live_info_d ...@@ -218,12 +218,18 @@ typedef struct tree_live_info_d
/* Number of basic blocks when live on exit calculated. */ /* Number of basic blocks when live on exit calculated. */
int num_blocks; int num_blocks;
/* Vector used when creating live ranges as a visited stack. */
int *work_stack;
/* Top of workstack. */
int *stack_top;
/* Bitmap of what variables are live on exit for a basic blocks. */ /* Bitmap of what variables are live on exit for a basic blocks. */
bitmap *liveout; bitmap *liveout;
} *tree_live_info_p; } *tree_live_info_p;
extern tree_live_info_p calculate_live_on_entry (var_map); extern tree_live_info_p calculate_live_ranges (var_map);
extern void calculate_live_on_exit (tree_live_info_p); extern void calculate_live_on_exit (tree_live_info_p);
extern void delete_tree_live_info (tree_live_info_p); extern void delete_tree_live_info (tree_live_info_p);
...@@ -233,7 +239,7 @@ extern void delete_tree_live_info (tree_live_info_p); ...@@ -233,7 +239,7 @@ extern void delete_tree_live_info (tree_live_info_p);
extern void dump_live_info (FILE *, tree_live_info_p, int); extern void dump_live_info (FILE *, tree_live_info_p, int);
static inline int partition_is_global (tree_live_info_p, int); static inline int partition_is_global (tree_live_info_p, int);
static inline bitmap live_entry_blocks (tree_live_info_p, int); static inline bitmap live_on_entry (tree_live_info_p, basic_block);
static inline bitmap live_on_exit (tree_live_info_p, basic_block); static inline bitmap live_on_exit (tree_live_info_p, basic_block);
static inline var_map live_var_map (tree_live_info_p); static inline var_map live_var_map (tree_live_info_p);
static inline void live_merge_and_clear (tree_live_info_p, int, int); static inline void live_merge_and_clear (tree_live_info_p, int, int);
...@@ -254,10 +260,13 @@ partition_is_global (tree_live_info_p live, int p) ...@@ -254,10 +260,13 @@ partition_is_global (tree_live_info_p live, int p)
partition P. */ partition P. */
static inline bitmap static inline bitmap
live_entry_blocks (tree_live_info_p live, int p) live_on_entry (tree_live_info_p live, basic_block bb)
{ {
gcc_assert (live->livein); gcc_assert (live->livein);
return live->livein[p]; gcc_assert (bb != ENTRY_BLOCK_PTR);
gcc_assert (bb != EXIT_BLOCK_PTR);
return live->livein[bb->index];
} }
...@@ -290,6 +299,8 @@ live_var_map (tree_live_info_p live) ...@@ -290,6 +299,8 @@ live_var_map (tree_live_info_p live)
static inline void static inline void
live_merge_and_clear (tree_live_info_p live, int p1, int p2) live_merge_and_clear (tree_live_info_p live, int p1, int p2)
{ {
gcc_assert (live->livein[p1]);
gcc_assert (live->livein[p2]);
bitmap_ior_into (live->livein[p1], live->livein[p2]); bitmap_ior_into (live->livein[p1], live->livein[p2]);
bitmap_zero (live->livein[p2]); bitmap_zero (live->livein[p2]);
} }
...@@ -300,7 +311,7 @@ live_merge_and_clear (tree_live_info_p live, int p1, int p2) ...@@ -300,7 +311,7 @@ live_merge_and_clear (tree_live_info_p live, int p1, int p2)
static inline void static inline void
make_live_on_entry (tree_live_info_p live, basic_block bb , int p) make_live_on_entry (tree_live_info_p live, basic_block bb , int p)
{ {
bitmap_set_bit (live->livein[p], bb->index); bitmap_set_bit (live->livein[bb->index], p);
bitmap_set_bit (live->global, p); bitmap_set_bit (live->global, p);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment