This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
find_many_sub_basic_blocks improvements
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, rth at redhat dot com, dpatel at apple dot com
- Date: Sat, 31 Jan 2004 01:27:18 +0100
- Subject: find_many_sub_basic_blocks improvements
Hi,
This is first change I need for CFG transparent tree expansion.
This patch extends find_many_sub_basic_block to deal with all cases as
find_basic_block_1 did. This include little bit of code duplication in
handling of labels whose address has been taken, but I hope that soonish we
will be able to elliminate find_basic_blocks completely.
Bootstrapped/regtested i686-pc-gnu-linux
OK for mainline?
Honza
* cfgbuild.c (find_bb_boundaries): Add extra argumentl
collect list of labels whose address has been taken
(control_flow_insn_p): Recognize noreturn call instructions
and EH instructions followed by barrier as control flow insns.
Index: cfgbuild.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgbuild.c,v
retrieving revision 1.41
diff -c -3 -p -r1.41 cfgbuild.c
*** cfgbuild.c 11 Dec 2003 00:20:36 -0000 1.41
--- cfgbuild.c 30 Jan 2004 13:16:43 -0000
*************** static rtx find_label_refs (rtx, rtx);
*** 54,60 ****
static void make_edges (rtx, basic_block, basic_block, int);
static void make_label_edge (sbitmap *, basic_block, rtx, int);
static void make_eh_edge (sbitmap *, basic_block, rtx);
- static void find_bb_boundaries (basic_block);
static void compute_outgoing_frequencies (basic_block);
/* Return true if insn is something that should be contained inside basic
--- 54,59 ----
*************** control_flow_insn_p (rtx insn)
*** 109,114 ****
--- 108,115 ----
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
case CALL_INSN:
+ if (find_reg_note (insn, REG_NORETURN, 0))
+ return true;
/* Call insn may return to the nonlocal goto handler. */
return ((nonlocal_goto_handler_labels
&& (0 == (note = find_reg_note (insn, REG_EH_REGION,
*************** control_flow_insn_p (rtx insn)
*** 118,123 ****
--- 119,129 ----
|| can_throw_internal (insn));
case INSN:
+ /* We represent EH manipulation via unspec followed by barrier.
+ Such instruction is control flow instruction even when there is
+ no other clue specifying it. */
+ if (NEXT_INSN (insn) && GET_CODE (NEXT_INSN (insn)) == BARRIER)
+ return true;
return (flag_non_call_exceptions && can_throw_internal (insn));
case BARRIER:
*************** enum state {BLOCK_NEW = 0, BLOCK_ORIGINA
*** 645,654 ****
#define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
/* Scan basic block BB for possible BB boundaries inside the block
! and create new basic blocks in the progress. */
! static void
! find_bb_boundaries (basic_block bb)
{
rtx insn = BB_HEAD (bb);
rtx end = BB_END (bb);
--- 651,663 ----
#define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
/* Scan basic block BB for possible BB boundaries inside the block
! and create new basic blocks in the progress.
! Collect and return a list of labels whose addresses are taken. This
! will be used in make_edges for use with computed gotos. */
!
! static rtx
! find_bb_boundaries (rtx lvl, basic_block bb)
{
rtx insn = BB_HEAD (bb);
rtx end = BB_END (bb);
*************** find_bb_boundaries (basic_block bb)
*** 656,662 ****
edge fallthru = NULL;
if (insn == BB_END (bb))
! return;
if (GET_CODE (insn) == CODE_LABEL)
insn = NEXT_INSN (insn);
--- 665,671 ----
edge fallthru = NULL;
if (insn == BB_END (bb))
! return lvl;
if (GET_CODE (insn) == CODE_LABEL)
insn = NEXT_INSN (insn);
*************** find_bb_boundaries (basic_block bb)
*** 666,671 ****
--- 675,704 ----
{
enum rtx_code code = GET_CODE (insn);
+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ {
+ rtx note;
+
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == REG_LABEL)
+ {
+ rtx lab = XEXP (note, 0), next;
+
+ if ((next = next_nonnote_insn (lab)) != NULL
+ && GET_CODE (next) == JUMP_INSN
+ && (GET_CODE (PATTERN (next)) == ADDR_VEC
+ || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+ ;
+ else if (GET_CODE (lab) == NOTE)
+ ;
+ else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
+ && find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
+ ;
+ else
+ lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
+ }
+ }
+
/* On code label, split current basic block. */
if (code == CODE_LABEL)
{
*************** find_bb_boundaries (basic_block bb)
*** 708,713 ****
--- 741,747 ----
followed by cleanup at fallthru edge, so the outgoing edges may
be dead. */
purge_dead_edges (bb);
+ return lvl;
}
/* Assume that frequency of basic block B is known. Compute frequencies
*************** void
*** 751,756 ****
--- 785,791 ----
find_many_sub_basic_blocks (sbitmap blocks)
{
basic_block bb, min, max;
+ rtx label_value_list = NULL;
FOR_EACH_BB (bb)
SET_STATE (bb,
*************** find_many_sub_basic_blocks (sbitmap bloc
*** 758,764 ****
FOR_EACH_BB (bb)
if (STATE (bb) == BLOCK_TO_SPLIT)
! find_bb_boundaries (bb);
FOR_EACH_BB (bb)
if (STATE (bb) != BLOCK_ORIGINAL)
--- 793,799 ----
FOR_EACH_BB (bb)
if (STATE (bb) == BLOCK_TO_SPLIT)
! label_value_list = find_bb_boundaries (label_value_list, bb);
FOR_EACH_BB (bb)
if (STATE (bb) != BLOCK_ORIGINAL)
*************** find_many_sub_basic_blocks (sbitmap bloc
*** 771,777 ****
/* Now re-scan and wire in all edges. This expect simple (conditional)
jumps at the end of each new basic blocks. */
! make_edges (NULL, min, max, 1);
/* Update branch probabilities. Expect only (un)conditional jumps
to be created with only the forward edges. */
--- 806,812 ----
/* Now re-scan and wire in all edges. This expect simple (conditional)
jumps at the end of each new basic blocks. */
! make_edges (label_value_list, min, max, 1);
/* Update branch probabilities. Expect only (un)conditional jumps
to be created with only the forward edges. */
*************** find_sub_basic_blocks (basic_block bb)
*** 808,814 ****
basic_block next = bb->next_bb;
min = bb;
! find_bb_boundaries (bb);
max = next->prev_bb;
/* Now re-scan and wire in all edges. This expect simple (conditional)
--- 843,849 ----
basic_block next = bb->next_bb;
min = bb;
! find_bb_boundaries (NULL, bb);
max = next->prev_bb;
/* Now re-scan and wire in all edges. This expect simple (conditional)
(find_many_sub_basic_block): Deal correctly with abnormal edges.