aboutsummaryrefslogtreecommitdiff
path: root/gcc/loop-init.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-03-28 12:14:26 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-03-28 12:14:26 +0000
commit7d776ee2520ce781f671150d8fcd2f6085362b2c (patch)
treea016e8f205f21bb435691b9d07878f5480b9aee9 /gcc/loop-init.c
parent911ba855542ada6e9d1843fe0f0a60097f9ea12e (diff)
downloadgcc-7d776ee2520ce781f671150d8fcd2f6085362b2c.zip
gcc-7d776ee2520ce781f671150d8fcd2f6085362b2c.tar.gz
gcc-7d776ee2520ce781f671150d8fcd2f6085362b2c.tar.bz2
loop-init.c (loop_optimizer_init): If loops are preserved perform incremental initialization of required loop features.
2012-03-28 Richard Guenther <rguenther@suse.de> * loop-init.c (loop_optimizer_init): If loops are preserved perform incremental initialization of required loop features. (loop_optimizer_finalize): If loops are to be preserved only clean up optional loop features. (rtl_loop_done): Forcefully free loops here. * cgraph.c (cgraph_release_function_body): Forcefully free loops. * cfgexpand.c (expand_gimple_cond): Properly add new basic-blocks to existing loops. (construct_init_block): Likewise. (construct_exit_block): Likewise. (gimple_expand_cfg): Clear LOOP_CLOSED_SSA loop state. Cleanup the CFG after expanding. * cfgloop.c (verify_loop_structure): Calculate or verify dominators. If we needed to calculate them, free them afterwards. * tree-pass.h (PROP_loops): New define. * tree-ssa-loop.c (pass_tree_loop_init): Provide PROP_loops. * basic-block.h (CLEANUP_CFG_CHANGED): New. * cfgcleanup.c (merge_blocks_move): Protect loop latches. (cleanup_cfg): If we did something and have loops around, fix them up. * cse.c (rest_of_handle_cse_after_global_opts): Call cleanup_cfg with CLEANUP_CFG_CHANGED. * cfghooks.c (merge_blocks): If we merge a loop header into its predecessor, update the loop structure. (duplicate_block): If we copy a loop latch, adjust loop state to note we may have multiple latches. (delete_basic_block): Mark loops for fixup if we remove a loop. * cfganal.c (forwarder_block_p): Protect loop latches, headers and preheaders. * cfgrtl.c (rtl_can_merge_blocks): Protect loop latches. (cfg_layout_can_merge_blocks_p): Likewise. * cprop.c (bypass_block): If we create a loop with multiple entries, mark it for removal. * except.c (emit_to_new_bb_before): Add the new basic-block to existing loops. * tree-eh.c (lower_resx): Likewise. * omp-low.c (finalize_task_copyfn): Do not copy PROP_loops. (expand_omp_taskreg): Likewise. * tree-inline.c (initialize_cfun): Likewise. * tree-mudflap.c (add_bb_to_loop): Prototype. (mf_build_check_statement_for): Properly add new basic-blocks to existing loops. * tree-ssa-threadupdate.c (thread_block): Mark loops for fixup if we remove a loop. (thread_through_loop_header): Likewise. * trans-mem.c (tm_log_emit_save_or_restores): Properly add new basic-blocks to existing loops. (expand_transaction): Likewise. * Makefile.in (except.o): Add $(CFGLOOP_H). (expr.o): Likewise. (cgraph.o): Likewise. (cprop.o): Likewise. (cfgexpand.o): Likewise. (cfganal.o): Likewise. (trans-mem.o): Likewise. (tree-eh.o): Likewise. From-SVN: r185913
Diffstat (limited to 'gcc/loop-init.c')
-rw-r--r--gcc/loop-init.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index daf5fa0..b8d7b7e 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -42,15 +42,28 @@ along with GCC; see the file COPYING3. If not see
void
loop_optimizer_init (unsigned flags)
{
- struct loops *loops;
+ if (!current_loops)
+ {
+ struct loops *loops = ggc_alloc_cleared_loops ();
+
+ gcc_assert (!(cfun->curr_properties & PROP_loops));
- gcc_assert (!current_loops);
- loops = ggc_alloc_cleared_loops ();
+ /* Find the loops. */
- /* Find the loops. */
+ flow_loops_find (loops);
+ current_loops = loops;
+ }
+ else
+ {
+ gcc_assert (cfun->curr_properties & PROP_loops);
- flow_loops_find (loops);
- current_loops = loops;
+ /* Ensure that the dominators are computed, like flow_loops_find does. */
+ calculate_dominance_info (CDI_DOMINATORS);
+
+#ifdef ENABLE_CHECKING
+ verify_loop_structure ();
+#endif
+ }
if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
{
@@ -104,6 +117,22 @@ loop_optimizer_finalize (void)
struct loop *loop;
basic_block bb;
+ if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
+ release_recorded_exits ();
+
+ /* If we should preserve loop structure, do not free it but clear
+ flags that advanced properties are there as we are not preserving
+ that in full. */
+ if (cfun->curr_properties & PROP_loops)
+ {
+ loops_state_clear (LOOP_CLOSED_SSA
+ | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
+ | LOOPS_HAVE_PREHEADERS
+ | LOOPS_HAVE_SIMPLE_LATCHES
+ | LOOPS_HAVE_FALLTHRU_PREHEADERS);
+ return;
+ }
+
gcc_assert (current_loops != NULL);
FOR_EACH_LOOP (li, loop, 0)
@@ -112,8 +141,6 @@ loop_optimizer_finalize (void)
}
/* Clean up. */
- if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
- release_recorded_exits ();
flow_loops_free (current_loops);
ggc_free (current_loops);
current_loops = NULL;
@@ -200,6 +227,8 @@ struct rtl_opt_pass pass_rtl_loop_init =
static unsigned int
rtl_loop_done (void)
{
+ /* No longer preserve loops, remove them now. */
+ cfun->curr_properties &= ~PROP_loops;
loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
@@ -223,7 +252,7 @@ struct rtl_opt_pass pass_rtl_loop_done =
TV_LOOP, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
- 0, /* properties_destroyed */
+ PROP_loops, /* properties_destroyed */
0, /* todo_flags_start */
TODO_verify_flow
| TODO_verify_rtl_sharing /* todo_flags_finish */