summaryrefslogtreecommitdiff
path: root/gcc/cfgloopmanip.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-10 08:55:57 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-10 08:55:57 +0000
commit053fdd999453feb09cff376ef51ca167dc432205 (patch)
treef2b46ed67074fdbfd5baaae62b80c6995933ebe7 /gcc/cfgloopmanip.c
parent5a24a79a9ed43d9154273567b60e88b694924c4f (diff)
downloadgcc-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.c99
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);
+}