summaryrefslogtreecommitdiff
path: root/gcc/cfghooks.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-28 12:14:26 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-28 12:14:26 +0000
commit79f958cbb1216fb4a56b690b85d8832da4044473 (patch)
treea016e8f205f21bb435691b9d07878f5480b9aee9 /gcc/cfghooks.c
parent58cf0091a5554627bfc2eb67025e0086e0f45d70 (diff)
downloadgcc-79f958cbb1216fb4a56b690b85d8832da4044473.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185913 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r--gcc/cfghooks.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index c4c51cc4404..1dca79a70cf 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -508,6 +508,7 @@ delete_basic_block (basic_block bb)
{
loop->header = NULL;
loop->latch = NULL;
+ loops_state_set (LOOPS_NEED_FIXUP);
}
remove_bb_from_loops (bb);
@@ -682,8 +683,18 @@ merge_blocks (basic_block a, basic_block b)
cfg_hooks->merge_blocks (a, b);
+ /* If we merge a loop header into its predecessor, update the loop
+ structure. */
if (current_loops != NULL)
- remove_bb_from_loops (b);
+ {
+ if (b->loop_father->header == b)
+ {
+ remove_bb_from_loops (a);
+ add_bb_to_loop (a, b->loop_father);
+ a->loop_father->header = a;
+ }
+ remove_bb_from_loops (b);
+ }
/* Normally there should only be one successor of A and that is B, but
partway though the merge of blocks for conditional_execution we'll
@@ -999,6 +1010,18 @@ duplicate_block (basic_block bb, edge e, basic_block after)
struct loop *cloop = bb->loop_father;
struct loop *copy = get_loop_copy (cloop);
add_bb_to_loop (new_bb, copy ? copy : cloop);
+ /* If we copied the loop latch block but not the loop, adjust
+ loop state.
+ ??? If we copied the loop header block but not the loop
+ we might either have created a loop copy or a loop with
+ multiple entries. In both cases we probably have to
+ ditch the loops and arrange for a fixup. */
+ if (!copy
+ && cloop->latch == bb)
+ {
+ cloop->latch = NULL;
+ loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+ }
}
return new_bb;