diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2006-11-17 12:29:17 +0100 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2006-11-17 11:29:17 +0000 |
commit | 598ec7bdbe0e6e2f7c58961fd0f61e0898a3083e (patch) | |
tree | 194dc21664ec5a698ea4824b9350190e2710fce6 /gcc/cfghooks.c | |
parent | 31198773e456d1a8ecabdd576fa3a9d4412cbf07 (diff) | |
download | gcc-598ec7bdbe0e6e2f7c58961fd0f61e0898a3083e.tar.gz |
tree-vrp.c (execute_vrp): Do not update current_loops.
* tree-vrp.c (execute_vrp): Do not update current_loops.
* loop-unswitch.c (unswitch_loop): Do not use loop_split_edge_with.
* doc/loop.texi: Remove documentation for cancelled functions.
* tree-ssa-loop-im.c (loop_commit_inserts): Removed.
(move_computations, determine_lsm): Use bsi_commit_edge_inserts
instead.
* cfgloopmanip.c (remove_bbs): Do not update loops explicitly.
(remove_path): Ensure that in delete_basic_blocks, the loops
are still allocated.
(add_loop): Work on valid loop structures.
(loopify): Modify call of add_loop.
(mfb_update_loops): Removed.
(create_preheader): Do not update loops explicitly.
(force_single_succ_latches, loop_version): Do not use
loop_split_edge_with.
(loop_split_edge_with): Removed.
* tree-ssa-loop-manip.c (create_iv, determine_exit_conditions):
Do not use bsi_insert_on_edge_immediate_loop.
(split_loop_exit_edge, tree_unroll_loop): Do not use
loop_split_edge_with.
(bsi_insert_on_edge_immediate_loop): Removed.
* tree-ssa-loop-ch.c (copy_loop_headers): Use current_loops. Do not
use loop_split_edge_with.
* cfghooks.c: Include cfgloop.h.
(verify_flow_info): Verify that loop_father is filled iff current_loops
are available.
(redirect_edge_and_branch_force, split_block, delete_basic_block,
split_edge, merge_blocks, make_forwarder_block, duplicate_block):
Update cfg.
* cfgloopanal.c (mark_irreducible_loops): Work if the function contains
no loops.
* modulo-sched.c (generate_prolog_epilog, canon_loop): Do not use
loop_split_edge_with.
(sms_schedule): Use current_loops.
* tree-ssa-dom.c (tree_ssa_dominator_optimize): Use current_loops.
* loop-init.c (loop_optimizer_init, loop_optimizer_finalize): Set
current_loops.
(rtl_loop_init, rtl_loop_done): Do not set current_loops.
* tree-ssa-sink.c (execute_sink_code): Use current_loops.
* ifcvt.c (if_convert): Ditto.
* predict.c (predict_loops): Do not clear current_loops.
(tree_estimate_probability): Use current_loops.
(propagate_freq): Receive head of the region to propagate instead of
loop.
(estimate_loops_at_level): Do not use shared to_visit bitmap.
(estimate_loops): New function. Handle case current_loops == NULL.
(estimate_bb_frequencies): Do not allocate tovisit. Use
estimate_loops.
* tree-ssa-loop.c (current_loops): Removed.
(tree_loop_optimizer_init): Do not return loops.
(tree_ssa_loop_init, tree_ssa_loop_done): Do not set current_loops.
* tree-vectorizer.c (slpeel_update_phi_nodes_for_guard1,
slpeel_update_phi_nodes_for_guard2, slpeel_tree_peel_loop_to_edge):
Do not update loops explicitly.
* function.h (struct function): Add x_current_loops field.
(current_loops): New macro.
* tree-if-conv.c (combine_blocks): Do not update loops explicitly.
* loop-unroll.c (split_edge_and_insert): New function.
(unroll_loop_runtime_iterations, analyze_insns_in_loop): Do not
use loop_split_edge_with.
* loop-doloop.c (add_test, doloop_modify): Ditto.
* tree-ssa-pre.c (init_pre, fini_pre): Do not set current_loops.
* cfglayout.c (copy_bbs): Do not update loops explicitly.
* lambda-code.c (perfect_nestify): Do not use loop_split_edge_with.
* tree-vect-transform.c (vect_transform_loop): Do not update loops
explicitly.
* cfgloop.c (flow_loops_cfg_dump): Do not dump dfs_order and rc_order.
(flow_loops_free): Do not free dfs_order and rc_order.
(flow_loops_find): Do not set dfs_order and rc_order in loops
structure. Do not call loops and flow info verification.
(add_bb_to_loop, remove_bb_from_loops): Check whether the block
already belongs to some loop.
* cfgloop.h (struct loops): Remove struct cfg.
(current_loops, loop_split_edge_with): Declaration removed.
(loop_optimizer_init, loop_optimizer_finalize): Declaration changed.
* tree-flow.h (loop_commit_inserts, bsi_insert_on_edge_immediate_loop):
Declaration removed.
* Makefile.in (cfghooks.o): Add CFGLOOP_H dependency.
* basic-block.h (split_edge_and_insert): Declare.
* tree-cfg.c (remove_bb): Do not update loops explicitly.
From-SVN: r118931
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r-- | gcc/cfghooks.c | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 4d89aea8f5c..0378b13ba80 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -29,6 +29,7 @@ Boston, MA 02110-1301, USA. */ #include "tree-flow.h" #include "timevar.h" #include "toplev.h" +#include "cfgloop.h" /* A pointer to one of the hooks containers. */ static struct cfg_hooks *cfg_hooks; @@ -115,6 +116,18 @@ verify_flow_info (void) edge e; edge_iterator ei; + if (bb->loop_father != NULL && current_loops == NULL) + { + error ("verify_flow_info: Block %i has loop_father, but there are no loops", + bb->index); + err = 1; + } + if (bb->loop_father == NULL && current_loops != NULL) + { + error ("verify_flow_info: Block %i lacks loop_father", bb->index); + err = 1; + } + if (bb->count < 0) { error ("verify_flow_info: Wrong count of block %i %i", @@ -308,12 +321,19 @@ basic_block redirect_edge_and_branch_force (edge e, basic_block dest) { basic_block ret; + struct loop *loop; if (!cfg_hooks->redirect_edge_and_branch_force) internal_error ("%s does not support redirect_edge_and_branch_force", cfg_hooks->name); ret = cfg_hooks->redirect_edge_and_branch_force (e, dest); + if (current_loops != NULL && ret != NULL) + { + loop = find_common_loop (single_pred (ret)->loop_father, + single_succ (ret)->loop_father); + add_bb_to_loop (ret, loop); + } return ret; } @@ -344,6 +364,9 @@ split_block (basic_block bb, void *i) set_immediate_dominator (CDI_DOMINATORS, new_bb, bb); } + if (current_loops != NULL) + add_bb_to_loop (new_bb, bb->loop_father); + return make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU); } @@ -381,6 +404,22 @@ delete_basic_block (basic_block bb) cfg_hooks->delete_basic_block (bb); + if (current_loops != NULL) + { + struct loop *loop = bb->loop_father; + + /* If we remove the header or the latch of a loop, mark the loop for + removal by setting its header and latch to NULL. */ + if (loop->latch == bb + || loop->header == bb) + { + loop->header = NULL; + loop->latch = NULL; + } + + remove_bb_from_loops (bb); + } + /* Remove the edges into and out of this block. Note that there may indeed be edges in, if we are removing an unreachable loop. */ while (EDGE_COUNT (bb->preds) != 0) @@ -407,6 +446,8 @@ split_edge (edge e) int freq = EDGE_FREQUENCY (e); edge f; bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0; + struct loop *loop; + basic_block src = e->src, dest = e->dest; if (!cfg_hooks->split_edge) internal_error ("%s does not support split_edge", cfg_hooks->name); @@ -455,7 +496,16 @@ split_edge (edge e) if (!f) set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret); } - }; + } + + if (current_loops != NULL) + { + loop = find_common_loop (src->loop_father, dest->loop_father); + add_bb_to_loop (ret, loop); + + if (loop->latch == src) + loop->latch = ret; + } return ret; } @@ -534,6 +584,9 @@ merge_blocks (basic_block a, basic_block b) if (!cfg_hooks->merge_blocks) internal_error ("%s does not support merge_blocks", cfg_hooks->name); + if (current_loops != NULL) + remove_bb_from_loops (b); + cfg_hooks->merge_blocks (a, b); /* Normally there should only be one successor of A and that is B, but @@ -575,6 +628,7 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), edge e, fallthru; edge_iterator ei; basic_block dummy, jump; + struct loop *loop, *ploop, *cloop; if (!cfg_hooks->make_forwarder_block) internal_error ("%s does not support make_forwarder_block", @@ -617,6 +671,33 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, 2); } + if (current_loops != NULL) + { + /* If we do not split a loop header, then both blocks belong to the + same loop. In case we split loop header and do not redirect the + latch edge to DUMMY, then DUMMY belongs to the outer loop, and + BB becomes the new header. */ + loop = dummy->loop_father; + if (loop->header == dummy + && find_edge (loop->latch, dummy) == NULL) + { + remove_bb_from_loops (dummy); + loop->header = bb; + + cloop = loop; + FOR_EACH_EDGE (e, ei, dummy->preds) + { + cloop = find_common_loop (cloop, e->src->loop_father); + } + add_bb_to_loop (dummy, cloop); + } + + /* In case we split loop latch, update it. */ + for (ploop = loop; ploop; ploop = ploop->outer) + if (ploop->latch == dummy) + ploop->latch = bb; + } + cfg_hooks->make_forwarder_block (fallthru); return fallthru; @@ -768,6 +849,10 @@ duplicate_block (basic_block bb, edge e, basic_block after) set_bb_original (new_bb, bb); set_bb_copy (bb, new_bb); + /* Add the new block to the prescribed loop. */ + if (current_loops != NULL) + add_bb_to_loop (new_bb, bb->loop_father->copy); + return new_bb; } |