This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cfg_cleanup and loop discovery in cfg_layout mode
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org, rth at redhat dot com,rakdver at atrey dot karlin dot mff dot cuni dot cz
- Date: Wed, 18 Jun 2003 00:38:21 +0200
- Subject: cfg_cleanup and loop discovery in cfg_layout mode
Hi,
this patch enables some use of CFGLAYOUT CFG manipulation rounties.
The modification of cfglayout is not what I would like to over write - in
cfglayout mode the cfgcleanup is much easier to do. In fact we can elliminate
the iteration completely - it is enought to do forwarding pass followed by BB
merging pass follows by dead block removal.
I plan to clean this up separately once I separate out the crossjumping that
will probably take some effort.
I also switched loop code to work entirely in cfglayout mode so the loop
datastructure don't need to be preserved during the initialization of cfglayout
so we can remove poor-man's (mines) micro-cfgcleanup inside cfglayout now.
Bootstrapped/regtested i386/mainline.
Honza
Tue Jun 17 23:27:53 CEST 2003 Jan Hubicka <jh@suse.cz>
* basic-block.h (CLEANUP_CFGLAYOUT): New flag.
* bb-reorder.c (cfg_layout_initialize): Update call.
* cfgcleanup.c (try_optimize_cfg): Supress optimizations of fallthru edges
in cfglayout mode.
* cfglayout.c (cleanup_unconditional_jumps): Kill.
(cfg_layout_initialize): Kill agrument loops; use cfgcleanup.
* cfglayout.h (cfg_layout_initialize): Update prototype.
* cfgloop.h (CP_INSIDE_CFGLAYOUT): Kill.
* cfgloopmanip.c (loop_split_edge_with): Use split_edge.
* flow.c (propagate_block): Do not crash when basic block ends
by first insn in the chain.
* loop-init.c (loop_optimizer_init): First enter cfglayout mode; later
do loop discovery.
* tracer.c (tracer): Update call of cfg_layout_initialize.
*** basic-block.h.old3 Tue Jun 17 17:24:14 2003
--- basic-block.h Tue Jun 17 17:25:11 2003
*************** enum update_life_extent
*** 500,505 ****
--- 500,506 ----
#define CLEANUP_THREADING 64 /* Do jump threading. */
#define CLEANUP_NO_INSN_DEL 128 /* Do not try to delete trivially dead
insns. */
+ #define CLEANUP_CFGLAYOUT 256 /* Do cleanup in cfglayout mode. */
extern void life_analysis PARAMS ((rtx, FILE *, int));
extern int update_life_info PARAMS ((sbitmap, enum update_life_extent,
int));
*** bb-reorder.c.old3 Tue Jun 17 21:07:20 2003
--- bb-reorder.c Tue Jun 17 21:07:23 2003
*************** reorder_basic_blocks ()
*** 1093,1099 ****
if ((* targetm.cannot_modify_jumps_p) ())
return;
! cfg_layout_initialize (NULL);
set_edge_can_fallthru_flag ();
mark_dfs_back_edges ();
--- 1093,1099 ----
if ((* targetm.cannot_modify_jumps_p) ())
return;
! cfg_layout_initialize ();
set_edge_can_fallthru_flag ();
mark_dfs_back_edges ();
*** cfgcleanup.c.old3 Tue Jun 17 17:25:26 2003
--- cfgcleanup.c Tue Jun 17 19:39:54 2003
*************** try_optimize_cfg (mode)
*** 1722,1728 ****
b->index);
delete_block (b);
! changed = true;
b = c;
}
--- 1722,1729 ----
b->index);
delete_block (b);
! if (!(mode & CLEANUP_CFGLAYOUT))
! changed = true;
b = c;
}
*************** try_optimize_cfg (mode)
*** 1756,1762 ****
}
/* If we fall through an empty block, we can remove it. */
! if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& GET_CODE (b->head) != CODE_LABEL
&& FORWARDER_BLOCK_P (b)
--- 1757,1764 ----
}
/* If we fall through an empty block, we can remove it. */
! if (!(mode & CLEANUP_CFGLAYOUT)
! && b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& GET_CODE (b->head) != CODE_LABEL
&& FORWARDER_BLOCK_P (b)
*************** try_optimize_cfg (mode)
*** 1782,1802 ****
&& !(s->flags & EDGE_COMPLEX)
&& (c = s->dest) != EXIT_BLOCK_PTR
&& c->pred->pred_next == NULL
! && b != c
! /* If the jump insn has side effects,
! we can't kill the edge. */
! && (GET_CODE (b->end) != JUMP_INSN
! || (flow2_completed
! ? simplejump_p (b->end)
! : onlyjump_p (b->end)))
! && (next = merge_blocks_move (s, b, c, mode)))
! {
! b = next;
! changed_here = true;
}
/* Simplify branch over branch. */
! if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
changed_here = true;
/* If B has a single outgoing edge, but uses a
--- 1784,1822 ----
&& !(s->flags & EDGE_COMPLEX)
&& (c = s->dest) != EXIT_BLOCK_PTR
&& c->pred->pred_next == NULL
! && b != c)
! {
! /* When not in cfg_layout mode use code aware of reordering
! INSN. This code possibly creates new basic blocks so it
! does not fit merge_blocks interface and is kept here in
! hope that it will become useless once more of compiler
! is transformed to use cfg_layout mode. */
!
! if ((mode & CLEANUP_CFGLAYOUT)
! && can_merge_blocks_p (b, c))
! {
! merge_blocks (b, c);
! update_forwarder_flag (b);
! changed_here = true;
! }
! else if (!(mode & CLEANUP_CFGLAYOUT)
! /* If the jump insn has side effects,
! we can't kill the edge. */
! && (GET_CODE (b->end) != JUMP_INSN
! || (flow2_completed
! ? simplejump_p (b->end)
! : onlyjump_p (b->end)))
! && (next = merge_blocks_move (s, b, c, mode)))
! {
! b = next;
! changed_here = true;
! }
}
/* Simplify branch over branch. */
! if ((mode & CLEANUP_EXPENSIVE)
! && !(mode & CLEANUP_CFGLAYOUT)
! && try_simplify_condjump (b))
changed_here = true;
/* If B has a single outgoing edge, but uses a
*** cfglayout.c.old3 Tue Jun 17 18:12:58 2003
--- cfglayout.c Tue Jun 17 22:24:21 2003
*************** static void set_block_levels PARAMS ((t
*** 54,60 ****
static void change_scope PARAMS ((rtx, tree, tree));
void verify_insn_chain PARAMS ((void));
- static void cleanup_unconditional_jumps PARAMS ((struct loops *));
static void fixup_fallthru_exit_predecessor PARAMS ((void));
static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
static void break_superblocks PARAMS ((void));
--- 54,59 ----
*************** verify_insn_chain ()
*** 803,890 ****
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 (loops)
- struct loops *loops;
- {
- basic_block bb;
-
- FOR_EACH_BB (bb)
- {
- 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)
- && bb->prev_bb != ENTRY_BLOCK_PTR)
- {
- basic_block prev = bb->prev_bb;
-
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "Removing forwarder BB %i\n",
- bb->index);
-
- if (loops)
- {
- /* bb cannot be loop header, as it only has one entry
- edge. It could be a loop latch. */
- if (bb->loop_father->header == bb)
- abort ();
-
- if (bb->loop_father->latch == bb)
- bb->loop_father->latch = bb->pred->src;
-
- if (get_immediate_dominator
- (loops->cfg.dom, bb->succ->dest) == bb)
- set_immediate_dominator
- (loops->cfg.dom, bb->succ->dest, bb->pred->src);
-
- remove_bb_from_loops (bb);
- delete_from_dominance_info (loops->cfg.dom, bb);
- }
-
- redirect_edge_succ_nodup (bb->pred, bb->succ->dest);
- 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;
-
- 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);
-
- 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
--- 830,835 ----
*************** cfg_layout_initialize_rbi (bb)
*** 1151,1158 ****
CFG layout changes. It keeps LOOPS up-to-date if not null. */
void
! cfg_layout_initialize (loops)
! struct loops *loops;
{
basic_block bb;
--- 1096,1102 ----
CFG layout changes. It keeps LOOPS up-to-date if not null. */
void
! cfg_layout_initialize ()
{
basic_block bb;
*************** cfg_layout_initialize (loops)
*** 1166,1174 ****
cfg_layout_rtl_register_cfg_hooks ();
- cleanup_unconditional_jumps (loops);
-
record_effective_endpoints ();
}
/* Splits superblocks. */
--- 1110,1118 ----
cfg_layout_rtl_register_cfg_hooks ();
record_effective_endpoints ();
+
+ cleanup_cfg (CLEANUP_CFGLAYOUT);
}
/* Splits superblocks. */
*** cfglayout.h.old3 Tue Jun 17 21:06:54 2003
--- cfglayout.h Tue Jun 17 21:08:40 2003
*************** typedef struct reorder_block_def
*** 35,41 ****
extern rtx cfg_layout_function_footer;
! extern void cfg_layout_initialize PARAMS ((struct loops *));
extern void cfg_layout_finalize PARAMS ((void));
extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
--- 35,41 ----
extern rtx cfg_layout_function_footer;
! extern void cfg_layout_initialize PARAMS ((void));
extern void cfg_layout_finalize PARAMS ((void));
extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
*** cfgloop.h.old3 Tue Jun 17 21:02:28 2003
--- cfgloop.h Tue Jun 17 21:02:55 2003
*************** extern int fix_loop_placement PARAMS ((
*** 299,306 ****
enum
{
! CP_SIMPLE_PREHEADERS = 1,
! CP_INSIDE_CFGLAYOUT = 2
};
extern void create_preheaders PARAMS ((struct loops *, int));
--- 299,305 ----
enum
{
! CP_SIMPLE_PREHEADERS = 1
};
extern void create_preheaders PARAMS ((struct loops *, int));
*** cfgloopmanip.c.old3 Tue Jun 17 20:50:45 2003
--- cfgloopmanip.c Tue Jun 17 20:58:35 2003
*************** loop_split_edge_with (e, insns, loops)
*** 1497,1527 ****
/* Create basic block for it. */
! new_bb = create_basic_block (NULL_RTX, NULL_RTX, EXIT_BLOCK_PTR->prev_bb);
add_to_dominance_info (loops->cfg.dom, new_bb);
add_bb_to_loop (new_bb, loop_c);
new_bb->flags = insns ? BB_SUPERBLOCK : 0;
! new_e = make_edge (new_bb, dest, EDGE_FALLTHRU);
! new_e->probability = REG_BR_PROB_BASE;
! new_e->count = e->count;
if (e->flags & EDGE_IRREDUCIBLE_LOOP)
{
new_bb->flags |= BB_IRREDUCIBLE_LOOP;
new_e->flags |= EDGE_IRREDUCIBLE_LOOP;
}
- new_bb->count = e->count;
- new_bb->frequency = EDGE_FREQUENCY (e);
- redirect_edge_and_branch_force (e, new_bb);
if (insns)
! {
! start_sequence ();
! emit_insn (insns);
! insns = get_insns ();
! end_sequence ();
! emit_insn_after (insns, new_bb->end);
! }
set_immediate_dominator (loops->cfg.dom, new_bb, src);
set_immediate_dominator (loops->cfg.dom, dest,
--- 1497,1516 ----
/* Create basic block for it. */
! new_bb = split_edge (e);
add_to_dominance_info (loops->cfg.dom, new_bb);
add_bb_to_loop (new_bb, loop_c);
new_bb->flags = insns ? BB_SUPERBLOCK : 0;
! new_e = new_bb->succ;
if (e->flags & EDGE_IRREDUCIBLE_LOOP)
{
new_bb->flags |= BB_IRREDUCIBLE_LOOP;
new_e->flags |= EDGE_IRREDUCIBLE_LOOP;
}
if (insns)
! emit_insn_after (insns, new_bb->end);
set_immediate_dominator (loops->cfg.dom, new_bb, src);
set_immediate_dominator (loops->cfg.dom, dest,
*** flow.c.old3 Tue Jun 17 22:34:27 2003
--- flow.c Tue Jun 17 22:35:17 2003
*************** propagate_block (bb, live, local_set, co
*** 2104,2110 ****
IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
prev = propagate_one_insn (pbi, insn);
! changed |= NEXT_INSN (prev) != insn;
if (insn == bb->head)
break;
--- 2104,2113 ----
IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
prev = propagate_one_insn (pbi, insn);
! if (!prev)
! changed |= insn != get_insns ();
! else
! changed |= NEXT_INSN (prev) != insn;
if (insn == bb->head)
break;
*** loop-init.c.old3 Tue Jun 17 21:03:15 2003
--- loop-init.c Tue Jun 17 21:57:04 2003
*************** loop_optimizer_init (dumpfile)
*** 37,42 ****
--- 37,45 ----
struct loops *loops = xcalloc (1, sizeof (struct loops));
edge e;
+ /* Initialize structures for layout changes. */
+ cfg_layout_initialize ();
+
/* Avoid annoying special cases of edges going to exit
block. */
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
*************** loop_optimizer_init (dumpfile)
*** 47,55 ****
--- 50,65 ----
if (flow_loops_find (loops, LOOP_TREE) <= 1)
{
+ basic_block bb;
+
/* No loops. */
flow_loops_free (loops);
free (loops);
+ /* Make chain. */
+ FOR_EACH_BB (bb)
+ if (bb->next_bb != EXIT_BLOCK_PTR)
+ bb->rbi->next = bb->next_bb;
+ cfg_layout_finalize ();
return NULL;
}
*************** loop_optimizer_init (dumpfile)
*** 59,69 ****
free (loops->cfg.dfs_order);
loops->cfg.dfs_order = NULL;
- /* Initialize structures for layout changes. */
- cfg_layout_initialize (loops);
-
/* Create pre-headers. */
! create_preheaders (loops, CP_SIMPLE_PREHEADERS | CP_INSIDE_CFGLAYOUT);
/* Force all latches to have only single successor. */
force_single_succ_latches (loops);
--- 69,76 ----
free (loops->cfg.dfs_order);
loops->cfg.dfs_order = NULL;
/* Create pre-headers. */
! create_preheaders (loops, CP_SIMPLE_PREHEADERS);
/* Force all latches to have only single successor. */
force_single_succ_latches (loops);
*** tracer.c.old3 Tue Jun 17 17:37:41 2003
--- tracer.c Tue Jun 17 21:08:04 2003
*************** tracer ()
*** 366,372 ****
{
if (n_basic_blocks <= 1)
return;
! cfg_layout_initialize (NULL);
mark_dfs_back_edges ();
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
--- 371,377 ----
{
if (n_basic_blocks <= 1)
return;
! cfg_layout_initialize ();
mark_dfs_back_edges ();
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);