summaryrefslogtreecommitdiff
path: root/gcc/cfgloopmanip.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-29 07:47:56 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-29 07:47:56 +0000
commit5f5d4cd12a68a2564978c5cbacbae78e7f9f1559 (patch)
tree075d0d98ba746f488ac4ecf2ecf94a83992aacbc /gcc/cfgloopmanip.c
parentd41dc6f8ad2b5f4e3d1bfd130e7f67dc10a99579 (diff)
downloadgcc-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.c95
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;