This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Preserve loops from tree to RTL loop optimizers


On Fri, 23 Mar 2012, Richard Guenther wrote:

> On Wed, 21 Mar 2012, Richard Sandiford wrote:
> 
> > Richard Guenther <rguenther@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  <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.
> 
> 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 <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]