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]

[PATCH] Fix PR63196, ensure loops are fixed before inlining


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  <rguenther@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


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