aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-cfg.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2005-03-10 09:55:57 +0100
committerZdenek Dvorak <rakdver@gcc.gnu.org>2005-03-10 08:55:57 +0000
commit2b271002241ca01925b19d586ff2f30ce797d380 (patch)
treef2b46ed67074fdbfd5baaae62b80c6995933ebe7 /gcc/tree-cfg.c
parent17049f0bbb41269470981caefa6d05fd3c26b47b (diff)
downloadgcc-2b271002241ca01925b19d586ff2f30ce797d380.zip
gcc-2b271002241ca01925b19d586ff2f30ce797d380.tar.gz
gcc-2b271002241ca01925b19d586ff2f30ce797d380.tar.bz2
Makefile.in (tree-optimize.o): Add CFGLOOP_H dependence.
* 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. From-SVN: r96232
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r--gcc/tree-cfg.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index be7ee56b..c9a8e31 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -959,6 +959,30 @@ cleanup_tree_cfg (void)
}
+/* Cleanup cfg and repair loop structures. */
+
+void
+cleanup_tree_cfg_loop (void)
+{
+ bitmap changed_bbs = BITMAP_ALLOC (NULL);
+
+ cleanup_tree_cfg ();
+
+ fix_loop_structure (current_loops, changed_bbs);
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* This usually does nothing. But sometimes parts of cfg that originally
+ were inside a loop get out of it due to edge removal (since they
+ become unreachable by back edges from latch). */
+ rewrite_into_loop_closed_ssa (changed_bbs);
+
+ BITMAP_FREE (changed_bbs);
+
+#ifdef ENABLE_CHECKING
+ verify_loop_structure (current_loops);
+#endif
+}
+
/* Cleanup useless labels in basic blocks. This is something we wish
to do early because it allows us to group case labels before creating
the edges for the CFG, and it speeds up block statement iterators in
@@ -1277,6 +1301,11 @@ tree_can_merge_blocks_p (basic_block a, basic_block b)
return false;
}
+ /* Protect the loop latches. */
+ if (current_loops
+ && b->loop_father->latch == b)
+ return false;
+
return true;
}
@@ -2045,6 +2074,20 @@ remove_bb (basic_block bb)
}
}
+ /* 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 (current_loops)
+ {
+ struct loop *loop = bb->loop_father;
+
+ if (loop->latch == bb
+ || loop->header == bb)
+ {
+ loop->latch = NULL;
+ loop->header = NULL;
+ }
+ }
+
/* Remove all the instructions in the block. */
for (i = bsi_start (bb); !bsi_end_p (i);)
{
@@ -4099,6 +4142,18 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
if (find_edge (ENTRY_BLOCK_PTR, bb))
return false;
+ if (current_loops)
+ {
+ basic_block dest;
+ /* Protect loop latches, headers and preheaders. */
+ if (bb->loop_father->header == bb)
+ return false;
+ dest = EDGE_SUCC (bb, 0)->dest;
+
+ if (dest->loop_father->header == dest)
+ return false;
+ }
+
return true;
}