On Fri, 23 Mar 2012, Richard Guenther wrote: > On Wed, 21 Mar 2012, Richard Sandiford wrote: > > > Richard Guenther <rguent...@suse.de> writes: > > > This patch makes us preserve loop structures from the start of tree > > > loop optimizers to the end of RTL loop optimizers. It uses a new > > > property, PROP_loops to indicate we want to preserve them and > > > massages loop_optimizer_init/finalize to honor that. > > > > > > On the RTL side the CFG manipulation was not prepared to handle > > > updating loops, so this patch fills in enough to pass bootstrap > > > and regtesting. We still do too much loop fixing from cleanup_cfg > > > basically because callers do not tell cleanup_cfg if they have > > > modified the CFG themselves (CSE for example does in some cases). > > > It was suggested to use a new flag to cleanup_cfg to do that, > > > other suggestions welcome. > > The updated patch below does that now. > > > > Bootstrapped on x86_64-unknown-linux-gnu, testing shows some > > > remaining libstdc++ errors, I am investigating them now but > > > don't expect major issues. > > As expected, this was a missed patch hunk that got lost during > some intermediate merging. > > > > Comments? The patch is ontop of the early RTL pass merge. > > > > Thanks for doing this (and for keeping the ~PROP_loops case around for > > passes after rtl_loop_done -- I have a patch that uses it for SMS). > > It should even be possible to preserve loop information until SMS > (basically until IRA, IRA invalidates loop information > it computes in a weird way so verification between IRA / reload would > fail). > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > If there are no further comments I am inclined to commit this > patch early next week (possibly causing quite some fallout ...).
Done. Richard. > 2012-03-23 Richard Guenther <rguent...@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. > > Index: gcc/loop-init.c > =================================================================== > *** gcc/loop-init.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/loop-init.c 2012-03-23 11:59:20.000000000 +0100 > *************** along with GCC; see the file COPYING3. > *** 42,56 **** > void > loop_optimizer_init (unsigned flags) > { > ! struct loops *loops; > > ! gcc_assert (!current_loops); > ! loops = ggc_alloc_cleared_loops (); > > ! /* Find the loops. */ > > ! flow_loops_find (loops); > ! current_loops = loops; > > if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES) > { > --- 42,69 ---- > void > loop_optimizer_init (unsigned flags) > { > ! if (!current_loops) > ! { > ! struct loops *loops = ggc_alloc_cleared_loops (); > ! > ! gcc_assert (!(cfun->curr_properties & PROP_loops)); > > ! /* Find the loops. */ > > ! flow_loops_find (loops); > ! current_loops = loops; > ! } > ! 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 > ! } > > if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES) > { > *************** loop_optimizer_finalize (void) > *** 104,109 **** > --- 117,138 ---- > 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) > *************** loop_optimizer_finalize (void) > *** 112,119 **** > } > > /* 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; > --- 141,146 ---- > *************** struct rtl_opt_pass pass_rtl_loop_init = > *** 200,205 **** > --- 227,234 ---- > 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); > > *************** struct rtl_opt_pass pass_rtl_loop_done = > *** 223,229 **** > TV_LOOP, /* tv_id */ > 0, /* properties_required */ > 0, /* properties_provided */ > ! 0, /* properties_destroyed */ > 0, /* todo_flags_start */ > TODO_verify_flow > | TODO_verify_rtl_sharing /* todo_flags_finish */ > --- 252,258 ---- > TV_LOOP, /* tv_id */ > 0, /* properties_required */ > 0, /* properties_provided */ > ! PROP_loops, /* properties_destroyed */ > 0, /* todo_flags_start */ > TODO_verify_flow > | TODO_verify_rtl_sharing /* todo_flags_finish */ > Index: gcc/cgraph.c > =================================================================== > *** gcc/cgraph.c.orig 2012-03-23 09:13:53.000000000 +0100 > --- gcc/cgraph.c 2012-03-23 11:59:20.000000000 +0100 > *************** The callgraph: > *** 99,104 **** > --- 99,105 ---- > #include "ipa-utils.h" > #include "lto-streamer.h" > #include "ipa-inline.h" > + #include "cfgloop.h" > > const char * const ld_plugin_symbol_resolution_names[]= > { > *************** cgraph_release_function_body (struct cgr > *** 1363,1368 **** > --- 1364,1375 ---- > { > tree old_decl = current_function_decl; > push_cfun (DECL_STRUCT_FUNCTION (node->decl)); > + if (cfun->cfg > + && current_loops) > + { > + cfun->curr_properties &= ~PROP_loops; > + loop_optimizer_finalize (); > + } > if (cfun->gimple_df) > { > current_function_decl = node->decl; > *************** cgraph_release_function_body (struct cgr > *** 1379,1385 **** > } > if (cfun->value_histograms) > free_histograms (); > - gcc_assert (!current_loops); > pop_cfun(); > gimple_set_body (node->decl, NULL); > VEC_free (ipa_opt_pass, heap, > --- 1386,1391 ---- > Index: gcc/cfgexpand.c > =================================================================== > *** gcc/cfgexpand.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cfgexpand.c 2012-03-23 11:59:20.000000000 +0100 > *************** along with GCC; see the file COPYING3. > *** 47,52 **** > --- 47,53 ---- > #include "ssaexpand.h" > #include "bitmap.h" > #include "sbitmap.h" > + #include "cfgloop.h" > #include "regs.h" /* For reg_renumber. */ > #include "integrate.h" /* For emit_initial_value_sets. */ > #include "insn-attr.h" /* For INSN_SCHEDULING. */ > *************** expand_gimple_cond (basic_block bb, gimp > *** 1940,1945 **** > --- 1941,1948 ---- > false_edge->flags |= EDGE_FALLTHRU; > new_bb->count = false_edge->count; > new_bb->frequency = EDGE_FREQUENCY (false_edge); > + if (current_loops && bb->loop_father) > + add_bb_to_loop (new_bb, bb->loop_father); > new_edge = make_edge (new_bb, dest, 0); > new_edge->probability = REG_BR_PROB_BASE; > new_edge->count = new_bb->count; > *************** construct_init_block (void) > *** 4118,4123 **** > --- 4121,4128 ---- > ENTRY_BLOCK_PTR); > init_block->frequency = ENTRY_BLOCK_PTR->frequency; > init_block->count = ENTRY_BLOCK_PTR->count; > + if (current_loops && ENTRY_BLOCK_PTR->loop_father) > + add_bb_to_loop (init_block, ENTRY_BLOCK_PTR->loop_father); > if (e) > { > first_block = e->dest; > *************** construct_exit_block (void) > *** 4185,4190 **** > --- 4190,4197 ---- > EXIT_BLOCK_PTR->prev_bb); > exit_block->frequency = EXIT_BLOCK_PTR->frequency; > exit_block->count = EXIT_BLOCK_PTR->count; > + if (current_loops && EXIT_BLOCK_PTR->loop_father) > + add_bb_to_loop (exit_block, EXIT_BLOCK_PTR->loop_father); > > ix = 0; > while (ix < EDGE_COUNT (EXIT_BLOCK_PTR->preds)) > *************** gimple_expand_cfg (void) > *** 4556,4561 **** > --- 4563,4570 ---- > timevar_push (TV_POST_EXPAND); > /* We are no longer in SSA form. */ > cfun->gimple_df->in_ssa_p = false; > + if (current_loops) > + loops_state_clear (LOOP_CLOSED_SSA); > > /* Expansion is used by optimization passes too, set maybe_hot_insn_p > conservatively to true until they are all profile aware. */ > Index: gcc/cfgloop.c > =================================================================== > *** gcc/cfgloop.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cfgloop.c 2012-03-23 11:59:20.000000000 +0100 > *************** verify_loop_structure (void) > *** 1317,1325 **** > unsigned num = number_of_loops (); > loop_iterator li; > struct loop_exit *exit, *mexit; > > ! /* We need up-to-date dominators, verify them. */ > ! verify_dominators (CDI_DOMINATORS); > > /* Check sizes. */ > sizes = XCNEWVEC (unsigned, num); > --- 1317,1329 ---- > unsigned num = number_of_loops (); > loop_iterator li; > struct loop_exit *exit, *mexit; > + bool dom_available = dom_info_available_p (CDI_DOMINATORS); > > ! /* We need up-to-date dominators, compute or verify them. */ > ! if (!dom_available) > ! calculate_dominance_info (CDI_DOMINATORS); > ! else > ! verify_dominators (CDI_DOMINATORS); > > /* Check sizes. */ > sizes = XCNEWVEC (unsigned, num); > *************** verify_loop_structure (void) > *** 1563,1568 **** > --- 1567,1574 ---- > gcc_assert (!err); > > free (sizes); > + if (!dom_available) > + free_dominance_info (CDI_DOMINATORS); > } > > /* Returns latch edge of LOOP. */ > Index: gcc/tree-pass.h > =================================================================== > *** gcc/tree-pass.h.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/tree-pass.h 2012-03-23 11:59:20.000000000 +0100 > *************** struct dump_file_info > *** 239,244 **** > --- 239,245 ---- > #define PROP_gimple_lomp (1 << 8) /* lowered OpenMP directives */ > #define PROP_cfglayout (1 << 9) /* cfglayout mode on > RTL */ > #define PROP_gimple_lcx (1 << 10) /* lowered complex */ > + #define PROP_loops (1 << 11) /* preserve loop structures */ > > #define PROP_trees \ > (PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_lomp) > Index: gcc/tree-ssa-loop.c > =================================================================== > *** gcc/tree-ssa-loop.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/tree-ssa-loop.c 2012-03-23 11:59:20.000000000 +0100 > *************** struct gimple_opt_pass pass_tree_loop_in > *** 92,98 **** > 0, /* static_pass_number */ > TV_TREE_LOOP_INIT, /* tv_id */ > PROP_cfg, /* properties_required */ > ! 0, /* properties_provided */ > 0, /* properties_destroyed */ > 0, /* todo_flags_start */ > 0 /* todo_flags_finish */ > --- 92,98 ---- > 0, /* static_pass_number */ > TV_TREE_LOOP_INIT, /* tv_id */ > PROP_cfg, /* properties_required */ > ! PROP_loops, /* properties_provided */ > 0, /* properties_destroyed */ > 0, /* todo_flags_start */ > 0 /* todo_flags_finish */ > Index: gcc/cfgcleanup.c > =================================================================== > *** gcc/cfgcleanup.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cfgcleanup.c 2012-03-23 12:01:21.000000000 +0100 > *************** merge_blocks_move (edge e, basic_block b > *** 779,784 **** > --- 779,789 ---- > if (e->flags & EDGE_FALLTHRU) > { > int b_index = b->index, c_index = c->index; > + > + /* Protect the loop latches. */ > + if (current_loops && c->loop_father->latch == c) > + return NULL; > + > merge_blocks (b, c); > update_forwarder_flag (b); > > *************** cleanup_cfg (int mode) > *** 2976,2981 **** > --- 2981,3003 ---- > if (!(mode & CLEANUP_CFGLAYOUT)) > delete_dead_jumptables (); > > + /* ??? We probably do this way too often. */ > + if (current_loops > + && (changed > + || (mode & CLEANUP_CFG_CHANGED))) > + { > + bitmap changed_bbs; > + timevar_push (TV_REPAIR_LOOPS); > + /* The above doesn't preserve dominance info if available. */ > + gcc_assert (!dom_info_available_p (CDI_DOMINATORS)); > + calculate_dominance_info (CDI_DOMINATORS); > + changed_bbs = BITMAP_ALLOC (NULL); > + fix_loop_structure (changed_bbs); > + BITMAP_FREE (changed_bbs); > + free_dominance_info (CDI_DOMINATORS); > + timevar_pop (TV_REPAIR_LOOPS); > + } > + > timevar_pop (TV_CLEANUP_CFG); > > return changed; > Index: gcc/cfghooks.c > =================================================================== > *** gcc/cfghooks.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cfghooks.c 2012-03-23 11:59:20.000000000 +0100 > *************** delete_basic_block (basic_block bb) > *** 508,513 **** > --- 508,514 ---- > { > loop->header = NULL; > loop->latch = NULL; > + loops_state_set (LOOPS_NEED_FIXUP); > } > > remove_bb_from_loops (bb); > *************** merge_blocks (basic_block a, basic_block > *** 682,689 **** > > cfg_hooks->merge_blocks (a, b); > > if (current_loops != NULL) > ! 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 > --- 683,700 ---- > > cfg_hooks->merge_blocks (a, b); > > + /* If we merge a loop header into its predecessor, update the loop > + structure. */ > if (current_loops != NULL) > ! { > ! 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 > *************** duplicate_block (basic_block bb, edge e, > *** 999,1004 **** > --- 1010,1027 ---- > 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; > Index: gcc/cfganal.c > =================================================================== > *** gcc/cfganal.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cfganal.c 2012-03-23 11:59:20.000000000 +0100 > *************** along with GCC; see the file COPYING3. > *** 37,42 **** > --- 37,43 ---- > #include "bitmap.h" > #include "sbitmap.h" > #include "timevar.h" > + #include "cfgloop.h" > > /* Store the data structures necessary for depth-first search. */ > struct depth_first_search_dsS { > *************** forwarder_block_p (const_basic_block bb) > *** 94,99 **** > --- 95,111 ---- > || !single_succ_p (bb)) > return false; > > + /* Protect loop latches, headers and preheaders. */ > + if (current_loops) > + { > + basic_block dest; > + if (bb->loop_father->header == bb) > + return false; > + dest = EDGE_SUCC (bb, 0)->dest; > + if (dest->loop_father->header == dest) > + return false; > + } > + > for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn)) > if (INSN_P (insn) && flow_active_insn_p (insn)) > return false; > Index: gcc/cfgrtl.c > =================================================================== > *** gcc/cfgrtl.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cfgrtl.c 2012-03-23 11:59:20.000000000 +0100 > *************** rtl_can_merge_blocks (basic_block a, bas > *** 727,732 **** > --- 727,736 ---- > if (BB_PARTITION (a) != BB_PARTITION (b)) > return false; > > + /* Protect the loop latches. */ > + if (current_loops && b->loop_father->latch == b) > + return false; > + > /* There must be exactly one edge in between the blocks. */ > return (single_succ_p (a) > && single_succ (a) == b > *************** cfg_layout_can_merge_blocks_p (basic_blo > *** 2786,2791 **** > --- 2790,2799 ---- > if (BB_PARTITION (a) != BB_PARTITION (b)) > return false; > > + /* Protect the loop latches. */ > + if (current_loops && b->loop_father->latch == b) > + return false; > + > /* If we would end up moving B's instructions, make sure it doesn't fall > through into the exit block, since we cannot recover from a fallthrough > edge into the exit block occurring in the middle of a function. */ > Index: gcc/cprop.c > =================================================================== > *** gcc/cprop.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cprop.c 2012-03-23 11:59:20.000000000 +0100 > *************** along with GCC; see the file COPYING3. > *** 48,53 **** > --- 48,54 ---- > #include "df.h" > #include "dbgcnt.h" > #include "target.h" > + #include "cfgloop.h" > > > /* An obstack for our working variables. */ > *************** bypass_block (basic_block bb, rtx setcc, > *** 1610,1615 **** > --- 1611,1627 ---- > && dest != old_dest > && dest != EXIT_BLOCK_PTR) > { > + if (current_loops != NULL > + && e->src->loop_father->latch == e->src) > + { > + /* ??? Now we are creating (or may create) a loop > + with multiple entries. Simply mark it for > + removal. Alternatively we could not do this > + threading. */ > + e->src->loop_father->header = NULL; > + e->src->loop_father->latch = NULL; > + } > + > redirect_edge_and_branch_force (e, dest); > > /* Copy the register setter to the redirected edge. > Index: gcc/omp-low.c > =================================================================== > *** gcc/omp-low.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/omp-low.c 2012-03-23 11:59:20.000000000 +0100 > *************** finalize_task_copyfn (gimple task_stmt) > *** 1242,1248 **** > > /* Inform the callgraph about the new function. */ > DECL_STRUCT_FUNCTION (child_fn)->curr_properties > ! = cfun->curr_properties; > > old_fn = current_function_decl; > push_cfun (child_cfun); > --- 1242,1248 ---- > > /* Inform the callgraph about the new function. */ > DECL_STRUCT_FUNCTION (child_fn)->curr_properties > ! = cfun->curr_properties & ~PROP_loops; > > old_fn = current_function_decl; > push_cfun (child_cfun); > *************** expand_omp_taskreg (struct omp_region *r > *** 3562,3568 **** > > /* Inform the callgraph about the new function. */ > DECL_STRUCT_FUNCTION (child_fn)->curr_properties > ! = cfun->curr_properties; > cgraph_add_new_function (child_fn, true); > > /* Fix the callgraph edges for child_cfun. Those for cfun will be > --- 3562,3568 ---- > > /* Inform the callgraph about the new function. */ > DECL_STRUCT_FUNCTION (child_fn)->curr_properties > ! = cfun->curr_properties & ~PROP_loops; > cgraph_add_new_function (child_fn, true); > > /* Fix the callgraph edges for child_cfun. Those for cfun will be > Index: gcc/tree-inline.c > =================================================================== > *** gcc/tree-inline.c.orig 2012-03-23 09:13:53.000000000 +0100 > --- gcc/tree-inline.c 2012-03-23 11:59:20.000000000 +0100 > *************** initialize_cfun (tree new_fndecl, tree c > *** 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; > --- 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 & ~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; > Index: gcc/tree-mudflap.c > =================================================================== > *** gcc/tree-mudflap.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/tree-mudflap.c 2012-03-23 11:59:20.000000000 +0100 > *************** along with GCC; see the file COPYING3. > *** 45,50 **** > --- 45,52 ---- > #include "cgraph.h" > #include "gimple.h" > > + extern void add_bb_to_loop (basic_block, struct loop *); > + > /* Internal function decls */ > > > *************** mf_build_check_statement_for (tree base, > *** 560,565 **** > --- 562,571 ---- > set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb); > } > > + /* Update loop info. */ > + if (current_loops) > + add_bb_to_loop (then_bb, cond_bb->loop_father); > + > /* Build our local variables. */ > mf_elem = make_rename_temp (mf_cache_structptr_type, "__mf_elem"); > mf_base = make_rename_temp (mf_uintptr_type, "__mf_base"); > Index: gcc/Makefile.in > =================================================================== > *** gcc/Makefile.in.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/Makefile.in 2012-03-23 11:59:20.000000000 +0100 > *************** trans-mem.o : trans-mem.c $(CONFIG_H) $( > *** 2159,2165 **** > $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_INLINE_H) \ > $(DIAGNOSTIC_CORE_H) $(DEMANGLE_H) output.h $(TRANS_MEM_H) \ > $(PARAMS_H) $(TARGET_H) langhooks.h \ > ! tree-pretty-print.h gimple-pretty-print.h > > ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h > \ > $(GGC_H) $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h > \ > --- 2159,2165 ---- > $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_INLINE_H) \ > $(DIAGNOSTIC_CORE_H) $(DEMANGLE_H) output.h $(TRANS_MEM_H) \ > $(PARAMS_H) $(TARGET_H) langhooks.h \ > ! tree-pretty-print.h gimple-pretty-print.h $(CFGLOOP_H) > > ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h > \ > $(GGC_H) $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h > \ > *************** tree-ssa-operands.o : tree-ssa-operands. > *** 2468,2474 **** > tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ > $(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) langhooks.h \ > $(GGC_H) $(TREE_PASS_H) coretypes.h $(TIMEVAR_H) pointer-set.h \ > ! $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h toplev.h > $(DIAGNOSTIC_CORE_H) > tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h > $(TM_H) \ > $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) output.h \ > $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TREE_PASS_H) > $(TIMEVAR_H) \ > --- 2468,2475 ---- > tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ > $(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) langhooks.h \ > $(GGC_H) $(TREE_PASS_H) coretypes.h $(TIMEVAR_H) pointer-set.h \ > ! $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h toplev.h \ > ! $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) > tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h > $(TM_H) \ > $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) output.h \ > $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TREE_PASS_H) > $(TIMEVAR_H) \ > *************** except.o : except.c $(CONFIG_H) $(SYSTEM > *** 2814,2820 **** > dwarf2asm.h dwarf2out.h toplev.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) > intl.h $(GGC_H) \ > gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) $(DWARF2_H) \ > $(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ > ! tree-pretty-print.h sbitmap.h $(COMMON_TARGET_H) > expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ > $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \ > $(LIBFUNCS_H) $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \ > --- 2815,2821 ---- > dwarf2asm.h dwarf2out.h toplev.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) > intl.h $(GGC_H) \ > gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) $(DWARF2_H) \ > $(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ > ! tree-pretty-print.h sbitmap.h $(COMMON_TARGET_H) $(CFGLOOP_H) > expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ > $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \ > $(LIBFUNCS_H) $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \ > *************** cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM > *** 2912,2918 **** > gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \ > $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \ > value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \ > ! ipa-inline.h $(LTO_STREAMER_H) > cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ > $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) > $(FLAGS_H) $(GGC_H) \ > $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \ > --- 2913,2919 ---- > gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \ > $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \ > value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \ > ! ipa-inline.h $(LTO_STREAMER_H) $(CFGLOOP_H) > cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ > $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) > $(FLAGS_H) $(GGC_H) \ > $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \ > *************** cprop.o : cprop.c $(CONFIG_H) $(SYSTEM_H > *** 3029,3035 **** > $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h > $(DIAGNOSTIC_CORE_H) \ > $(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) $(TREE_H) $(TIMEVAR_H) \ > intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \ > ! $(DF_H) > gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ > $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \ > $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h > $(DIAGNOSTIC_CORE_H) \ > --- 3030,3036 ---- > $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h > $(DIAGNOSTIC_CORE_H) \ > $(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) $(TREE_H) $(TIMEVAR_H) \ > intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \ > ! $(DF_H) $(CFGLOOP_H) > gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ > $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \ > $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h > $(DIAGNOSTIC_CORE_H) \ > *************** cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) > *** 3149,3155 **** > $(DIAGNOSTIC_H) toplev.h $(DIAGNOSTIC_CORE_H) $(BASIC_BLOCK_H) > $(FLAGS_H) debug.h $(PARAMS_H) \ > value-prof.h $(TREE_INLINE_H) $(TARGET_H) $(SSAEXPAND_H) $(REGS_H) \ > tree-pretty-print.h gimple-pretty-print.h $(BITMAP_H) sbitmap.h \ > ! $(INSN_ATTR_H) $(INTEGRATE_H) > cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) > $(RTL_ERROR_H) \ > $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ > output.h $(FUNCTION_H) $(EXCEPT_H) $(TM_P_H) $(INSN_ATTR_H) \ > --- 3150,3156 ---- > $(DIAGNOSTIC_H) toplev.h $(DIAGNOSTIC_CORE_H) $(BASIC_BLOCK_H) > $(FLAGS_H) debug.h $(PARAMS_H) \ > value-prof.h $(TREE_INLINE_H) $(TARGET_H) $(SSAEXPAND_H) $(REGS_H) \ > tree-pretty-print.h gimple-pretty-print.h $(BITMAP_H) sbitmap.h \ > ! $(INSN_ATTR_H) $(INTEGRATE_H) $(CFGLOOP_H) > cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) > $(RTL_ERROR_H) \ > $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ > output.h $(FUNCTION_H) $(EXCEPT_H) $(TM_P_H) $(INSN_ATTR_H) \ > *************** cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM > *** 3158,3164 **** > $(TREE_PASS_H) $(DF_H) $(GGC_H) $(COMMON_TARGET_H) > cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ > $(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \ > ! $(TIMEVAR_H) $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) vecprim.h sbitmap.h > $(BITMAP_H) > cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) > $(RTL_H) \ > $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h > $(DIAGNOSTIC_CORE_H) \ > $(FUNCTION_H) $(EXCEPT_H) $(TIMEVAR_H) $(TREE_H) $(EXPR_H) sbitmap.h > --- 3159,3166 ---- > $(TREE_PASS_H) $(DF_H) $(GGC_H) $(COMMON_TARGET_H) > cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ > $(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \ > ! $(TIMEVAR_H) $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) vecprim.h sbitmap.h \ > ! $(BITMAP_H) $(CFGLOOP_H) > cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) > $(RTL_H) \ > $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h > $(DIAGNOSTIC_CORE_H) \ > $(FUNCTION_H) $(EXCEPT_H) $(TIMEVAR_H) $(TREE_H) $(EXPR_H) sbitmap.h > Index: gcc/trans-mem.c > =================================================================== > *** gcc/trans-mem.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/trans-mem.c 2012-03-23 11:59:20.000000000 +0100 > *************** > *** 34,39 **** > --- 34,40 ---- > #include "langhooks.h" > #include "tree-pretty-print.h" > #include "gimple-pretty-print.h" > + #include "cfgloop.h" > > > #define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 2000 - 1) > *************** tm_log_emit_save_or_restores (basic_bloc > *** 1270,1275 **** > --- 1271,1282 ---- > cond_bb = create_empty_bb (before_bb); > code_bb = create_empty_bb (cond_bb); > *end_bb = create_empty_bb (code_bb); > + if (current_loops && before_bb->loop_father) > + { > + add_bb_to_loop (cond_bb, before_bb->loop_father); > + add_bb_to_loop (code_bb, before_bb->loop_father); > + add_bb_to_loop (*end_bb, before_bb->loop_father); > + } > redirect_edge_pred (fallthru_edge, *end_bb); > fallthru_edge->flags = EDGE_FALLTHRU; > make_edge (before_bb, cond_bb, old_flags); > *************** expand_transaction (struct tm_region *re > *** 2682,2687 **** > --- 2689,2696 ---- > basic_block test_bb; > > test_bb = create_empty_bb (slice_bb); > + if (current_loops && slice_bb->loop_father) > + add_bb_to_loop (test_bb, slice_bb->loop_father); > if (VEC_empty (tree, tm_log_save_addresses)) > region->entry_block = test_bb; > gsi = gsi_last_bb (test_bb); > *************** expand_transaction (struct tm_region *re > *** 2719,2724 **** > --- 2728,2735 ---- > basic_block empty_bb; > > region->entry_block = empty_bb = create_empty_bb (atomic_bb); > + if (current_loops && atomic_bb->loop_father) > + add_bb_to_loop (empty_bb, atomic_bb->loop_father); > > e = FALLTHRU_EDGE (atomic_bb); > redirect_edge_pred (e, empty_bb); > Index: gcc/tree-ssa-threadupdate.c > =================================================================== > *** gcc/tree-ssa-threadupdate.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/tree-ssa-threadupdate.c 2012-03-23 11:59:20.000000000 +0100 > *************** thread_block (basic_block bb, bool noloo > *** 624,629 **** > --- 624,630 ---- > { > loop->header = NULL; > loop->latch = NULL; > + loops_state_set (LOOPS_NEED_FIXUP); > } > } > > *************** thread_through_loop_header (struct loop > *** 969,974 **** > --- 970,976 ---- > original header. */ > loop->header = NULL; > loop->latch = NULL; > + loops_state_set (LOOPS_NEED_FIXUP); > return thread_block (header, false); > } > > Index: gcc/cfgloopmanip.c > =================================================================== > *** gcc/cfgloopmanip.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/cfgloopmanip.c 2012-03-23 11:59:20.000000000 +0100 > *************** fix_loop_structure (bitmap changed_bbs) > *** 1728,1733 **** > --- 1728,1735 ---- > if (record_exits) > record_loop_exits (); > > + loops_state_clear (LOOPS_NEED_FIXUP); > + > #ifdef ENABLE_CHECKING > verify_loop_structure (); > #endif > Index: gcc/tree-cfgcleanup.c > =================================================================== > *** gcc/tree-cfgcleanup.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/tree-cfgcleanup.c 2012-03-23 11:59:20.000000000 +0100 > *************** repair_loop_structures (void) > *** 793,799 **** > #endif > scev_reset (); > > - loops_state_clear (LOOPS_NEED_FIXUP); > timevar_pop (TV_REPAIR_LOOPS); > } > > --- 793,798 ---- > Index: gcc/except.c > =================================================================== > *** gcc/except.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/except.c 2012-03-23 11:59:20.000000000 +0100 > *************** along with GCC; see the file COPYING3. > *** 144,149 **** > --- 144,150 ---- > #include "tree-pass.h" > #include "timevar.h" > #include "tree-flow.h" > + #include "cfgloop.h" > > /* Provide defaults for stuff that may not be defined when using > sjlj exceptions. */ > *************** static basic_block > *** 898,904 **** > emit_to_new_bb_before (rtx seq, rtx insn) > { > rtx last; > ! basic_block bb; > edge e; > edge_iterator ei; > > --- 899,905 ---- > emit_to_new_bb_before (rtx seq, rtx insn) > { > rtx last; > ! basic_block bb, prev_bb; > edge e; > edge_iterator ei; > > *************** emit_to_new_bb_before (rtx seq, rtx insn > *** 913,921 **** > last = emit_insn_before (seq, insn); > if (BARRIER_P (last)) > last = PREV_INSN (last); > ! bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb); > update_bb_for_insn (bb); > bb->flags |= BB_SUPERBLOCK; > return bb; > } > > --- 914,929 ---- > last = emit_insn_before (seq, insn); > if (BARRIER_P (last)) > last = PREV_INSN (last); > ! prev_bb = BLOCK_FOR_INSN (insn)->prev_bb; > ! bb = create_basic_block (seq, last, prev_bb); > update_bb_for_insn (bb); > bb->flags |= BB_SUPERBLOCK; > + if (current_loops) > + { > + add_bb_to_loop (bb, prev_bb->loop_father); > + if (prev_bb->loop_father->header == prev_bb) > + prev_bb->loop_father->header = bb; > + } > return bb; > } > > Index: gcc/tree-eh.c > =================================================================== > *** gcc/tree-eh.c.orig 2012-03-22 13:10:50.000000000 +0100 > --- gcc/tree-eh.c 2012-03-23 11:59:20.000000000 +0100 > *************** along with GCC; see the file COPYING3. > *** 38,43 **** > --- 38,44 ---- > #include "diagnostic-core.h" > #include "gimple.h" > #include "target.h" > + #include "cfgloop.h" > > /* In some instances a tree and a gimple need to be stored in a same table, > i.e. in hash tables. This is a structure to do this. */ > *************** lower_resx (basic_block bb, gimple stmt, > *** 3041,3046 **** > --- 3042,3049 ---- > gimple_stmt_iterator gsi2; > > new_bb = create_empty_bb (bb); > + if (current_loops) > + add_bb_to_loop (new_bb, bb->loop_father); > lab = gimple_block_label (new_bb); > gsi2 = gsi_start_bb (new_bb); > > Index: gcc/basic-block.h > =================================================================== > *** gcc/basic-block.h.orig 2012-01-10 10:11:18.000000000 +0100 > --- gcc/basic-block.h 2012-03-23 12:00:25.000000000 +0100 > *************** edge find_edge (basic_block, basic_block > *** 741,746 **** > --- 741,747 ---- > #define CLEANUP_NO_INSN_DEL 16 /* Do not try to delete trivially dead > insns. */ > #define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */ > + #define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */ > > /* In lcm.c */ > extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *, > Index: gcc/cse.c > =================================================================== > *** gcc/cse.c.orig 2012-03-22 13:12:15.000000000 +0100 > --- gcc/cse.c 2012-03-23 13:00:42.000000000 +0100 > *************** rest_of_handle_cse (void) > *** 7451,7457 **** > { > timevar_push (TV_JUMP); > rebuild_jump_labels (get_insns ()); > ! cleanup_cfg (0); > timevar_pop (TV_JUMP); > } > else if (tem == 1 || optimize > 1) > --- 7451,7457 ---- > { > timevar_push (TV_JUMP); > rebuild_jump_labels (get_insns ()); > ! cleanup_cfg (CLEANUP_CFG_CHANGED); > timevar_pop (TV_JUMP); > } > else if (tem == 1 || optimize > 1) > *************** rest_of_handle_cse2 (void) > *** 7511,7517 **** > { > timevar_push (TV_JUMP); > rebuild_jump_labels (get_insns ()); > ! cleanup_cfg (0); > timevar_pop (TV_JUMP); > } > else if (tem == 1) > --- 7511,7517 ---- > { > timevar_push (TV_JUMP); > rebuild_jump_labels (get_insns ()); > ! cleanup_cfg (CLEANUP_CFG_CHANGED); > timevar_pop (TV_JUMP); > } > else if (tem == 1) > *************** rest_of_handle_cse_after_global_opts (vo > *** 7572,7578 **** > { > timevar_push (TV_JUMP); > rebuild_jump_labels (get_insns ()); > ! cleanup_cfg (0); > timevar_pop (TV_JUMP); > } > else if (tem == 1) > --- 7572,7578 ---- > { > timevar_push (TV_JUMP); > rebuild_jump_labels (get_insns ()); > ! cleanup_cfg (CLEANUP_CFG_CHANGED); > timevar_pop (TV_JUMP); > } > else if (tem == 1) > -- Richard Guenther <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer