diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-10 08:55:57 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-10 08:55:57 +0000 |
commit | 053fdd999453feb09cff376ef51ca167dc432205 (patch) | |
tree | f2b46ed67074fdbfd5baaae62b80c6995933ebe7 /gcc/cfgloopmanip.c | |
parent | 5a24a79a9ed43d9154273567b60e88b694924c4f (diff) | |
download | gcc-053fdd999453feb09cff376ef51ca167dc432205.tar.gz |
* Makefile.in (tree-optimize.o): Add CFGLOOP_H dependence.
* cfgloop.c (flow_loop_nodes_find): Export.
* cfgloop.h (flow_loop_nodes_find, fix_loop_structure):
Declare.
* cfgloopmanip.c (fix_loop_structure): New function.
* predict.c (predict_loops): Clean up the loops information.
* tree-cfg.c (cleanup_tree_cfg_loop): New function.
(tree_can_merge_blocks_p, remove_bb, tree_forwarder_block_p): Respect
loop structure.
* tree-flow.h (cleanup_tree_cfg_loop): Declare.
(rewrite_into_loop_closed_ssa): Declaration changed.
* tree-loop-linear.c (linear_transform_loops): Add argument to
rewrite_into_loop_closed_ssa call.
* tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
* tree-ssa-loop-im.c (move_computations): Ditto.
* tree-ssa-loop.c (tree_loop_optimizer_init): Ditto.
* tree-vectorizer.c (vectorize_loops): Ditto.
* tree-optimize.c: Include cfgloop.h.
(execute_todo): Choose whether to call cleanup_tree_cfg or
cleanup_tree_cfg_loop.
* tree-ssa-loop-ivcanon.c (canonicalize_loop_induction_variables,
(tree_unroll_loops_completely): Enable cleanup_tree_cfg_loop call.
* tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Enable
cleanup_tree_cfg_loop call.
* tree-ssa-loop-manip.c (find_uses_to_rename_bb): New function.
(find_uses_to_rename, rewrite_into_loop_closed_ssa): Support
work on part of cfg.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96232 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r-- | gcc/cfgloopmanip.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 946d09fd234..7405380fb25 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -1372,3 +1372,102 @@ create_loop_notes (void) } flow_loops_free (&loops); } + +/* The structure of LOOPS might have changed. Some loops might get removed + (and their headers and latches were set to NULL), loop exists might get + removed (thus the loop nesting may be wrong), and some blocks and edges + were changed (so the information about bb --> loop mapping does not have + to be correct). But still for the remaining loops the header dominates + the latch, and loops did not get new subloobs (new loops might possibly + get created, but we are not interested in them). Fix up the mess. + + If CHANGED_BBS is not NULL, basic blocks whose loop has changed are + marked in it. */ + +void +fix_loop_structure (struct loops *loops, bitmap changed_bbs) +{ + basic_block bb; + struct loop *loop, *ploop; + unsigned i; + + /* Remove the old bb -> loop mapping. */ + FOR_EACH_BB (bb) + { + bb->aux = (void *) (size_t) bb->loop_father->depth; + bb->loop_father = loops->tree_root; + } + + /* Remove the dead loops from structures. */ + loops->tree_root->num_nodes = n_basic_blocks + 2; + for (i = 1; i < loops->num; i++) + { + loop = loops->parray[i]; + if (!loop) + continue; + + loop->num_nodes = 0; + if (loop->header) + continue; + + while (loop->inner) + { + ploop = loop->inner; + flow_loop_tree_node_remove (ploop); + flow_loop_tree_node_add (loop->outer, ploop); + } + + /* Remove the loop and free its data. */ + flow_loop_tree_node_remove (loop); + loops->parray[loop->num] = NULL; + flow_loop_free (loop); + } + + /* Rescan the bodies of loops, starting from the outermost. */ + loop = loops->tree_root; + while (1) + { + if (loop->inner) + loop = loop->inner; + else + { + while (!loop->next + && loop != loops->tree_root) + loop = loop->outer; + if (loop == loops->tree_root) + break; + + loop = loop->next; + } + + loop->num_nodes = flow_loop_nodes_find (loop->header, loop); + } + + /* Now fix the loop nesting. */ + for (i = 1; i < loops->num; i++) + { + loop = loops->parray[i]; + if (!loop) + continue; + + bb = loop_preheader_edge (loop)->src; + if (bb->loop_father != loop->outer) + { + flow_loop_tree_node_remove (loop); + flow_loop_tree_node_add (bb->loop_father, loop); + } + } + + /* Mark the blocks whose loop has changed. */ + FOR_EACH_BB (bb) + { + if (changed_bbs + && (void *) (size_t) bb->loop_father->depth != bb->aux) + bitmap_set_bit (changed_bbs, bb->index); + + bb->aux = NULL; + } + + mark_single_exit_loops (loops); + mark_irreducible_loops (loops); +} |