This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
find_sub_basic_blocks improvements
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, patches at x86-64 dot org
- Subject: find_sub_basic_blocks improvements
- From: Jan Hubicka <jh at suse dot cz>
- Date: Tue, 17 Jul 2001 17:15:57 +0200
Hi,
this patch makes find_sub_basic_blocks useable in more general way,
than it was till now.
Now it should be able to fixup almost any emit of new insns,
as it uses directly make_edges to wire in the CFG.
Bootstrapped/regtested i686 together with next patch.
Tue Jul 17 17:06:10 CEST 2001 Jan Hubicka <jh@suse.cz>
* basic-block.h (find_sub_basic_block): Declare.
* flow.c (make_edges): New arguments MIN and MAX;
(find_sub_basic_blocks): Revamp to use make_edges
and purge_dead_edges.
(find_basic_blocks): Update call of find_sub_basic_block.
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.102
diff -c -3 -p -r1.102 basic-block.h
*** basic-block.h 2001/07/16 20:54:42 1.102
--- basic-block.h 2001/07/17 14:57:07
*************** extern void debug_regset PARAMS ((regse
*** 597,602 ****
--- 599,605 ----
extern void allocate_reg_life_data PARAMS ((void));
extern void allocate_bb_life_data PARAMS ((void));
extern void find_unreachable_blocks PARAMS ((void));
+ extern void find_sub_basic_blocks PARAMS ((basic_block));
/* This function is always defined so it can be called from the
debugger, and it is declared extern so we don't get warnings about
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.429
diff -c -3 -p -r1.429 flow.c
*** flow.c 2001/07/17 04:55:23 1.429
--- flow.c 2001/07/17 14:57:11
*************** static int flow_find_cross_jump PARAMS
*** 374,380 ****
static int count_basic_blocks PARAMS ((rtx));
static void find_basic_blocks_1 PARAMS ((rtx));
static rtx find_label_refs PARAMS ((rtx, rtx));
! static void make_edges PARAMS ((rtx));
static void make_label_edge PARAMS ((sbitmap *, basic_block,
rtx, int));
static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
--- 374,380 ----
static int count_basic_blocks PARAMS ((rtx));
static void find_basic_blocks_1 PARAMS ((rtx));
static rtx find_label_refs PARAMS ((rtx, rtx));
! static void make_edges PARAMS ((rtx, int, int));
static void make_label_edge PARAMS ((sbitmap *, basic_block,
rtx, int));
static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
*************** static void flow_loop_tree_node_add PARA
*** 484,490 ****
static void flow_loops_tree_build PARAMS ((struct loops *));
static int flow_loop_level_compute PARAMS ((struct loop *, int));
static int flow_loops_level_compute PARAMS ((struct loops *));
- static void find_sub_basic_blocks PARAMS ((basic_block));
static bool redirect_edge_and_branch PARAMS ((edge, basic_block));
static basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
static rtx block_label PARAMS ((basic_block));
--- 484,489 ----
*************** find_basic_blocks (f, nregs, file)
*** 547,553 ****
compute_bb_for_insn (max_uid);
/* Discover the edges of our cfg. */
! make_edges (label_value_list);
/* Do very simple cleanup now, for the benefit of code that runs between
here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns. */
--- 546,552 ----
compute_bb_for_insn (max_uid);
/* Discover the edges of our cfg. */
! make_edges (label_value_list, 0, n_basic_blocks - 1);
/* Do very simple cleanup now, for the benefit of code that runs between
here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns. */
*************** find_label_refs (f, lvl)
*** 709,747 ****
/* Assume that someone emitted code with control flow instructions to the
basic block. Update the data structure. */
! static void
find_sub_basic_blocks (bb)
basic_block bb;
{
! rtx first_insn = bb->head, insn;
rtx end = bb->end;
- edge succ_list = bb->succ;
rtx jump_insn = NULL_RTX;
int created = 0;
int barrier = 0;
edge falltru = 0;
! basic_block first_bb = bb, last_bb;
! int i;
! if (GET_CODE (first_insn) == LABEL_REF)
! first_insn = NEXT_INSN (first_insn);
! first_insn = NEXT_INSN (first_insn);
! bb->succ = NULL;
- insn = first_insn;
/* Scan insn chain and try to find new basic block boundaries. */
! while (insn != end)
{
enum rtx_code code = GET_CODE (insn);
switch (code)
{
- case JUMP_INSN:
- /* We need some special care for those expressions. */
- if (GET_CODE (PATTERN (insn)) == ADDR_VEC
- || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
- abort();
- jump_insn = insn;
- break;
case BARRIER:
if (!jump_insn)
abort ();
--- 708,737 ----
/* Assume that someone emitted code with control flow instructions to the
basic block. Update the data structure. */
! void
find_sub_basic_blocks (bb)
basic_block bb;
{
! rtx insn = bb->head;
rtx end = bb->end;
rtx jump_insn = NULL_RTX;
int created = 0;
int barrier = 0;
edge falltru = 0;
! basic_block first_bb = bb;
! if (insn == bb->end)
! return;
!
! if (GET_CODE (insn) == CODE_LABEL)
! insn = NEXT_INSN (insn);
/* Scan insn chain and try to find new basic block boundaries. */
! while (1)
{
enum rtx_code code = GET_CODE (insn);
switch (code)
{
case BARRIER:
if (!jump_insn)
abort ();
*************** find_sub_basic_blocks (bb)
*** 753,760 ****
if (jump_insn)
bb->end = jump_insn;
bb = falltru->dest;
! if (barrier)
! remove_edge (falltru);
barrier = 0;
jump_insn = 0;
created = 1;
--- 743,749 ----
if (jump_insn)
bb->end = jump_insn;
bb = falltru->dest;
! remove_edge (falltru);
barrier = 0;
jump_insn = 0;
created = 1;
*************** find_sub_basic_blocks (bb)
*** 762,767 ****
--- 751,757 ----
make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
break;
case INSN:
+ case JUMP_INSN:
/* In case we've previously split insn on the JUMP_INSN, move the
block header to proper place. */
if (jump_insn)
*************** find_sub_basic_blocks (bb)
*** 769,810 ****
falltru = split_block (bb, PREV_INSN (insn));
bb->end = jump_insn;
bb = falltru->dest;
! if (barrier)
! abort ();
jump_insn = 0;
}
default:
break;
}
insn = NEXT_INSN (insn);
}
- /* Last basic block must end in the original BB end. */
- if (jump_insn)
- abort ();
! /* Wire in the original edges for last basic block. */
! if (created)
! {
! bb->succ = succ_list;
! while (succ_list)
! succ_list->src = bb, succ_list = succ_list->succ_next;
! }
! else
! bb->succ = succ_list;
/* Now re-scan and wire in all edges. This expect simple (conditional)
jumps at the end of each new basic blocks. */
! last_bb = bb;
! for (i = first_bb->index; i < last_bb->index; i++)
! {
! bb = BASIC_BLOCK (i);
! if (GET_CODE (bb->end) == JUMP_INSN)
! {
! mark_jump_label (PATTERN (bb->end), bb->end, 0);
! make_label_edge (NULL, bb, JUMP_LABEL (bb->end), 0);
! }
! insn = NEXT_INSN (insn);
! }
}
/* Find all basic blocks of the function whose first insn is F.
--- 759,792 ----
falltru = split_block (bb, PREV_INSN (insn));
bb->end = jump_insn;
bb = falltru->dest;
! remove_edge (falltru);
jump_insn = 0;
}
+ /* We need some special care for those expressions. */
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ if (GET_CODE (PATTERN (insn)) == ADDR_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
+ abort();
+ jump_insn = insn;
+ }
+ break;
default:
break;
}
+ if (insn == end)
+ break;
insn = NEXT_INSN (insn);
}
! /* We've possibly replaced the conditional jump by conditional jump
! followed by cleanup at fallthru edge, so the outgoing edges may
! be dead. */
! purge_dead_edges (bb);
/* Now re-scan and wire in all edges. This expect simple (conditional)
jumps at the end of each new basic blocks. */
! make_edges (NULL, first_bb->index, bb->index - 1);
}
/* Find all basic blocks of the function whose first insn is F.
*************** clear_edges ()
*** 1170,1176 ****
n_edges = 0;
}
! /* Identify the edges between basic blocks.
NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks
that are otherwise unreachable may be reachable with a non-local goto.
--- 1152,1158 ----
n_edges = 0;
}
! /* Identify the edges between basic blocks MIN to MAX.
NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks
that are otherwise unreachable may be reachable with a non-local goto.
*************** clear_edges ()
*** 1179,1186 ****
the list of exception regions active at the end of the basic block. */
static void
! make_edges (label_value_list)
rtx label_value_list;
{
int i;
sbitmap *edge_cache = NULL;
--- 1161,1169 ----
the list of exception regions active at the end of the basic block. */
static void
! make_edges (label_value_list, min, max)
rtx label_value_list;
+ int min, max;
{
int i;
sbitmap *edge_cache = NULL;
*************** make_edges (label_value_list)
*** 1200,1206 ****
/* By nature of the way these get numbered, block 0 is always the entry. */
make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
! for (i = 0; i < n_basic_blocks; ++i)
{
basic_block bb = BASIC_BLOCK (i);
rtx insn, x;
--- 1183,1189 ----
/* By nature of the way these get numbered, block 0 is always the entry. */
make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
! for (i = min; i <= max; ++i)
{
basic_block bb = BASIC_BLOCK (i);
rtx insn, x;