public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Preserve loops from tree to RTL loop optimizers
@ 2012-03-20 15:21 Richard Guenther
  2012-03-21 20:23 ` Richard Sandiford
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Guenther @ 2012-03-20 15:21 UTC (permalink / raw)
  To: gcc-patches


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.

Bootstrapped on x86_64-unknown-linux-gnu, testing shows some
remaining libstdc++ errors, I am investigating them now but
don't expect major issues.

Comments?  The patch is ontop of the early RTL pass merge.

Thanks,
Richard.

2012-03-20  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.
	* cfgcleanup.c (merge_blocks_move): Protect loop latches.
	(cleanup_cfg): If we did something and have loops around, fix
	them up.
	* 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-20 10:54:47.000000000 +0100
--- gcc/loop-init.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/cgraph.c	2012-03-20 13:33:27.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-20 11:36:14.000000000 +0100
--- gcc/cfgexpand.c	2012-03-20 13:33:55.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-20 10:54:47.000000000 +0100
--- gcc/cfgloop.c	2012-03-20 13:33:27.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-20 11:14:19.000000000 +0100
--- gcc/tree-pass.h	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/tree-ssa-loop.c	2012-03-20 13:33:27.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-20 11:03:49.000000000 +0100
--- gcc/cfgcleanup.c	2012-03-20 13:33:27.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,3001 ----
    if (!(mode & CLEANUP_CFGLAYOUT))
      delete_dead_jumptables ();
  
+   /* ???  We do this way too often.  */
+   if (current_loops)
+     {
+       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-20 10:54:47.000000000 +0100
--- gcc/cfghooks.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/cfganal.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/cfgrtl.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/cprop.c	2012-03-20 13:33:27.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"
  
  \f
  /* 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-20 10:54:47.000000000 +0100
--- gcc/omp-low.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/tree-inline.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/tree-mudflap.c	2012-03-20 13:33:27.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-20 11:36:41.000000000 +0100
--- gcc/Makefile.in	2012-03-20 14:37:29.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-20 10:54:47.000000000 +0100
--- gcc/trans-mem.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/tree-ssa-threadupdate.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/cfgloopmanip.c	2012-03-20 13:33:27.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-20 10:54:47.000000000 +0100
--- gcc/tree-cfgcleanup.c	2012-03-20 13:33:27.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-20 10:51:26.000000000 +0100
--- gcc/except.c	2012-03-20 13:50:05.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;
  }
  \f
--- 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;
  }
  \f
Index: gcc/tree-eh.c
===================================================================
*** gcc/tree-eh.c.orig	2012-02-10 15:44:24.000000000 +0100
--- gcc/tree-eh.c	2012-03-20 14:37:11.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,
*** 3062,3067 ****
--- 3063,3070 ----
  	  e = make_edge (bb, new_bb, EDGE_FALLTHRU);
  	  e->count = bb->count;
  	  e->probability = REG_BR_PROB_BASE;
+ 	  if (current_loops)
+ 	    add_bb_to_loop (new_bb, bb->loop_father);
  	}
        else
  	{

^ permalink raw reply	[flat|nested] 8+ messages in thread
* Re: [PATCH] Preserve loops from tree to RTL loop optimizers
@ 2012-04-01 22:55 David Edelsohn
  2012-04-02  6:52 ` Ramana Radhakrishnan
  0 siblings, 1 reply; 8+ messages in thread
From: David Edelsohn @ 2012-04-01 22:55 UTC (permalink / raw)
  To: Richard Guenther, Richard Sandiford; +Cc: GCC Patches

> If there are no further comments I am inclined to commit this
> patch early next week (possibly causing quite some fallout ...).

I am glad there was not more fallout.  Unfortunately powerpc-aix was
not so lucky:

/farm/dje/src/src/libstdc++-v3/src/c++98/streambuf.cc: In function
'std::streamsize
std::__copy_streambufs_eof(std::basic_streambuf<_CharT, _Traits>*,
std::basic_streambuf<_CharT, _Traits>*, bool&) [with _CharT = wchar_t;
_Traits = std::char_traits<wchar_t>; std::streamsize = long int]':
/farm/dje/src/src/libstdc++-v3/src/c++98/streambuf.cc:113:5: internal
compiler error: in get_loop_body, at cfgloop.c:831

Line 831 is:

  gcc_assert (tv == loop->num_nodes);

Reverting the patch fixes the ICE.

- David

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-09-02 17:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-20 15:21 [PATCH] Preserve loops from tree to RTL loop optimizers Richard Guenther
2012-03-21 20:23 ` Richard Sandiford
2012-03-23 14:14   ` Richard Guenther
2012-03-28 12:14     ` Richard Guenther
2012-04-01 22:55 David Edelsohn
2012-04-02  6:52 ` Ramana Radhakrishnan
2012-06-16 18:40   ` H.J. Lu
2012-09-02 17:08     ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).