Commit 918ed612 by Zdenek Dvorak Committed by Zdenek Dvorak

basic_block.h (struct basic_block_def): Added prev_bb and next_bb fields.

	* basic_block.h (struct basic_block_def): Added prev_bb and next_bb
	fields.
	(FOR_BB_BETWEEN, FOR_ALL_BB, FOR_ALL_BB_REVERSE): New macros for
	traversing basic block chain.
	(create_basic_block_structure, create_basic_block): Declaration changed.
	(link_block, unlink_block): Declare.
	* cfg.c (entry_exit_blocks): Initialize new fields.
	(link_block, unlink_block): New.
	(expunge_block_nocompact): Unlink basic block.
	(dump_flow_info): Print prev_bb/next_bb fields.
	* cfgbuild.c (find_basic_blocks_1, find_basic_blocks): Modified.
	* cfgcleanup.c (merge_blocks_move_predecessor_nojumps): Modified.
	* cfglayout.c (fixup_reorder_chain, cfg_layout_duplicate_bb): Modified.
	* cfgrtl.c (create_basic_block_structure, create_basic_block,
	split_block, force_nonfallthru_and_redirect, split_edge): Modified.
	(verify_flow_info): Check that list agrees with numbering.

From-SVN: r53642
parent e0322d5c
2002-05-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* basic_block.h (struct basic_block_def): Added prev_bb and next_bb
fields.
(FOR_BB_BETWEEN, FOR_ALL_BB, FOR_ALL_BB_REVERSE): New macros for
traversing basic block chain.
(create_basic_block_structure, create_basic_block): Declaration changed.
(link_block, unlink_block): Declare.
* cfg.c (entry_exit_blocks): Initialize new fields.
(link_block, unlink_block): New.
(expunge_block_nocompact): Unlink basic block.
(dump_flow_info): Print prev_bb/next_bb fields.
* cfgbuild.c (find_basic_blocks_1, find_basic_blocks): Modified.
* cfgcleanup.c (merge_blocks_move_predecessor_nojumps): Modified.
* cfglayout.c (fixup_reorder_chain, cfg_layout_duplicate_bb): Modified.
* cfgrtl.c (create_basic_block_structure, create_basic_block,
split_block, force_nonfallthru_and_redirect, split_edge): Modified.
(verify_flow_info): Check that list agrees with numbering.
2002-05-19 Neil Booth <neil@daikokuya.demon.co.uk> 2002-05-19 Neil Booth <neil@daikokuya.demon.co.uk>
* c-common.c (preprocessing_asm): New macro. * c-common.c (preprocessing_asm): New macro.
......
...@@ -206,6 +206,9 @@ typedef struct basic_block_def { ...@@ -206,6 +206,9 @@ typedef struct basic_block_def {
/* The index of this block. */ /* The index of this block. */
int index; int index;
/* Previous and next blocks in the chain. */
struct basic_block_def *prev_bb, *next_bb;
/* The loop depth of this block. */ /* The loop depth of this block. */
int loop_depth; int loop_depth;
...@@ -240,6 +243,16 @@ extern varray_type basic_block_info; ...@@ -240,6 +243,16 @@ extern varray_type basic_block_info;
#define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N))) #define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N)))
/* For iterating over basic blocks. */
#define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \
for (BB = FROM; BB != TO; BB = BB->DIR)
#define FOR_EACH_BB(BB) \
FOR_BB_BETWEEN (BB, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR, next_bb)
#define FOR_EACH_BB_REVERSE(BB) \
FOR_BB_BETWEEN (BB, EXIT_BLOCK_PTR->prev_bb, ENTRY_BLOCK_PTR, prev_bb)
/* What registers are live at the setjmp call. */ /* What registers are live at the setjmp call. */
extern regset regs_live_at_setjmp; extern regset regs_live_at_setjmp;
...@@ -314,8 +327,8 @@ extern void remove_edge PARAMS ((edge)); ...@@ -314,8 +327,8 @@ extern void remove_edge PARAMS ((edge));
extern void redirect_edge_succ PARAMS ((edge, basic_block)); extern void redirect_edge_succ PARAMS ((edge, basic_block));
extern edge redirect_edge_succ_nodup PARAMS ((edge, basic_block)); extern edge redirect_edge_succ_nodup PARAMS ((edge, basic_block));
extern void redirect_edge_pred PARAMS ((edge, basic_block)); extern void redirect_edge_pred PARAMS ((edge, basic_block));
extern basic_block create_basic_block_structure PARAMS ((int, rtx, rtx, rtx)); extern basic_block create_basic_block_structure PARAMS ((int, rtx, rtx, rtx, basic_block));
extern basic_block create_basic_block PARAMS ((int, rtx, rtx)); extern basic_block create_basic_block PARAMS ((rtx, rtx, basic_block));
extern int flow_delete_block PARAMS ((basic_block)); extern int flow_delete_block PARAMS ((basic_block));
extern int flow_delete_block_noexpunge PARAMS ((basic_block)); extern int flow_delete_block_noexpunge PARAMS ((basic_block));
extern void clear_bb_flags PARAMS ((void)); extern void clear_bb_flags PARAMS ((void));
...@@ -644,6 +657,8 @@ extern void debug_regset PARAMS ((regset)); ...@@ -644,6 +657,8 @@ extern void debug_regset PARAMS ((regset));
extern void allocate_reg_life_data PARAMS ((void)); extern void allocate_reg_life_data PARAMS ((void));
extern void allocate_bb_life_data PARAMS ((void)); extern void allocate_bb_life_data PARAMS ((void));
extern void expunge_block PARAMS ((basic_block)); extern void expunge_block PARAMS ((basic_block));
extern void link_block PARAMS ((basic_block, basic_block));
extern void unlink_block PARAMS ((basic_block));
extern void expunge_block_nocompact PARAMS ((basic_block)); extern void expunge_block_nocompact PARAMS ((basic_block));
extern basic_block alloc_block PARAMS ((void)); extern basic_block alloc_block PARAMS ((void));
extern void find_unreachable_blocks PARAMS ((void)); extern void find_unreachable_blocks PARAMS ((void));
......
...@@ -93,6 +93,8 @@ struct basic_block_def entry_exit_blocks[2] ...@@ -93,6 +93,8 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* global_live_at_end */ NULL, /* global_live_at_end */
NULL, /* aux */ NULL, /* aux */
ENTRY_BLOCK, /* index */ ENTRY_BLOCK, /* index */
NULL, /* prev_bb */
EXIT_BLOCK_PTR, /* next_bb */
0, /* loop_depth */ 0, /* loop_depth */
0, /* count */ 0, /* count */
0, /* frequency */ 0, /* frequency */
...@@ -111,6 +113,8 @@ struct basic_block_def entry_exit_blocks[2] ...@@ -111,6 +113,8 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* global_live_at_end */ NULL, /* global_live_at_end */
NULL, /* aux */ NULL, /* aux */
EXIT_BLOCK, /* index */ EXIT_BLOCK, /* index */
ENTRY_BLOCK_PTR, /* prev_bb */
NULL, /* next_bb */
0, /* loop_depth */ 0, /* loop_depth */
0, /* count */ 0, /* count */
0, /* frequency */ 0, /* frequency */
...@@ -220,12 +224,35 @@ alloc_block () ...@@ -220,12 +224,35 @@ alloc_block ()
return bb; return bb;
} }
/* Link block B to chain after AFTER. */
void
link_block (b, after)
basic_block b, after;
{
b->next_bb = after->next_bb;
b->prev_bb = after;
after->next_bb = b;
b->next_bb->prev_bb = b;
}
/* Unlink block B from chain. */
void
unlink_block (b)
basic_block b;
{
b->next_bb->prev_bb = b->prev_bb;
b->prev_bb->next_bb = b->next_bb;
}
/* Remove block B from the basic block array and compact behind it. */ /* Remove block B from the basic block array and compact behind it. */
void void
expunge_block_nocompact (b) expunge_block_nocompact (b)
basic_block b; basic_block b;
{ {
unlink_block (b);
/* Invalidate data to make bughunting easier. */ /* Invalidate data to make bughunting easier. */
memset (b, 0, sizeof *b); memset (b, 0, sizeof *b);
b->index = -3; b->index = -3;
...@@ -521,6 +548,8 @@ dump_flow_info (file) ...@@ -521,6 +548,8 @@ dump_flow_info (file)
fprintf (file, "\nBasic block %d: first insn %d, last %d, ", fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
i, INSN_UID (bb->head), INSN_UID (bb->end)); i, INSN_UID (bb->head), INSN_UID (bb->end));
fprintf (file, "prev %d, next %d, ",
bb->prev_bb->index, bb->next_bb->index);
fprintf (file, "loop_depth %d, count ", bb->loop_depth); fprintf (file, "loop_depth %d, count ", bb->loop_depth);
fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count); fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
fprintf (file, ", freq %i.\n", bb->frequency); fprintf (file, ", freq %i.\n", bb->frequency);
......
...@@ -476,6 +476,7 @@ find_basic_blocks_1 (f) ...@@ -476,6 +476,7 @@ find_basic_blocks_1 (f)
rtx trll = NULL_RTX; rtx trll = NULL_RTX;
rtx head = NULL_RTX; rtx head = NULL_RTX;
rtx end = NULL_RTX; rtx end = NULL_RTX;
basic_block prev = ENTRY_BLOCK_PTR;
/* We process the instructions in a slightly different way than we did /* We process the instructions in a slightly different way than we did
previously. This is so that we see a NOTE_BASIC_BLOCK after we have previously. This is so that we see a NOTE_BASIC_BLOCK after we have
...@@ -492,7 +493,7 @@ find_basic_blocks_1 (f) ...@@ -492,7 +493,7 @@ find_basic_blocks_1 (f)
if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER) if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
&& head) && head)
{ {
create_basic_block_structure (i++, head, end, bb_note); prev = create_basic_block_structure (i++, head, end, bb_note, prev);
head = end = NULL_RTX; head = end = NULL_RTX;
bb_note = NULL_RTX; bb_note = NULL_RTX;
} }
...@@ -506,7 +507,7 @@ find_basic_blocks_1 (f) ...@@ -506,7 +507,7 @@ find_basic_blocks_1 (f)
if (head && control_flow_insn_p (insn)) if (head && control_flow_insn_p (insn))
{ {
create_basic_block_structure (i++, head, end, bb_note); prev = create_basic_block_structure (i++, head, end, bb_note, prev);
head = end = NULL_RTX; head = end = NULL_RTX;
bb_note = NULL_RTX; bb_note = NULL_RTX;
} }
...@@ -588,7 +589,7 @@ find_basic_blocks_1 (f) ...@@ -588,7 +589,7 @@ find_basic_blocks_1 (f)
} }
if (head != NULL_RTX) if (head != NULL_RTX)
create_basic_block_structure (i++, head, end, bb_note); create_basic_block_structure (i++, head, end, bb_note, prev);
else if (bb_note) else if (bb_note)
delete_insn (bb_note); delete_insn (bb_note);
...@@ -633,6 +634,8 @@ find_basic_blocks (f, nregs, file) ...@@ -633,6 +634,8 @@ find_basic_blocks (f, nregs, file)
} }
n_basic_blocks = count_basic_blocks (f); n_basic_blocks = count_basic_blocks (f);
ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
/* Size the basic block table. The actual structures will be allocated /* Size the basic block table. The actual structures will be allocated
by find_basic_blocks_1, since we want to keep the structure pointers by find_basic_blocks_1, since we want to keep the structure pointers
......
...@@ -723,6 +723,9 @@ merge_blocks_move_predecessor_nojumps (a, b) ...@@ -723,6 +723,9 @@ merge_blocks_move_predecessor_nojumps (a, b)
a->index = b->index; a->index = b->index;
b->index = index; b->index = index;
unlink_block (a);
link_block (a, b->prev_bb);
/* Now blocks A and B are contiguous. Merge them. */ /* Now blocks A and B are contiguous. Merge them. */
merge_blocks_nomove (a, b); merge_blocks_nomove (a, b);
} }
......
...@@ -357,7 +357,7 @@ scope_to_insns_finalize () ...@@ -357,7 +357,7 @@ scope_to_insns_finalize ()
static void static void
fixup_reorder_chain () fixup_reorder_chain ()
{ {
basic_block bb; basic_block bb, prev_bb;
int index; int index;
rtx insn = NULL; rtx insn = NULL;
...@@ -541,11 +541,20 @@ fixup_reorder_chain () ...@@ -541,11 +541,20 @@ fixup_reorder_chain ()
} }
} }
for (bb = BASIC_BLOCK (0), index = 0; bb; bb = RBI (bb)->next, index ++) prev_bb = ENTRY_BLOCK_PTR;
bb = BASIC_BLOCK (0);
index = 0;
for (; bb; prev_bb = bb, bb = RBI (bb)->next, index ++)
{ {
bb->index = index; bb->index = index;
BASIC_BLOCK (index) = bb; BASIC_BLOCK (index) = bb;
bb->prev_bb = prev_bb;
prev_bb->next_bb = bb;
} }
prev_bb->next_bb = EXIT_BLOCK_PTR;
EXIT_BLOCK_PTR->prev_bb = prev_bb;
} }
/* Perform sanity checks on the insn chain. /* Perform sanity checks on the insn chain.
...@@ -871,8 +880,9 @@ cfg_layout_duplicate_bb (bb, e) ...@@ -871,8 +880,9 @@ cfg_layout_duplicate_bb (bb, e)
#endif #endif
insn = duplicate_insn_chain (bb->head, bb->end); insn = duplicate_insn_chain (bb->head, bb->end);
new_bb = create_basic_block (n_basic_blocks, insn, new_bb = create_basic_block (insn,
insn ? get_last_insn () : NULL); insn ? get_last_insn () : NULL,
EXIT_BLOCK_PTR->prev_bb);
alloc_aux_for_block (new_bb, sizeof (struct reorder_block_def)); alloc_aux_for_block (new_bb, sizeof (struct reorder_block_def));
if (RBI (bb)->header) if (RBI (bb)->header)
......
...@@ -248,12 +248,14 @@ delete_insn_chain_and_edges (first, last) ...@@ -248,12 +248,14 @@ delete_insn_chain_and_edges (first, last)
the note and basic block struct in BB_NOTE, if any and do not grow the note and basic block struct in BB_NOTE, if any and do not grow
BASIC_BLOCK chain and should be used directly only by CFG construction code. BASIC_BLOCK chain and should be used directly only by CFG construction code.
END can be NULL in to create new empty basic block before HEAD. Both END END can be NULL in to create new empty basic block before HEAD. Both END
and HEAD can be NULL to create basic block at the end of INSN chain. */ and HEAD can be NULL to create basic block at the end of INSN chain.
AFTER is the basic block we should be put after. */
basic_block basic_block
create_basic_block_structure (index, head, end, bb_note) create_basic_block_structure (index, head, end, bb_note, after)
int index; int index;
rtx head, end, bb_note; rtx head, end, bb_note;
basic_block after;
{ {
basic_block bb; basic_block bb;
...@@ -311,6 +313,7 @@ create_basic_block_structure (index, head, end, bb_note) ...@@ -311,6 +313,7 @@ create_basic_block_structure (index, head, end, bb_note)
bb->end = end; bb->end = end;
bb->index = index; bb->index = index;
bb->flags = BB_NEW; bb->flags = BB_NEW;
link_block (bb, after);
BASIC_BLOCK (index) = bb; BASIC_BLOCK (index) = bb;
if (basic_block_for_insn) if (basic_block_for_insn)
update_bb_for_insn (bb); update_bb_for_insn (bb);
...@@ -323,17 +326,18 @@ create_basic_block_structure (index, head, end, bb_note) ...@@ -323,17 +326,18 @@ create_basic_block_structure (index, head, end, bb_note)
} }
/* Create new basic block consisting of instructions in between HEAD and END /* Create new basic block consisting of instructions in between HEAD and END
and place it to the BB chain at position INDEX. END can be NULL in to and place it to the BB chain after block AFTER. END can be NULL in to
create new empty basic block before HEAD. Both END and HEAD can be NULL to create new empty basic block before HEAD. Both END and HEAD can be NULL to
create basic block at the end of INSN chain. */ create basic block at the end of INSN chain. */
basic_block basic_block
create_basic_block (index, head, end) create_basic_block (head, end, after)
int index;
rtx head, end; rtx head, end;
basic_block after;
{ {
basic_block bb; basic_block bb;
int i; int i;
int index = after->index + 1;
/* Place the new block just after the block being split. */ /* Place the new block just after the block being split. */
VARRAY_GROW (basic_block_info, ++n_basic_blocks); VARRAY_GROW (basic_block_info, ++n_basic_blocks);
...@@ -349,7 +353,7 @@ create_basic_block (index, head, end) ...@@ -349,7 +353,7 @@ create_basic_block (index, head, end)
tmp->index = i; tmp->index = i;
} }
bb = create_basic_block_structure (index, head, end, NULL); bb = create_basic_block_structure (index, head, end, NULL, after);
bb->aux = NULL; bb->aux = NULL;
return bb; return bb;
} }
...@@ -537,7 +541,7 @@ split_block (bb, insn) ...@@ -537,7 +541,7 @@ split_block (bb, insn)
return 0; return 0;
/* Create the new basic block. */ /* Create the new basic block. */
new_bb = create_basic_block (bb->index + 1, NEXT_INSN (insn), bb->end); new_bb = create_basic_block (NEXT_INSN (insn), bb->end, bb);
new_bb->count = bb->count; new_bb->count = bb->count;
new_bb->frequency = bb->frequency; new_bb->frequency = bb->frequency;
new_bb->loop_depth = bb->loop_depth; new_bb->loop_depth = bb->loop_depth;
...@@ -998,7 +1002,7 @@ force_nonfallthru_and_redirect (e, target) ...@@ -998,7 +1002,7 @@ force_nonfallthru_and_redirect (e, target)
/* We can't redirect the entry block. Create an empty block at the /* We can't redirect the entry block. Create an empty block at the
start of the function which we use to add the new jump. */ start of the function which we use to add the new jump. */
edge *pe1; edge *pe1;
basic_block bb = create_basic_block (0, e->dest->head, NULL); basic_block bb = create_basic_block (e->dest->head, NULL, ENTRY_BLOCK_PTR);
/* Change the existing edge's source to be the new block, and add /* Change the existing edge's source to be the new block, and add
a new edge from the entry block to the new block. */ a new edge from the entry block to the new block. */
...@@ -1019,7 +1023,7 @@ force_nonfallthru_and_redirect (e, target) ...@@ -1019,7 +1023,7 @@ force_nonfallthru_and_redirect (e, target)
/* Create the new structures. */ /* Create the new structures. */
note = last_loop_beg_note (e->src->end); note = last_loop_beg_note (e->src->end);
jump_block jump_block
= create_basic_block (e->src->index + 1, NEXT_INSN (note), NULL); = create_basic_block (NEXT_INSN (note), NULL, e->src);
jump_block->count = e->count; jump_block->count = e->count;
jump_block->frequency = EDGE_FREQUENCY (e); jump_block->frequency = EDGE_FREQUENCY (e);
jump_block->loop_depth = target->loop_depth; jump_block->loop_depth = target->loop_depth;
...@@ -1286,8 +1290,7 @@ split_edge (edge_in) ...@@ -1286,8 +1290,7 @@ split_edge (edge_in)
else else
before = NULL_RTX; before = NULL_RTX;
bb = create_basic_block (edge_in->dest == EXIT_BLOCK_PTR ? n_basic_blocks bb = create_basic_block (before, NULL, edge_in->dest->prev_bb);
: edge_in->dest->index, before, NULL);
bb->count = edge_in->count; bb->count = edge_in->count;
bb->frequency = EDGE_FREQUENCY (edge_in); bb->frequency = EDGE_FREQUENCY (edge_in);
...@@ -1719,12 +1722,49 @@ verify_flow_info () ...@@ -1719,12 +1722,49 @@ verify_flow_info ()
size_t *edge_checksum; size_t *edge_checksum;
rtx x; rtx x;
int i, last_bb_num_seen, num_bb_notes, err = 0; int i, last_bb_num_seen, num_bb_notes, err = 0;
basic_block bb, last_bb_seen;
bb_info = (basic_block *) xcalloc (max_uid, sizeof (basic_block)); bb_info = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
last_visited = (basic_block *) xcalloc (n_basic_blocks + 2, last_visited = (basic_block *) xcalloc (n_basic_blocks + 2,
sizeof (basic_block)); sizeof (basic_block));
edge_checksum = (size_t *) xcalloc (n_basic_blocks + 2, sizeof (size_t)); edge_checksum = (size_t *) xcalloc (n_basic_blocks + 2, sizeof (size_t));
/* Check bb chain & numbers. */
last_bb_seen = ENTRY_BLOCK_PTR;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
{
if (bb != EXIT_BLOCK_PTR
&& bb != BASIC_BLOCK (bb->index))
{
error ("bb %d on wrong place", bb->index);
err = 1;
}
if (bb->prev_bb != last_bb_seen)
{
error ("prev_bb of %d should be %d, not %d",
bb->index, last_bb_seen->index, bb->prev_bb->index);
err = 1;
}
/* For now, also check that we didn't change the order. */
if (bb != EXIT_BLOCK_PTR && bb->index != last_bb_seen->index + 1)
{
error ("Wrong order of blocks %d and %d",
last_bb_seen->index, bb->index);
err = 1;
}
if (bb == EXIT_BLOCK_PTR && last_bb_seen->index != n_basic_blocks - 1)
{
error ("Only %d of %d blocks in chain",
last_bb_seen->index + 1, n_basic_blocks);
err = 1;
}
last_bb_seen = bb;
}
for (i = n_basic_blocks - 1; i >= 0; i--) for (i = n_basic_blocks - 1; i >= 0; i--)
{ {
basic_block bb = BASIC_BLOCK (i); basic_block bb = BASIC_BLOCK (i);
......
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