This allows cfgcleanup to remove some of the extra CFG that exists
just for loop analysis passes convenience (those can be and are
easily re-created by passes doing loop_optimizer_init ()).

It may fix a regression uncovered in private communication.

Untested - my original idea how to fix this (tree_forwarder_block_p
hunk) ran into the issue in remove_forwarder_block which causes
loops to be removed / re-discovered (losing meta-data).

Richard.

2014-02-19  Richard Biener  <rguent...@suse.de>

        * tree-cfgcleanup.c (tree_forwarder_block_p): Protect
        latches and preheaders only if requested.
        (remove_forwarder_block): Update loop structure if we
        removed a forwarder that is a loop latch.

Index: gcc/tree-cfgcleanup.c
===================================================================
*** gcc/tree-cfgcleanup.c       (revision 207878)
--- gcc/tree-cfgcleanup.c       (working copy)
*************** tree_forwarder_block_p (basic_block bb,
*** 307,321 ****
  
    if (current_loops)
      {
!       basic_block dest;
!       /* Protect loop latches, headers and preheaders.  */
        if (bb->loop_father->header == bb)
        return false;
-       dest = EDGE_SUCC (bb, 0)->dest;
  
!       if (dest->loop_father->header == dest)
        return false;
      }
    return true;
  }
  
--- 307,324 ----
  
    if (current_loops)
      {
!       /* Protect loop headers.  */
        if (bb->loop_father->header == bb)
        return false;
  
!       /* Protect loop latches and preheaders if requested.  */
!       basic_block dest = EDGE_SUCC (bb, 0)->dest;
!       if (dest->loop_father->header == dest
!         && (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS)
!             || loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)))
        return false;
      }
+ 
    return true;
  }
  
*************** remove_forwarder_block (basic_block bb)
*** 497,503 ****
        set_immediate_dominator (CDI_DOMINATORS, dest, dom);
      }
  
!   /* And kill the forwarder block.  */
    delete_basic_block (bb);
  
    return true;
--- 500,511 ----
        set_immediate_dominator (CDI_DOMINATORS, dest, dom);
      }
  
!   /* And kill the forwarder block, but first adjust its parent loop
!      latch info as otherwise the cfg hook has a hard time not to
!      kill the loop.  */
!   if (current_loops
!       && bb->loop_father->latch == bb)
!     bb->loop_father->latch = dest;
    delete_basic_block (bb);
  
    return true;

Reply via email to