diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-01-29 07:47:56 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-01-29 07:47:56 +0000 |
commit | 5f5d4cd12a68a2564978c5cbacbae78e7f9f1559 (patch) | |
tree | 075d0d98ba746f488ac4ecf2ecf94a83992aacbc /gcc/cfgloopmanip.c | |
parent | d41dc6f8ad2b5f4e3d1bfd130e7f67dc10a99579 (diff) | |
download | gcc-5f5d4cd12a68a2564978c5cbacbae78e7f9f1559.tar.gz |
* Makefile.in (cfghooks.o): Add TIMEVAR_H and toplev.h dependency.
* basic-block.h (tidy_fallthru_edge, tidy_fallthru_edges, dump_bb,
verify_flow_info): Declaration removed.
* cfg.c (verify_flow_info, dump_bb): Moved to cfghooks.c.
(debug_bb, debug_bb_n): Add argument to dump_bb call.
* cfgcleanup.c (try_simplify_condjump, try_crossjump_to_edge,
try_optimize_cfg, delete_unreachable_blocks): Use delete_basic_block
instead of delete_block.
* cfghooks.c: Include timevar.h and toplev.h.
(cfg_hooks): Define here.
(verify_flow_info, dump_bb): Moved from cfg.c.
(redirect_edge_and_branch, redirect_edge_and_branch_force,
split_block, split_block_after_labels, move_block_after,
delete_basic_block, split_edge, create_basic_block,
create_empty_bb, can_merge_blocks_p, merge_blocks,
make_forwarder_block, tidy_fallthru_edge, tidy_fallthru_edges):
New functions.
* cfghooks.h (struct cfg_hooks): Added fields name,
make_forwarder_block, tidy_fallthru_edge and
move_block_after. Changed type of verify_flow_info, dump_bb,
split_block fields. Renamed cfgh_split_edge and delete_block
fields.
(redirect_edge_and_branch, redirect_edge_and_branch_force,
split_block, delete_block, split_edge, create_basic_block,
can_merge_blocks_p, merge_blocks): Macros removed.
(cfg_hooks): Do not export.
(verify_flow_info, dump_bb, redirect_edge_and_branch,
redirect_edge_and_branch_force, split_block, split_block_after_labels,
move_block_after, delete_basic_block, split_edge, create_basic_block,
create_empty_bb, can_merge_blocks_p, merge_blocks,
make_forwarder_block, tidy_fallthru_edge, tidy_fallthru_edges):
Declare.
(cfg_layout_rtl_cfg_hooks): Declare.
* cfgloop.c (update_latch_info, mfb_keep_just, mfb_keep_nonlatch):
New functions.
(canonicalize_loop_headers): Use new semantics of make_forwarder_block.
(redirect_edge_with_latch_update): Removed.
(make_forwarder_block): Moved to cfghooks.c, semantics changed.
* cfgloopmanip.c (remove_bbs): Do not update dominators here.
* cfgrtl.c (cfg_layout_split_block, rtl_split_block, rtl_dump_bb,
rtl_delete_block, rtl_split_block, rtl_merge_blocks,
tidy_fallthru_edge, rtl_split_edge, cfg_layout_delete_block,
cfg_layout_merge_blocks, cfg_layout_split_edge): Partly moved to
cfghooks.c.
(rtl_create_basic_block): Coding style fix.
(rtl_tidy_fallthru_edge, rtl_move_block_after,
rtl_make_forwarder_block): New functions.
(update_cfg_after_block_merging): Removed.
(rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Fill in new entries.
* flow.c (verify_wide_reg, verify_local_live_at_start): Add argument
to dump_bb.
* ifcvt.c (merge_if_block, find_cond_trap, find_if_case_1,
find_if_case_2): Don't update dominators.
* timevar.def (TV_CFG_VERIFY): New.
* loop-unswitch.c (unswitch_loop): Don't call add_to_dominance_info.
* cfglayout.c (copy_bbs): Don't call add_to_dominance_info.
* cfgloopmanip.c (split_loop_bb): Don't update dominators.
(remove_bbs): Don't call remove_bbs.
(create_preheader): Use make_forwarder_block.
(mfb_keep_just, mfb_update_loops): New static functions.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76851 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r-- | gcc/cfgloopmanip.c | 95 |
1 files changed, 45 insertions, 50 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 86af4a2536b..2c60659fec8 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -63,11 +63,6 @@ split_loop_bb (basic_block bb, rtx insn) /* Add dest to loop. */ add_bb_to_loop (e->dest, e->src->loop_father); - /* Fix dominators. */ - add_to_dominance_info (CDI_DOMINATORS, e->dest); - redirect_immediate_dominators (CDI_DOMINATORS, e->src, e->dest); - set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src); - return e; } @@ -88,8 +83,7 @@ remove_bbs (basic_block *bbs, int nbbs) for (i = 0; i < nbbs; i++) { remove_bb_from_loops (bbs[i]); - delete_from_dominance_info (CDI_DOMINATORS, bbs[i]); - delete_block (bbs[i]); + delete_basic_block (bbs[i]); } } @@ -1070,19 +1064,45 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, return true; } +/* A callback for make_forwarder block, to redirect all edges except for + MFB_KJ_EDGE to the entry part. E is the edge for that we should decide + whether to redirect it. */ + +static edge mfb_kj_edge; +static bool +mfb_keep_just (edge e) +{ + return e != mfb_kj_edge; +} + +/* A callback for make_forwarder block, to update data structures for a basic + block JUMP created by redirecting an edge (only the latch edge is being + redirected). */ + +static void +mfb_update_loops (basic_block jump) +{ + struct loop *loop = jump->succ->dest->loop_father; + + if (dom_computed[CDI_DOMINATORS]) + set_immediate_dominator (CDI_DOMINATORS, jump, jump->pred->src); + add_bb_to_loop (jump, loop); + loop->latch = jump; +} + /* Creates a pre-header for a LOOP. Returns newly created block. Unless CP_SIMPLE_PREHEADERS is set in FLAGS, we only force LOOP to have single entry; otherwise we also force preheader block to have only one successor. - The function also updates dominators stored in DOM. */ + The function also updates dominators. */ + static basic_block create_preheader (struct loop *loop, int flags) { edge e, fallthru; basic_block dummy; - basic_block jump, src = 0; struct loop *cloop, *ploop; int nentry = 0; - rtx insn; + bool irred = false; cloop = loop->outer; @@ -1090,6 +1110,7 @@ create_preheader (struct loop *loop, int flags) { if (e->src == loop->latch) continue; + irred |= (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0; nentry++; } if (!nentry) @@ -1102,17 +1123,9 @@ create_preheader (struct loop *loop, int flags) return NULL; } - insn = first_insn_after_basic_block_note (loop->header); - if (insn) - insn = PREV_INSN (insn); - else - insn = get_last_insn (); - if (insn == BB_END (loop->header)) - { - /* Split_block would not split block after its end. */ - emit_note_after (NOTE_INSN_DELETED, insn); - } - fallthru = split_block (loop->header, insn); + mfb_kj_edge = loop_latch_edge (loop); + fallthru = make_forwarder_block (loop->header, mfb_keep_just, + mfb_update_loops); dummy = fallthru->src; loop->header = fallthru->dest; @@ -1122,35 +1135,22 @@ create_preheader (struct loop *loop, int flags) if (ploop->latch == dummy) ploop->latch = fallthru->dest; - add_to_dominance_info (CDI_DOMINATORS, fallthru->dest); - - /* Redirect edges. */ + /* Reorganize blocks so that the preheader is not stuck in the middle of the + loop. */ for (e = dummy->pred; e; e = e->pred_next) - { - src = e->src; - if (src == loop->latch) - break; - } - if (!e) - abort (); + if (e->src != loop->latch) + break; + move_block_after (dummy, e->src); + + loop->header->loop_father = loop; + add_bb_to_loop (dummy, cloop); - dummy->frequency -= EDGE_FREQUENCY (e); - dummy->count -= e->count; - fallthru->count -= e->count; - jump = redirect_edge_and_branch_force (e, loop->header); - if (jump) + if (irred) { - add_to_dominance_info (CDI_DOMINATORS, jump); - set_immediate_dominator (CDI_DOMINATORS, jump, src); - add_bb_to_loop (jump, loop); - loop->latch = jump; + dummy->flags |= BB_IRREDUCIBLE_LOOP; + dummy->succ->flags |= EDGE_IRREDUCIBLE_LOOP; } - /* Update structures. */ - redirect_immediate_dominators (CDI_DOMINATORS, dummy, loop->header); - set_immediate_dominator (CDI_DOMINATORS, loop->header, dummy); - loop->header->loop_father = loop; - add_bb_to_loop (dummy, cloop); if (rtl_dump_file) fprintf (rtl_dump_file, "Created preheader block for loop %i\n", loop->num); @@ -1212,7 +1212,6 @@ loop_split_edge_with (edge e, rtx insns) /* Create basic block for it. */ new_bb = split_edge (e); - add_to_dominance_info (CDI_DOMINATORS, new_bb); add_bb_to_loop (new_bb, loop_c); new_bb->flags = insns ? BB_SUPERBLOCK : 0; @@ -1226,10 +1225,6 @@ loop_split_edge_with (edge e, rtx insns) if (insns) emit_insn_after (insns, BB_END (new_bb)); - set_immediate_dominator (CDI_DOMINATORS, new_bb, src); - set_immediate_dominator (CDI_DOMINATORS, dest, - recount_dominator (CDI_DOMINATORS, dest)); - if (dest->loop_father->latch == src) dest->loop_father->latch = new_bb; |