aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cfgloop.c4
-rw-r--r--gcc/cfgloop.h8
-rw-r--r--gcc/loop-init.c35
4 files changed, 56 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bb2db3d..5af9fd4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 789c45a..399420d 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -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);
}
+
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index e868f5d..d62a415 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -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. */
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index 26c953f..e3734ab 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -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);
}