cfgloop.c (mark_loop_for_removal): Record former header when ENABLE_CHECKING.
authorRichard Biener <rguenther@suse.de>
Fri, 5 Sep 2014 13:04:40 +0000 (13:04 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 5 Sep 2014 13:04:40 +0000 (13:04 +0000)
2014-09-05  Richard Biener  <rguenther@suse.de>

* cfgloop.c (mark_loop_for_removal): Record former header
when ENABLE_CHECKING.
* cfgloop.h (strut loop): Add former_header member when
ENABLE_CHECKING.
* loop-init.c (fix_loop_structure): Sanity check loops
marked for removal if they re-appeared.

From-SVN: r214957

gcc/ChangeLog
gcc/cfgloop.c
gcc/cfgloop.h
gcc/loop-init.c

index bb2db3de7372a195c2e88c34d2e6b2b75d442ac2..5af9fd485db4a1b39b25f529ed0dca1e93aa53e7 100644 (file)
@@ -1,3 +1,12 @@
+2014-09-05  Richard Biener  <rguenther@suse.de>
+
+       * cfgloop.c (mark_loop_for_removal): Record former header
+       when ENABLE_CHECKING.
+       * cfgloop.h (strut loop): Add former_header member when
+       ENABLE_CHECKING.
+       * loop-init.c (fix_loop_structure): Sanity check loops
+       marked for removal if they re-appeared.
+
 2014-09-05  Alan Lawrence  <alan.lawrence@arm.com>
 
        * config/aarch64/arm_neon.h (int32x1_t, int16x1_t, int8x1_t,
index 789c45a8f0348fcfefd833d3e8d09e8e131662b2..399420ddbde330dc3f5c75e017a654743dd77aca 100644 (file)
@@ -1927,7 +1927,11 @@ 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 e868f5d4ba1490b99216672b6352b6e78afe68df..d62a4151cb03de720ff1b1cc25756794421430fa 100644 (file)
@@ -193,6 +193,14 @@ struct GTY ((chain_next ("%h.next"))) loop {
 
   /* 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 26c953f71e519e3aa8b8a39a92d7c132ce817f43..e3734abadcea94742c6a7ab97fd6d4ad6a8a94f7 100644 (file)
@@ -245,6 +245,12 @@ 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);
     }
@@ -272,6 +278,35 @@ 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 ()))
+         {
+           basic_block former_header
+             = BASIC_BLOCK_FOR_FN (cfun, loop->former_header->index);
+           /* If the old header still exists we want to check if the
+              original loop is re-discovered or the old header is now
+              part of a newly discovered loop.
+              In both cases we should have avoided removing the loop.  */
+           if (former_header == loop->former_header)
+             {
+               if (former_header->loop_father->header == former_header)
+                 fprintf (dump_file, "fix_loop_structure: rediscovered "
+                          "removed loop %d as loop %d with old header %d\n",
+                          loop->num, former_header->loop_father->num,
+                          former_header->index);
+               else if ((unsigned) former_header->loop_father->num
+                        >= old_nloops)
+                 fprintf (dump_file, "fix_loop_structure: header %d of "
+                          "removed loop %d is part of the newly "
+                          "discovered loop %d with header %d\n",
+                          former_header->index, loop->num,
+                          former_header->loop_father->num,
+                          former_header->loop_father->header->index);
+             }
+         }
+#endif
        (*get_loops (cfun))[i] = NULL;
        flow_loop_free (loop);
       }