cfg merge part 15 - more cfglayout bits
Jan Hubicka
jh@suse.cz
Thu May 9 09:11:00 GMT 2002
Hi,
these support routines are used by the software trace cache implementation.
Basically when cfglayout is in the action, we don't need to have unconditional
jumps in the code at all. There is also new function that marks edges that
can be made fallthru (this includes the "normal" fallthru edges and branches
of reversible conditional jumps).
Honza
Thu May 9 17:24:24 CEST 2002 Jan Hubicka <jh@suse.cz>
Josef Zlomek <zlomek@matfyz.cz>
2002-01-14 Josef Zlomek <zlomek@matfyz.cz>
cfg.c (dump_edge_info): added dumping of EDGE_CAN_FALLTHRU.
bb-reorder.c (find_traces_1_round): fixed bug in computing the
iterations of the loop.
Wed Jan 9 2002 Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz>
* basic-block.h: New flag EDGE_CAN_FALLTHRU
* cfganal.c (set_edge_can_fallthru_flag): New function; marks the edges
that can be made fallthru.
Mon Nov 12 16:25:53 CET 2001 Jan Hubicka <jh@suse.cz>
* cfglayout.c (cleanup_unconditional_jumps): New static function.
(cfg_layout_initialize): Use it.
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.139
diff -c -3 -p -r1.139 basic-block.h
*** basic-block.h 8 May 2002 09:17:16 -0000 1.139
--- basic-block.h 9 May 2002 15:18:16 -0000
*************** typedef struct edge_def {
*** 141,146 ****
--- 141,147 ----
#define EDGE_EH 8
#define EDGE_FAKE 16
#define EDGE_DFS_BACK 32
+ #define EDGE_CAN_FALLTHRU 64
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
*************** extern conflict_graph conflict_graph_com
*** 699,704 ****
--- 700,706 ----
PARAMS ((regset,
partition));
extern bool mark_dfs_back_edges PARAMS ((void));
+ extern void set_edge_can_fallthru_flag PARAMS ((void));
extern void update_br_prob_note PARAMS ((basic_block));
extern void fixup_abnormal_edges PARAMS ((void));
Index: cfganal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfganal.c,v
retrieving revision 1.17
diff -c -3 -p -r1.17 cfganal.c
*** cfganal.c 9 May 2002 12:56:47 -0000 1.17
--- cfganal.c 9 May 2002 15:18:17 -0000
*************** mark_dfs_back_edges ()
*** 189,194 ****
--- 189,224 ----
return found;
}
+ /* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
+
+ void
+ set_edge_can_fallthru_flag ()
+ {
+ int i;
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ edge e;
+
+ /* The FALLTHRU edge is also CAN_FALLTHRU edge. */
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ e->flags |= EDGE_CAN_FALLTHRU;
+
+ /* If the BB ends with an invertable condjump all (2) edges are
+ CAN_FALLTHRU edges. */
+ if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
+ continue;
+ if (!any_condjump_p (bb->end))
+ continue;
+ if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
+ continue;
+ invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
+ bb->succ->flags |= EDGE_CAN_FALLTHRU;
+ bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
+ }
+ }
+
/* Return true if we need to add fake edge to exit.
Helper function for the flow_call_edges_add. */
*************** flow_call_edges_add (blocks)
*** 326,334 ****
/* Note that the following may create a new basic block
and renumber the existing basic blocks. */
! e = split_block (bb, split_at_insn);
! if (e)
! blocks_split++;
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
}
--- 356,367 ----
/* Note that the following may create a new basic block
and renumber the existing basic blocks. */
! if (split_at_insn != bb->end)
! {
! e = split_block (bb, split_at_insn);
! if (e)
! blocks_split++;
! }
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
}
Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfglayout.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 cfglayout.c
*** cfglayout.c 8 May 2002 09:17:17 -0000 1.10
--- cfglayout.c 9 May 2002 15:18:18 -0000
*************** static void set_block_levels PARAMS ((t
*** 46,51 ****
--- 46,52 ----
static void change_scope PARAMS ((rtx, tree, tree));
void verify_insn_chain PARAMS ((void));
+ static void cleanup_unconditional_jumps PARAMS (());
static void fixup_fallthru_exit_predecessor PARAMS ((void));
static rtx unlink_insn_chain PARAMS ((rtx, rtx));
static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
*************** verify_insn_chain ()
*** 578,583 ****
--- 579,654 ----
abort ();
}
+ /* Remove any unconditional jumps and forwarder block creating fallthru
+ edges instead. During BB reordering fallthru edges are not required
+ to target next basic block in the linear CFG layout, so the unconditional
+ jumps are not needed. If LOOPS is not null, also update loop structure &
+ dominators. */
+
+ static void
+ cleanup_unconditional_jumps ()
+ {
+ int i;
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+
+ if (!bb->succ)
+ continue;
+ if (bb->succ->flags & EDGE_FALLTHRU)
+ continue;
+ if (!bb->succ->succ_next)
+ {
+ rtx insn;
+ if (GET_CODE (bb->head) != CODE_LABEL && forwarder_block_p (bb) && i)
+ {
+ basic_block prev = BASIC_BLOCK (--i);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Removing forwarder BB %i\n",
+ bb->index);
+
+ redirect_edge_succ (bb->pred, bb->succ->dest);
+ flow_delete_block (bb);
+ bb = prev;
+ }
+ else if (simplejump_p (bb->end))
+ {
+ rtx jump = bb->end;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Removing jump %i in BB %i\n",
+ INSN_UID (jump), bb->index);
+ delete_insn (jump);
+ bb->succ->flags |= EDGE_FALLTHRU;
+ }
+ else
+ continue;
+
+ /* Cleanup barriers and delete ADDR_VECs in a way as they are belonging
+ to removed tablejump anyway. */
+ insn = NEXT_INSN (bb->end);
+ while (insn
+ && (GET_CODE (insn) != NOTE
+ || NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
+ {
+ rtx next = NEXT_INSN (insn);
+
+ if (GET_CODE (insn) == BARRIER)
+ delete_barrier (insn);
+ else if (GET_CODE (insn) == JUMP_INSN)
+ delete_insn_chain (PREV_INSN (insn), insn);
+ else if (GET_CODE (insn) == CODE_LABEL)
+ ;
+ else if (GET_CODE (insn) != NOTE)
+ abort ();
+
+ insn = next;
+ }
+ }
+ }
+ }
+
/* The block falling through to exit must be the last one in the
reordered chain. Ensure that this condition is met. */
static void
*************** cfg_layout_redirect_edge (e, dest)
*** 767,772 ****
--- 838,851 ----
}
else
redirect_edge_and_branch (e, dest);
+
+ /* We don't want simplejumps in the insn stream during cfglayout. */
+ if (simplejump_p (src->end))
+ {
+ delete_insn (src->end);
+ delete_barrier (NEXT_INSN (src->end));
+ src->succ->flags |= EDGE_FALLTHRU;
+ }
dest->index = old_index;
}
*************** cfg_layout_initialize ()
*** 867,872 ****
--- 946,953 ----
/* Our algorithm depends on fact that there are now dead jumptables
around the code. */
alloc_aux_for_blocks (sizeof (struct reorder_block_def));
+
+ cleanup_unconditional_jumps ();
scope_to_insns_initialize ();
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgrtl.c,v
retrieving revision 1.43
diff -c -3 -p -r1.43 cfgrtl.c
*** cfgrtl.c 9 May 2002 12:56:47 -0000 1.43
--- cfgrtl.c 9 May 2002 15:18:19 -0000
*************** verify_flow_info ()
*** 1830,1836 ****
if (e->flags & EDGE_FALLTHRU)
n_fallthru++;
! if ((e->flags & ~EDGE_DFS_BACK) == 0)
n_branch++;
if (e->flags & EDGE_ABNORMAL_CALL)
--- 1830,1836 ----
if (e->flags & EDGE_FALLTHRU)
n_fallthru++;
! if ((e->flags & ~(EDGE_DFS_BACK | EDGE_CAN_FALLTHRU)) == 0)
n_branch++;
if (e->flags & EDGE_ABNORMAL_CALL)
Index: cfg.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfg.c,v
retrieving revision 1.23
retrieving revision 1.16.2.10
diff -c -3 -p -r1.23 -r1.16.2.10
*** cfg.c 10 Apr 2002 00:15:58 -0000 1.23
--- cfg.c 16 Apr 2002 18:14:28 -0000 1.16.2.10
*************** dump_edge_info (file, e, do_succ)
*** 609,615 ****
if (e->flags)
{
static const char * const bitnames[]
! = {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back"};
int comma = 0;
int i, flags = e->flags;
--- 619,625 ----
if (e->flags)
{
static const char * const bitnames[]
! = {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
int comma = 0;
int i, flags = e->flags;
More information about the Gcc-patches
mailing list