From e4ca2139f2fd864316e6fd4e76dea933c67621ab Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 5 Sep 2014 13:04:40 +0000 Subject: [PATCH] cfgloop.c (mark_loop_for_removal): Record former header when ENABLE_CHECKING. 2014-09-05 Richard Biener * 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 | 9 +++++++++ gcc/cfgloop.c | 4 ++++ gcc/cfgloop.h | 8 ++++++++ gcc/loop-init.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb2db3de737..5af9fd485db 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2014-09-05 Richard Biener + + * 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 * config/aarch64/arm_neon.h (int32x1_t, int16x1_t, int8x1_t, diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 789c45a8f03..399420ddbde 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 e868f5d4ba1..d62a4151cb0 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 26c953f71e5..e3734abadce 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); } -- 2.30.2