The following patch makes us create and preserves loops from the point we build the CFG. As-is the patch passes bootstrap on x86_64-unknown-linux-gnu for all languages including Ada and has no ICEs running the testsuite. There are a few testcases that fail which I still have to investigate.
I tried to properly outline the loop tree on SESE region outlining (used by OMP and auto-par), I have a followup patch for that but it's complicated by the fact that OMP doesn't preserve loops enough to do things fancy and autopar wanting to verify loops after each loop outlined (and I don't want to remove that or forcefully fixup loops all the time). So I need more time on that bit. Anyway, good enough for comments at least (I'm currently checking if the tree-sra bits are still necessary). One change with the patch is that loop fixup can be delayed until the next loop_optimzer_init call which means that passes looking at the loop tree but not calling loop_optimizer_init need to watch out for all sorts of oddities in the loop tree. Generally you are expected to call loop_optimizer_init in such case. Any comments? In the final version of the patch (or maybe incrementally) I'd like to drop PROP_loops, not compute loops at CFG build but at first loop_optimizer_init and make loop_optimizer_finalize not free current_loops (but only drop to the most basic set of loop tree state). I'd also eventually drop most explicit calls to fixup_loop_structure (given lazy handling in loop_optimizer_init). Richard. 2013-03-19 Richard Biener <rguent...@suse.de> * tree-cfg.c (execute_build_cfg): Build the loop tree. (pass_build_cfg): Provide PROP_loops. (move_sese_region_to_fn): Remove loops that are outlined into fn for now. * tree-inline.c: Include cfgloop.h. (initialize_cfun): Do not drop PROP_loops. (copy_loops): New function. (copy_cfg_body): Copy loop structure. (tree_function_versioning): Initialize destination loop tree. ??? * tree-sra.c (modify_function): Always cleanup the CFG (and fix loops). * tree-ssa-loop.c (pass_tree_loop_init): Do not provide PROP_loops. * loop-init.c (loop_optimizer_init): Fixup loops if required. * tree-optimize.c (execute_fixup_cfg): If we need to cleanup the CFG make sure we fixup loops as well. * tree-ssa-tail-merge.c: Include cfgloop.h. (find_same_succ_bb): Avoid merging loop latches with anything. * lto-streamer-out.c (output_struct_function_base): Drop PROP_loops for now. * tree-ssa-phiopt.c: Include tree-scalar-evolution.h. (tree_ssa_cs_elim): Initialize the loop optimizer and SCEV. * ipa-split.c: Include cfgloop.h. (split_function): Add the new return block to the loop tree root. * tree-cfgcleanup.c (remove_forwarder_block_with_phi): Return whether we have removed the forwarder block. (merge_phi_nodes): If we removed a forwarder fixup loops. * cfgloop.h (place_new_loop): Declare. * cfgloopmanip.c (place_new_loop): Export. * Makefile.in (asan.o): Add $(CFGLOOP_H) dependency. (tree-switch-conversion.o): Likewise. (tree-complex.o): Likewise. (tree-inline.o): Likewise. (tree-ssa-tailmerge.o): Likewise. (ipa-split.o): Likewise. (tree-ssa-phiopt.o): Add $(SCEV_H) dependency. * tree-switch-conversion.c: Include cfgloop.h (process_switch): If we emit a bit-test cascade, schedule loops for fixup. * tree-complex.c: Include cfgloop.h. (expand_complex_div_wide): Properly add new basic-blocks to loops. * asan.c: Include cfgloop.h. (create_cond_insert_point): Properly add new basic-blocks to loops, schedule loop fixup. * omp-low.c (expand_parallel_call): Properly add new basic-blocks to loops. (expand_omp_for_generic): Likewise. (expand_omp_sections): Likewise. (expand_omp_atomic_pipeline): Schedule loops for fixup. Index: trunk/gcc/tree-cfg.c =================================================================== *** trunk.orig/gcc/tree-cfg.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-cfg.c 2013-04-24 16:05:54.972456799 +0200 *************** execute_build_cfg (void) *** 220,225 **** --- 220,227 ---- fprintf (dump_file, "Scope blocks:\n"); dump_scope_blocks (dump_file, dump_flags); } + cleanup_tree_cfg (); + loop_optimizer_init (AVOID_CFG_MODIFICATIONS); return 0; } *************** struct gimple_opt_pass pass_build_cfg = *** 236,245 **** 0, /* static_pass_number */ TV_TREE_CFG, /* tv_id */ PROP_gimple_leh, /* properties_required */ ! PROP_cfg, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_stmts | TODO_cleanup_cfg /* todo_flags_finish */ } }; --- 238,247 ---- 0, /* static_pass_number */ TV_TREE_CFG, /* tv_id */ PROP_gimple_leh, /* properties_required */ ! PROP_cfg | PROP_loops, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_stmts /* todo_flags_finish */ } }; *************** move_sese_region_to_fn (struct function *** 6728,6733 **** --- 6730,6747 ---- d.eh_map = eh_map; d.remap_decls_p = true; + /* Cancel all loops inside the SESE region. + ??? We rely on loop fixup because loop structure is not 100% + up-to-date when called from OMP lowering and thus cancel_loop_tree + will not work. + ??? Properly move loops to the outlined function. */ + FOR_EACH_VEC_ELT (bbs, i, bb) + if (bb->loop_father->header == bb) + { + bb->loop_father->header = NULL; + bb->loop_father->latch = NULL; + loops_state_set (LOOPS_NEED_FIXUP); + } FOR_EACH_VEC_ELT (bbs, i, bb) { /* No need to update edge counts on the last block. It has Index: trunk/gcc/tree-inline.c =================================================================== *** trunk.orig/gcc/tree-inline.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-inline.c 2013-04-24 10:21:37.797474905 +0200 *************** along with GCC; see the file COPYING3. *** 47,52 **** --- 47,53 ---- #include "value-prof.h" #include "tree-pass.h" #include "target.h" + #include "cfgloop.h" #include "rtl.h" /* FIXME: For asm_str_count. */ *************** initialize_cfun (tree new_fndecl, tree c *** 2092,2098 **** cfun->static_chain_decl = src_cfun->static_chain_decl; cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area; cfun->function_end_locus = src_cfun->function_end_locus; ! cfun->curr_properties = src_cfun->curr_properties & ~PROP_loops; cfun->last_verified = src_cfun->last_verified; cfun->va_list_gpr_size = src_cfun->va_list_gpr_size; cfun->va_list_fpr_size = src_cfun->va_list_fpr_size; --- 2093,2099 ---- cfun->static_chain_decl = src_cfun->static_chain_decl; cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area; cfun->function_end_locus = src_cfun->function_end_locus; ! cfun->curr_properties = src_cfun->curr_properties; cfun->last_verified = src_cfun->last_verified; cfun->va_list_gpr_size = src_cfun->va_list_gpr_size; cfun->va_list_fpr_size = src_cfun->va_list_fpr_size; *************** maybe_move_debug_stmts_to_successors (co *** 2197,2202 **** --- 2198,2242 ---- } } + /* Make a copy of the sub-loops of SRC_PARENT and place them + as siblings of DEST_PARENT. */ + + static void + copy_loops (bitmap blocks_to_copy, + struct loop *dest_parent, struct loop *src_parent) + { + struct loop *src_loop = src_parent->inner; + while (src_loop) + { + if (!blocks_to_copy + || bitmap_bit_p (blocks_to_copy, src_loop->header->index)) + { + struct loop *dest_loop = alloc_loop (); + + /* Assign the new loop its header and latch and associate + those with the new loop. */ + dest_loop->header = (basic_block)src_loop->header->aux; + dest_loop->header->loop_father = dest_loop; + if (src_loop->latch != NULL) + { + dest_loop->latch = (basic_block)src_loop->latch->aux; + dest_loop->latch->loop_father = dest_loop; + } + + /* Copy loop meta-data. */ + copy_loop_info (src_loop, dest_loop); + + /* Finally place it into the loop array and the loop tree. */ + place_new_loop (dest_loop); + flow_loop_tree_node_add (dest_parent, dest_loop); + + /* Recurse. */ + copy_loops (blocks_to_copy, dest_loop, src_loop); + } + src_loop = src_loop->next; + } + } + /* Make a copy of the body of FN so that it can be inserted inline in another function. Walks FN via CFG, returns new fndecl. */ *************** copy_cfg_body (copy_body_data * id, gcov *** 2274,2279 **** --- 2314,2320 ---- basic_block new_bb = copy_bb (id, bb, frequency_scale, count_scale); bb->aux = new_bb; new_bb->aux = bb; + new_bb->loop_father = entry_block_map->loop_father; } last = last_basic_block; *************** copy_cfg_body (copy_body_data * id, gcov *** 2294,2299 **** --- 2335,2350 ---- e->count = incoming_count; } + /* Duplicate the loop tree, if available and wanted. */ + if (id->src_cfun->x_current_loops != NULL + && current_loops != NULL) + { + copy_loops (blocks_to_copy, entry_block_map->loop_father, + id->src_cfun->x_current_loops->tree_root); + /* Defer to cfgcleanup to update loop-father fields of basic-blocks. */ + loops_state_set (LOOPS_NEED_FIXUP); + } + if (gimple_in_ssa_p (cfun)) FOR_ALL_BB_FN (bb, cfun_to_copy) if (!blocks_to_copy *************** tree_function_versioning (tree old_decl, *** 5151,5156 **** --- 5202,5215 ---- } } + /* Set up the destination functions loop tree. */ + if (DECL_STRUCT_FUNCTION (old_decl)->x_current_loops) + { + cfun->curr_properties &= ~PROP_loops; + loop_optimizer_init (AVOID_CFG_MODIFICATIONS); + cfun->curr_properties |= PROP_loops; + } + /* Copy the Function's body. */ copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, blocks_to_copy, new_entry); Index: trunk/gcc/tree-sra.c =================================================================== *** trunk.orig/gcc/tree-sra.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-sra.c 2013-04-24 10:21:37.798474915 +0200 *************** modify_function (struct cgraph_node *nod *** 4854,4860 **** sra_ipa_reset_debug_stmts (adjustments); convert_callers (new_node, node->symbol.decl, adjustments); cgraph_make_node_local (new_node); ! return cfg_changed; } /* Return false the function is apparently unsuitable for IPA-SRA based on it's --- 4854,4860 ---- sra_ipa_reset_debug_stmts (adjustments); convert_callers (new_node, node->symbol.decl, adjustments); cgraph_make_node_local (new_node); ! return cfg_changed | true; } /* Return false the function is apparently unsuitable for IPA-SRA based on it's Index: trunk/gcc/tree-ssa-loop.c =================================================================== *** trunk.orig/gcc/tree-ssa-loop.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-ssa-loop.c 2013-04-24 10:21:37.798474915 +0200 *************** struct gimple_opt_pass pass_tree_loop_in *** 93,99 **** 0, /* static_pass_number */ TV_NONE, /* tv_id */ PROP_cfg, /* properties_required */ ! PROP_loops, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ 0 /* todo_flags_finish */ --- 93,99 ---- 0, /* static_pass_number */ TV_NONE, /* tv_id */ PROP_cfg, /* properties_required */ ! 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ 0 /* todo_flags_finish */ Index: trunk/gcc/loop-init.c =================================================================== *** trunk.orig/gcc/loop-init.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/loop-init.c 2013-04-24 10:21:37.798474915 +0200 *************** loop_optimizer_init (unsigned flags) *** 91,106 **** } else { gcc_assert (cfun->curr_properties & PROP_loops); /* Ensure that the dominators are computed, like flow_loops_find does. */ calculate_dominance_info (CDI_DOMINATORS); #ifdef ENABLE_CHECKING ! verify_loop_structure (); #endif /* Clear all flags. */ loops_state_clear (~0U); } --- 91,117 ---- } else { + bool recorded_exits = loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS); + gcc_assert (cfun->curr_properties & PROP_loops); /* Ensure that the dominators are computed, like flow_loops_find does. */ calculate_dominance_info (CDI_DOMINATORS); + if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) + { + loops_state_clear (~0U); + fix_loop_structure (NULL); + } + #ifdef ENABLE_CHECKING ! else ! verify_loop_structure (); #endif /* Clear all flags. */ + if (recorded_exits) + release_recorded_exits (); loops_state_clear (~0U); } Index: trunk/gcc/tree-optimize.c =================================================================== *** trunk.orig/gcc/tree-optimize.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-optimize.c 2013-04-24 12:39:50.382355309 +0200 *************** execute_fixup_cfg (void) *** 204,209 **** --- 204,213 ---- if (dump_file) gimple_dump_cfg (dump_file, dump_flags); + if (current_loops + && (todo & TODO_cleanup_cfg)) + loops_state_set (LOOPS_NEED_FIXUP); + return todo; } Index: trunk/gcc/tree-ssa-tail-merge.c =================================================================== *** trunk.orig/gcc/tree-ssa-tail-merge.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-ssa-tail-merge.c 2013-04-24 10:21:37.799474926 +0200 *************** along with GCC; see the file COPYING3. *** 197,202 **** --- 197,203 ---- #include "gimple-pretty-print.h" #include "tree-ssa-sccvn.h" #include "tree-dump.h" + #include "cfgloop.h" /* ??? This currently runs as part of tree-ssa-pre. Why is this not a stand-alone GIMPLE pass? */ *************** find_same_succ_bb (basic_block bb, same_ *** 688,694 **** edge_iterator ei; edge e; ! if (bb == NULL) return; bitmap_set_bit (same->bbs, bb->index); FOR_EACH_EDGE (e, ei, bb->succs) --- 689,697 ---- edge_iterator ei; edge e; ! if (bb == NULL ! || (current_loops ! && bb->loop_father->latch == bb)) return; bitmap_set_bit (same->bbs, bb->index); FOR_EACH_EDGE (e, ei, bb->succs) Index: trunk/gcc/lto-streamer-out.c =================================================================== *** trunk.orig/gcc/lto-streamer-out.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/lto-streamer-out.c 2013-04-24 10:21:37.799474926 +0200 *************** output_struct_function_base (struct outp *** 734,741 **** FOR_EACH_VEC_SAFE_ELT (fn->local_decls, i, t) stream_write_tree (ob, t, true); ! /* Output current IL state of the function. */ ! streamer_write_uhwi (ob, fn->curr_properties); /* Write all the attributes for FN. */ bp = bitpack_create (ob->main_stream); --- 734,742 ---- FOR_EACH_VEC_SAFE_ELT (fn->local_decls, i, t) stream_write_tree (ob, t, true); ! /* Output current IL state of the function. ! ??? We don't stream loops. */ ! streamer_write_uhwi (ob, fn->curr_properties & ~PROP_loops); /* Write all the attributes for FN. */ bp = bitpack_create (ob->main_stream); Index: trunk/gcc/tree-ssa-phiopt.c =================================================================== *** trunk.orig/gcc/tree-ssa-phiopt.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-ssa-phiopt.c 2013-04-24 10:21:37.799474926 +0200 *************** along with GCC; see the file COPYING3. *** 37,42 **** --- 37,43 ---- #include "insn-config.h" #include "expr.h" #include "optabs.h" + #include "tree-scalar-evolution.h" #ifndef HAVE_conditional_move #define HAVE_conditional_move (0) *************** tree_ssa_phiopt (void) *** 241,247 **** static unsigned int tree_ssa_cs_elim (void) { ! return tree_ssa_phiopt_worker (true, false); } /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */ --- 242,257 ---- static unsigned int tree_ssa_cs_elim (void) { ! unsigned todo; ! /* ??? We are not interested in loop related info, but the following ! will create it, ICEing as we didn't init loops with pre-headers. ! An interfacing issue of find_data_references_in_bb. */ ! loop_optimizer_init (LOOPS_NORMAL); ! scev_initialize (); ! todo = tree_ssa_phiopt_worker (true, false); ! scev_finalize (); ! loop_optimizer_finalize (); ! return todo; } /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */ Index: trunk/gcc/ipa-split.c =================================================================== *** trunk.orig/gcc/ipa-split.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/ipa-split.c 2013-04-24 10:21:37.800474936 +0200 *************** along with GCC; see the file COPYING3. *** 90,95 **** --- 90,96 ---- #include "params.h" #include "gimple-pretty-print.h" #include "ipa-inline.h" + #include "cfgloop.h" /* Per basic block info. */ *************** split_function (struct split_point *spli *** 1131,1136 **** --- 1132,1139 ---- e = make_edge (new_return_bb, EXIT_BLOCK_PTR, 0); e->probability = REG_BR_PROB_BASE; e->count = new_return_bb->count; + if (current_loops) + add_bb_to_loop (new_return_bb, current_loops->tree_root); bitmap_set_bit (split_point->split_bbs, new_return_bb->index); } /* When we pass around the value, use existing return block. */ Index: trunk/gcc/tree-cfgcleanup.c =================================================================== *** trunk.orig/gcc/tree-cfgcleanup.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-cfgcleanup.c 2013-04-24 10:21:37.800474936 +0200 *************** cleanup_tree_cfg (void) *** 748,756 **** return changed; } ! /* Merge the PHI nodes at BB into those at BB's sole successor. */ ! static void remove_forwarder_block_with_phi (basic_block bb) { edge succ = single_succ_edge (bb); --- 748,757 ---- return changed; } ! /* Tries to merge the PHI nodes at BB into those at BB's sole successor. ! Returns true if successful. */ ! static bool remove_forwarder_block_with_phi (basic_block bb) { edge succ = single_succ_edge (bb); *************** remove_forwarder_block_with_phi (basic_b *** 762,768 **** However it may happen that the infinite loop is created afterwards due to removal of forwarders. */ if (dest == bb) ! return; /* If the destination block consists of a nonlocal label, do not merge it. */ --- 763,769 ---- However it may happen that the infinite loop is created afterwards due to removal of forwarders. */ if (dest == bb) ! return false; /* If the destination block consists of a nonlocal label, do not merge it. */ *************** remove_forwarder_block_with_phi (basic_b *** 770,776 **** if (label && gimple_code (label) == GIMPLE_LABEL && DECL_NONLOCAL (gimple_label_label (label))) ! return; /* Redirect each incoming edge to BB to DEST. */ while (EDGE_COUNT (bb->preds) > 0) --- 771,777 ---- if (label && gimple_code (label) == GIMPLE_LABEL && DECL_NONLOCAL (gimple_label_label (label))) ! return false; /* Redirect each incoming edge to BB to DEST. */ while (EDGE_COUNT (bb->preds) > 0) *************** remove_forwarder_block_with_phi (basic_b *** 859,864 **** --- 860,867 ---- /* Remove BB since all of BB's incoming edges have been redirected to DEST. */ delete_basic_block (bb); + + return true; } /* This pass merges PHI nodes if one feeds into another. For example, *************** merge_phi_nodes (void) *** 960,972 **** } /* Now let's drain WORKLIST. */ while (current != worklist) { bb = *--current; ! remove_forwarder_block_with_phi (bb); } - free (worklist); return 0; } --- 963,985 ---- } /* Now let's drain WORKLIST. */ + bool changed = false; while (current != worklist) { bb = *--current; ! changed |= remove_forwarder_block_with_phi (bb); } free (worklist); + + /* Removing forwarder blocks can cause formerly irreducible loops + to become reducible if we merged two entry blocks. */ + if (changed + && current_loops) + { + calculate_dominance_info (CDI_DOMINATORS); + fix_loop_structure (NULL); + } + return 0; } Index: trunk/gcc/cfgloop.h =================================================================== *** trunk.orig/gcc/cfgloop.h 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/cfgloop.h 2013-04-24 10:21:37.800474936 +0200 *************** void rescan_loop_exit (edge, bool, bool) *** 232,237 **** --- 232,238 ---- /* Loop data structure manipulation/querying. */ extern void flow_loop_tree_node_add (struct loop *, struct loop *); extern void flow_loop_tree_node_remove (struct loop *); + extern void place_new_loop (struct loop *); extern void add_loop (struct loop *, struct loop *); extern bool flow_loop_nested_p (const struct loop *, const struct loop *); extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block); Index: trunk/gcc/cfgloopmanip.c =================================================================== *** trunk.orig/gcc/cfgloopmanip.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/cfgloopmanip.c 2013-04-24 10:21:37.800474936 +0200 *************** remove_path (edge e) *** 410,416 **** /* Creates place for a new LOOP in loops structure. */ ! static void place_new_loop (struct loop *loop) { loop->num = number_of_loops (); --- 410,416 ---- /* Creates place for a new LOOP in loops structure. */ ! void place_new_loop (struct loop *loop) { loop->num = number_of_loops (); Index: trunk/gcc/Makefile.in =================================================================== *** trunk.orig/gcc/Makefile.in 2013-04-24 10:09:08.000000000 +0200 --- trunk/gcc/Makefile.in 2013-04-24 16:26:58.107407462 +0200 *************** tree-dump.o: tree-dump.c $(CONFIG_H) $(S *** 2224,2230 **** tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(RTL_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \ $(HASHTAB_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \ ! intl.h $(FUNCTION_H) $(GIMPLE_H) \ debug.h $(DIAGNOSTIC_H) $(EXCEPT_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \ $(IPA_PROP_H) value-prof.h $(TREE_PASS_H) $(TARGET_H) \ $(TREE_PRETTY_PRINT_H) --- 2224,2230 ---- tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(RTL_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \ $(HASHTAB_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \ ! intl.h $(FUNCTION_H) $(GIMPLE_H) $(CFGLOOP_H) \ debug.h $(DIAGNOSTIC_H) $(EXCEPT_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \ $(IPA_PROP_H) value-prof.h $(TREE_PASS_H) $(TARGET_H) \ $(TREE_PRETTY_PRINT_H) *************** stor-layout.o : stor-layout.c $(CONFIG_H *** 2236,2242 **** $(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \ $(DIAGNOSTIC_CORE_H) $(CGRAPH_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(GIMPLE_H) asan.o : asan.c asan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \ ! output.h coretypes.h $(GIMPLE_PRETTY_PRINT_H) \ tree-iterator.h $(TREE_FLOW_H) $(TREE_PASS_H) \ $(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) langhooks.h \ $(HASH_TABLE_H) alloc-pool.h --- 2236,2242 ---- $(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \ $(DIAGNOSTIC_CORE_H) $(CGRAPH_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(GIMPLE_H) asan.o : asan.c asan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \ ! output.h coretypes.h $(GIMPLE_PRETTY_PRINT_H) $(CFGLOOP_H) \ tree-iterator.h $(TREE_FLOW_H) $(TREE_PASS_H) \ $(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) langhooks.h \ $(HASH_TABLE_H) alloc-pool.h *************** tsan.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_ *** 2249,2255 **** tree-ssa-propagate.h tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \ $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \ ! $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \ $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \ $(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) --- 2249,2255 ---- tree-ssa-propagate.h tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \ $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \ ! $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \ $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \ $(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) *************** tree-ssa-phiopt.o : tree-ssa-phiopt.c $( *** 2320,2326 **** $(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \ $(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \ $(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_H) \ ! insn-config.h $(EXPR_H) $(OPTABS_H) tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ --- 2320,2326 ---- $(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \ $(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \ $(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_H) \ ! insn-config.h $(EXPR_H) $(OPTABS_H) $(SCEV_H) tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ *************** ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM *** 2931,2937 **** $(TREE_INLINE_H) $(PARAMS_H) $(TREE_PRETTY_PRINT_H) $(IPA_INLINE_H) ipa-split.o : ipa-split.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \ ! $(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) \ $(TREE_INLINE_H) $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ --- 2931,2937 ---- $(TREE_INLINE_H) $(PARAMS_H) $(TREE_PRETTY_PRINT_H) $(IPA_INLINE_H) ipa-split.o : ipa-split.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \ ! $(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) $(CFGLOOP_H) \ $(TREE_INLINE_H) $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ *************** tree-sra.o : tree-sra.c $(CONFIG_H) $(SY *** 3059,3070 **** $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ ! $(TM_H) coretypes.h $(GIMPLE_H) \ $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \ $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \ $(GIMPLE_PRETTY_PRINT_H) langhooks.h tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ ! $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) \ tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h tree-emutls.o : tree-emutls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \ --- 3059,3070 ---- $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ ! $(TM_H) coretypes.h $(GIMPLE_H) $(CFGLOOP_H) \ $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \ $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \ $(GIMPLE_PRETTY_PRINT_H) langhooks.h tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ ! $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) $(CFGLOOP_H) \ tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h tree-emutls.o : tree-emutls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \ Index: trunk/gcc/tree-switch-conversion.c =================================================================== *** trunk.orig/gcc/tree-switch-conversion.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-switch-conversion.c 2013-04-24 10:21:37.801474946 +0200 *************** Software Foundation, 51 Franklin Street, *** 36,41 **** --- 36,42 ---- #include "tree-ssa-operands.h" #include "tree-pass.h" #include "gimple-pretty-print.h" + #include "cfgloop.h" /* ??? For lang_hooks.types.type_for_mode, but is there a word_mode type in the GIMPLE type system that is language-independent? */ *************** process_switch (gimple swtch) *** 1351,1356 **** --- 1352,1359 ---- fputs (" expanding as bit test is preferable\n", dump_file); emit_case_bit_tests (swtch, info.index_expr, info.range_min, info.range_size); + if (current_loops) + loops_state_set (LOOPS_NEED_FIXUP); return NULL; } Index: trunk/gcc/tree-complex.c =================================================================== *** trunk.orig/gcc/tree-complex.c 2013-04-24 10:08:37.000000000 +0200 --- trunk/gcc/tree-complex.c 2013-04-24 10:21:37.802474957 +0200 *************** along with GCC; see the file COPYING3. *** 28,33 **** --- 28,34 ---- #include "tree-iterator.h" #include "tree-pass.h" #include "tree-ssa-propagate.h" + #include "cfgloop.h" /* For each complex ssa name, a lattice value. We're interested in finding *************** expand_complex_div_wide (gimple_stmt_ite *** 1139,1144 **** --- 1140,1150 ---- make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE); make_edge (bb_true, bb_join, EDGE_FALLTHRU); make_edge (bb_false, bb_join, EDGE_FALLTHRU); + if (current_loops) + { + add_bb_to_loop (bb_true, bb_cond->loop_father); + add_bb_to_loop (bb_false, bb_cond->loop_father); + } /* Update dominance info. Note that bb_join's data was updated by split_block. */ Index: trunk/gcc/asan.c =================================================================== *** trunk.orig/gcc/asan.c 2013-04-19 11:15:01.000000000 +0200 --- trunk/gcc/asan.c 2013-04-24 10:33:30.361166827 +0200 *************** along with GCC; see the file COPYING3. *** 36,41 **** --- 36,42 ---- #include "langhooks.h" #include "hash-table.h" #include "alloc-pool.h" + #include "cfgloop.h" /* AddressSanitizer finds out-of-bounds and use-after-free bugs with <2x slowdown on average. *************** create_cond_insert_point (gimple_stmt_it *** 1220,1225 **** --- 1221,1231 ---- basic_block cond_bb = e->src; basic_block fallthru_bb = e->dest; basic_block then_bb = create_empty_bb (cond_bb); + if (current_loops) + { + add_bb_to_loop (then_bb, cond_bb->loop_father); + loops_state_set (LOOPS_NEED_FIXUP); + } /* Set up the newly created 'then block'. */ e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); Index: trunk/gcc/omp-low.c =================================================================== *** trunk.orig/gcc/omp-low.c 2013-04-09 16:12:41.000000000 +0200 --- trunk/gcc/omp-low.c 2013-04-24 16:05:54.972456799 +0200 *************** expand_parallel_call (struct omp_region *** 3056,3061 **** --- 3056,3066 ---- make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE); + if (current_loops) + { + add_bb_to_loop (then_bb, cond_bb->loop_father); + add_bb_to_loop (else_bb, cond_bb->loop_father); + } e_then = make_edge (then_bb, bb, EDGE_FALLTHRU); e_else = make_edge (else_bb, bb, EDGE_FALLTHRU); *************** expand_omp_for_generic (struct omp_regio *** 4011,4016 **** --- 4016,4023 ---- tree vtype = TREE_TYPE (fd->loops[i].v); bb = create_empty_bb (last_bb); + if (current_loops) + add_bb_to_loop (bb, last_bb->loop_father); gsi = gsi_start_bb (bb); if (i < fd->collapse - 1) *************** expand_omp_for_generic (struct omp_regio *** 4114,4119 **** --- 4121,4128 ---- remove_edge (e); make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE); + if (current_loops) + add_bb_to_loop (l2_bb, cont_bb->loop_father); if (fd->collapse > 1) { e = find_edge (cont_bb, l1_bb); *************** expand_omp_sections (struct omp_region * *** 4902,4907 **** --- 4911,4918 ---- t = gimple_block_label (default_bb); u = build_case_label (NULL, NULL, t); make_edge (l0_bb, default_bb, 0); + if (current_loops) + add_bb_to_loop (default_bb, l0_bb->loop_father); stmt = gimple_build_switch (vmain, u, label_vec); gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT); *************** expand_omp_atomic_pipeline (basic_block *** 5438,5443 **** --- 5449,5458 ---- if (gimple_in_ssa_p (cfun)) update_ssa (TODO_update_ssa_no_phi); + /* ??? The above could use loop construction primitives. */ + if (current_loops) + loops_state_set (LOOPS_NEED_FIXUP); + return true; }