The following patch makes sure we don't inline / copy a CFG with
loops needing fixups.  In the particular case function versioning
after IPA-CP made a CFG portion dead, removing a loop.

The patch also makes the bogus loop removal detection unconditional
as gengtype doesn't seem to be able to handle preprocessor conditional
fields.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

2014-09-08  Richard Biener  <rguent...@suse.de>

        PR ipa/63196
        * cfgloop.c (mark_loop_for_removal): Track former header
        unconditionally.
        * cfgloop.h (struct loop): Add former_header member unconditionally.
        * loop-init.c (fix_loop_structure): Enable bogus loop removal
        diagnostic unconditionally.
        * tree-inline.c (copy_loops): The source loop header should
        always be non-NULL.
        (tree_function_versioning): If loops need fixup after removing
        unreachable blocks fix them.

Index: gcc/cfgloop.c
===================================================================
--- gcc/cfgloop.c       (revision 215008)
+++ gcc/cfgloop.c       (working copy)
@@ -1927,9 +1937,7 @@ bb_loop_depth (const_basic_block bb)
 void
 mark_loop_for_removal (loop_p loop)
 {
-#ifdef ENABLE_CHECKING
   loop->former_header = loop->header;
-#endif
   loop->header = NULL;
   loop->latch = NULL;
   loops_state_set (LOOPS_NEED_FIXUP);
Index: gcc/cfgloop.h
===================================================================
--- gcc/cfgloop.h       (revision 215008)
+++ gcc/cfgloop.h       (working copy)
@@ -194,13 +194,11 @@ struct GTY ((chain_next ("%h.next"))) lo
   /* Number of iteration analysis data for RTL.  */
   struct niter_desc *simple_loop_desc;
 
-#ifdef ENABLE_CHECKING
   /* For sanity checking during loop fixup we record here the former
      loop header for loops marked for removal.  Note that this prevents
      the basic-block from being collected but its index can still be
      reused.  */
   basic_block former_header;
-#endif
 };
 
 /* Flags for state of loop structure.  */
Index: gcc/loop-init.c
===================================================================
--- gcc/loop-init.c     (revision 215008)
+++ gcc/loop-init.c     (working copy)
@@ -245,12 +245,10 @@ fix_loop_structure (bitmap changed_bbs)
        }
 
       /* Remove the loop.  */
-#ifdef ENABLE_CHECKING
       if (loop->header)
        loop->former_header = loop->header;
       else
        gcc_assert (loop->former_header != NULL);
-#endif
       loop->header = NULL;
       flow_loop_tree_node_remove (loop);
     }
@@ -278,7 +276,6 @@ fix_loop_structure (bitmap changed_bbs)
   FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
     if (loop && loop->header == NULL)
       {
-#ifdef ENABLE_CHECKING
        if (dump_file
            && ((unsigned) loop->former_header->index
                < basic_block_info_for_fn (cfun)->length ()))
@@ -306,7 +303,6 @@ fix_loop_structure (bitmap changed_bbs)
                           former_header->loop_father->header->index);
              }
          }
-#endif
        (*get_loops (cfun))[i] = NULL;
        flow_loop_free (loop);
       }
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c   (revision 215008)
+++ gcc/tree-inline.c   (working copy)
@@ -2376,11 +2376,8 @@ copy_loops (copy_body_data *id,
 
          /* Assign the new loop its header and latch and associate
             those with the new loop.  */
-         if (src_loop->header != NULL)
-           {
-             dest_loop->header = (basic_block)src_loop->header->aux;
-             dest_loop->header->loop_father = dest_loop;
-           }
+         dest_loop->header = (basic_block)src_loop->header->aux;
+         dest_loop->header->loop_father = dest_loop;
          if (src_loop->latch != NULL)
            {
              dest_loop->latch = (basic_block)src_loop->latch->aux;
@@ -5536,6 +5533,11 @@ tree_function_versioning (tree old_decl,
   delete_unreachable_blocks_update_callgraph (&id);
   if (id.dst_node->definition)
     cgraph_edge::rebuild_references ();
+  if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+    {
+      calculate_dominance_info (CDI_DOMINATORS);
+      fix_loop_structure (NULL);
+    }
   update_ssa (TODO_update_ssa);
 
   /* After partial cloning we need to rescale frequencies, so they are

Reply via email to