Hello. Following patch fixes ICE in IPA ICF. Problem was that number of non-debug statements in a BB can change (for instance by IPA split), so that the number is recomputed.
Patch can bootstrap on x86_64-linux-pc and no regression has been seen. Ready for trunk? Thanks, Martin
gcc/ChangeLog: 2014-11-20 Martin Liska <mli...@suse.cz> * gimple-iterator.h (gsi_nondebug_stmt_count): New function. * ipa-icf-gimple.c (func_checker::compare_bb): Number of BB is recomputed because it can be split. gcc/testsuite/ChangeLog: 2014-11-20 Martin Liska <mli...@suse.cz> * gcc.dg/ipa/pr63909.c: New test.
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h index fb6cc07..f73b1f6 100644 --- a/gcc/gimple-iterator.h +++ b/gcc/gimple-iterator.h @@ -331,4 +331,18 @@ gsi_seq (gimple_stmt_iterator i) return *i.seq; } +/* Return number of nondebug statements in basic block BB. */ + +static inline unsigned +gsi_nondebug_stmt_count (basic_block bb) +{ + unsigned c = 0; + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); + gsi_next (&gsi)) + if (!is_gimple_debug (gsi_stmt (gsi))) + c++; + + return c; +} + #endif /* GCC_GIMPLE_ITERATOR_H */ diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c index 8f2a438..83661ac 100644 --- a/gcc/ipa-icf-gimple.c +++ b/gcc/ipa-icf-gimple.c @@ -563,6 +563,9 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2) gimple_stmt_iterator gsi1, gsi2; gimple s1, s2; + bb1->nondbg_stmt_count = gsi_nondebug_stmt_count (bb1->bb); + bb2->nondbg_stmt_count = gsi_nondebug_stmt_count (bb2->bb); + if (bb1->nondbg_stmt_count != bb2->nondbg_stmt_count || bb1->edge_count != bb2->edge_count) return return_false (); diff --git a/gcc/testsuite/gcc.dg/ipa/pr63909.c b/gcc/testsuite/gcc.dg/ipa/pr63909.c new file mode 100644 index 0000000..8538e21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr63909.c @@ -0,0 +1,27 @@ +/* { dg-options "-O2 -fno-guess-branch-probability" } */ + +int z; + +__attribute__((noinline)) +void g () +{ + if (++z) + __builtin_exit (0); + g (); +} + +__attribute__((noinline)) +void f () +{ + if (++z) + __builtin_exit (0); + f (); +} + +int main() +{ + f (); + g (); + + return 0; +}