Commit dda49b66 by Steven Bosscher Committed by Steven Bosscher

basic-block.h (XMALLOC_REG_SET, [...]): New.

	* basic-block.h (XMALLOC_REG_SET, XFREE_REG_SET): New.
	(struct basic_block_def): Remove local_set and cond_local_set
	fields.  Update comment for global_live_at_start.
	* flow.c (calculate_global_regs_live): Allocate local_sets and
	cond_local_sets here as arrays of bitmaps previously stored in
	bb->local_set and bb->cond_local_set.  Use xmalloc instead of
	obstack allocated bitmaps.

From-SVN: r90390
parent 780f9446
2004-11-10 Steven Bosscher <stevenb@suse.de>
* basic-block.h (XMALLOC_REG_SET, XFREE_REG_SET): New.
(struct basic_block_def): Remove local_set and cond_local_set
fields. Update comment for global_live_at_start.
* flow.c (calculate_global_regs_live): Allocate local_sets and
cond_local_sets here as arrays of bitmaps previously stored in
bb->local_set and bb->cond_local_set. Use xmalloc instead of
obstack allocated bitmaps.
2004-11-09 H.J. Lu <hongjiu.lu@intel.com> 2004-11-09 H.J. Lu <hongjiu.lu@intel.com>
PR target/18380 PR target/18380
......
...@@ -110,6 +110,12 @@ typedef bitmap_iterator reg_set_iterator; ...@@ -110,6 +110,12 @@ typedef bitmap_iterator reg_set_iterator;
/* Do any cleanup needed on a regset when it is no longer used. */ /* Do any cleanup needed on a regset when it is no longer used. */
#define FREE_REG_SET(REGSET) BITMAP_FREE(REGSET) #define FREE_REG_SET(REGSET) BITMAP_FREE(REGSET)
/* Allocate a register set with xmalloc. */
#define XMALLOC_REG_SET() BITMAP_XMALLOC ()
/* Free a register set. */
#define XFREE_REG_SET(REGSET) BITMAP_XFREE (REGSET)
/* Do any one-time initializations needed for regsets. */ /* Do any one-time initializations needed for regsets. */
#define INIT_ONCE_REG_SET() BITMAP_INIT_ONCE () #define INIT_ONCE_REG_SET() BITMAP_INIT_ONCE ()
...@@ -229,20 +235,9 @@ struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb") ...@@ -229,20 +235,9 @@ struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")
VEC(edge) *preds; VEC(edge) *preds;
VEC(edge) *succs; VEC(edge) *succs;
/* Liveness info. */ /* The registers that are live on entry to this block. */
/* The registers that are modified within this in block. */
bitmap GTY ((skip (""))) local_set;
/* The registers that are conditionally modified within this block.
In other words, registers that are set only as part of a
COND_EXEC. */
bitmap GTY ((skip (""))) cond_local_set;
/* The registers that are live on entry to this block.
Note that in SSA form, global_live_at_start does not reflect the
use of regs in phi functions, since the liveness of these regs
may depend on which edge was taken into the block. */
bitmap GTY ((skip (""))) global_live_at_start; bitmap GTY ((skip (""))) global_live_at_start;
/* The registers that are live on exit from this block. */ /* The registers that are live on exit from this block. */
bitmap GTY ((skip (""))) global_live_at_end; bitmap GTY ((skip (""))) global_live_at_end;
......
...@@ -112,7 +112,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -112,7 +112,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* TODO: /* TODO:
Split out from life_analysis: Split out from life_analysis:
- local property discovery (bb->local_live, bb->local_set) - local property discovery
- global property computation - global property computation
- log links creation - log links creation
- pre/post modify transformation - pre/post modify transformation
...@@ -1018,6 +1018,14 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) ...@@ -1018,6 +1018,14 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
regset tmp, new_live_at_end, invalidated_by_call; regset tmp, new_live_at_end, invalidated_by_call;
regset_head tmp_head, invalidated_by_call_head; regset_head tmp_head, invalidated_by_call_head;
regset_head new_live_at_end_head; regset_head new_live_at_end_head;
/* The registers that are modified within this in block. */
regset *local_sets;
/* The registers that are conditionally modified within this block.
In other words, regs that are set only as part of a COND_EXEC. */
regset *cond_local_sets;
int i; int i;
/* Some passes used to forget clear aux field of basic block causing /* Some passes used to forget clear aux field of basic block causing
...@@ -1036,12 +1044,18 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) ...@@ -1036,12 +1044,18 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
SET_REGNO_REG_SET (invalidated_by_call, i); SET_REGNO_REG_SET (invalidated_by_call, i);
/* Allocate space for the sets of local properties. */
local_sets = xcalloc (last_basic_block - (INVALID_BLOCK + 1),
sizeof (regset));
cond_local_sets = xcalloc (last_basic_block - (INVALID_BLOCK + 1),
sizeof (regset));
/* Create a worklist. Allocate an extra slot for ENTRY_BLOCK, and one /* Create a worklist. Allocate an extra slot for ENTRY_BLOCK, and one
because the `head == tail' style test for an empty queue doesn't because the `head == tail' style test for an empty queue doesn't
work with a full queue. */ work with a full queue. */
queue = xmalloc ((n_basic_blocks + 2) * sizeof (*queue)); queue = xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1)) * sizeof (*queue));
qtail = queue; qtail = queue;
qhead = qend = queue + n_basic_blocks + 2; qhead = qend = queue + n_basic_blocks - (INVALID_BLOCK + 1);
/* Queue the blocks set in the initial mask. Do this in reverse block /* Queue the blocks set in the initial mask. Do this in reverse block
number order so that we are more likely for the first round to do number order so that we are more likely for the first round to do
...@@ -1171,13 +1185,14 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) ...@@ -1171,13 +1185,14 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
} }
/* On our first pass through this block, we'll go ahead and continue. /* On our first pass through this block, we'll go ahead and continue.
Recognize first pass by local_set NULL. On subsequent passes, we Recognize first pass by checking if local_set is NULL for this
get to skip out early if live_at_end wouldn't have changed. */ basic block. On subsequent passes, we get to skip out early if
live_at_end wouldn't have changed. */
if (bb->local_set == NULL) if (local_sets[bb->index - (INVALID_BLOCK + 1)] == NULL)
{ {
bb->local_set = OBSTACK_ALLOC_REG_SET (&flow_obstack); local_sets[bb->index - (INVALID_BLOCK + 1)] = XMALLOC_REG_SET ();
bb->cond_local_set = OBSTACK_ALLOC_REG_SET (&flow_obstack); cond_local_sets[bb->index - (INVALID_BLOCK + 1)] = XMALLOC_REG_SET ();
rescan = 1; rescan = 1;
} }
else else
...@@ -1190,28 +1205,35 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) ...@@ -1190,28 +1205,35 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
new_live_at_end); new_live_at_end);
if (!rescan) if (!rescan)
/* If any of the registers in the new live_at_end set are {
conditionally set in this basic block, we must rescan. regset cond_local_set;
This is because conditional lifetimes at the end of the
block do not just take the live_at_end set into /* If any of the registers in the new live_at_end set are
account, but also the liveness at the start of each conditionally set in this basic block, we must rescan.
successor block. We can miss changes in those sets if This is because conditional lifetimes at the end of the
we only compare the new live_at_end against the block do not just take the live_at_end set into
previous one. */ account, but also the liveness at the start of each
rescan = bitmap_intersect_p (new_live_at_end, successor block. We can miss changes in those sets if
bb->cond_local_set); we only compare the new live_at_end against the
previous one. */
cond_local_set = cond_local_sets[bb->index - (INVALID_BLOCK + 1)];
rescan = bitmap_intersect_p (new_live_at_end, cond_local_set);
}
if (!rescan) if (!rescan)
{ {
regset local_set;
/* Find the set of changed bits. Take this opportunity /* Find the set of changed bits. Take this opportunity
to notice that this set is empty and early out. */ to notice that this set is empty and early out. */
bitmap_xor (tmp, bb->global_live_at_end, new_live_at_end); bitmap_xor (tmp, bb->global_live_at_end, new_live_at_end);
if (bitmap_empty_p (tmp)) if (bitmap_empty_p (tmp))
continue; continue;
/* If any of the changed bits overlap with local_set, /* If any of the changed bits overlap with local_sets[bb],
we'll have to rescan the block. */ we'll have to rescan the block. */
rescan = bitmap_intersect_p (tmp, bb->local_set); local_set = local_sets[bb->index - (INVALID_BLOCK + 1)];
rescan = bitmap_intersect_p (tmp, local_set);
} }
} }
...@@ -1238,8 +1260,10 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) ...@@ -1238,8 +1260,10 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
/* Rescan the block insn by insn to turn (a copy of) live_at_end /* Rescan the block insn by insn to turn (a copy of) live_at_end
into live_at_start. */ into live_at_start. */
propagate_block (bb, new_live_at_end, bb->local_set, propagate_block (bb, new_live_at_end,
bb->cond_local_set, flags); local_sets[bb->index - (INVALID_BLOCK + 1)],
cond_local_sets[bb->index - (INVALID_BLOCK + 1)],
flags);
/* If live_at start didn't change, no need to go farther. */ /* If live_at start didn't change, no need to go farther. */
if (REG_SET_EQUAL_P (bb->global_live_at_start, new_live_at_end)) if (REG_SET_EQUAL_P (bb->global_live_at_start, new_live_at_end))
...@@ -1272,20 +1296,22 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) ...@@ -1272,20 +1296,22 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
EXECUTE_IF_SET_IN_SBITMAP (blocks_out, 0, i, EXECUTE_IF_SET_IN_SBITMAP (blocks_out, 0, i,
{ {
basic_block bb = BASIC_BLOCK (i); basic_block bb = BASIC_BLOCK (i);
FREE_REG_SET (bb->local_set); XFREE_REG_SET (local_sets[bb->index - (INVALID_BLOCK + 1)]);
FREE_REG_SET (bb->cond_local_set); XFREE_REG_SET (cond_local_sets[bb->index - (INVALID_BLOCK + 1)]);
}); });
} }
else else
{ {
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
FREE_REG_SET (bb->local_set); XFREE_REG_SET (local_sets[bb->index - (INVALID_BLOCK + 1)]);
FREE_REG_SET (bb->cond_local_set); XFREE_REG_SET (cond_local_sets[bb->index - (INVALID_BLOCK + 1)]);
} }
} }
free (queue); free (queue);
free (cond_local_sets);
free (local_sets);
} }
......
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