The problem stems from tree-ssa-tail-merge that breaks bb->count, The CFG looks like
2 / \ / 6 5 (0) | | 3 <----- | / \ | | 7 (1) 8 - | / 4 (1) (in parenthesis the bb->count from gcov) 2 / \ / 6 / | | 3 <-- | / | | 5 (0) 8 -- | | 4 (1) so 5 and 4 are now in different partitions, producing an assertion because there is no EDGE_CROSSING between them. I can see 3 solutions to this 1) merge the BB counts in tree-ssa-tail-merge.c, so 5 is in the same partition that 4 2) don't tail-merge blocks that belong to different partitions. 3) add a EDGE_CROSSING flag on the edge between 4 and 5. 1) fixes the problem, so 5 and 4 are now in the same partition. The fix is quite trivial, as with attached. the other solution 2) is more conservative, and also fixes the problem. I don't think 3) is necessary. more ideas ? thanks, Christian On 09/11/2012 06:21 PM, Jakub Jelinek wrote: > On Tue, Sep 11, 2012 at 05:40:30PM +0200, Steven Bosscher wrote: >> On Tue, Sep 11, 2012 at 5:31 PM, Christian Bruel <christian.br...@st.com> >> wrote: >>> Actually, the edge is fairly simple. I have >>> >>> BB5 (BB_COLD_PARTITION) -> BB10 (BB_HOT_PARTITION) -> EXIT >>> >>> and BB10 has no other incoming edges. and we are duplicating it. >> >> That is wrong, should never happen. Is there a test case to play with? >> It'd be good to have a PR for this. > > Isn't that the standard case when !HAVE_return ? Then you can have only a > single return through epilogue, and when the epilogue is in the hot > partition, even if cold code is returning, it needs to jump to the epilogue. > > Jakub >
Index: tree-ssa-tail-merge.c =================================================================== --- tree-ssa-tail-merge.c (revision 191129) +++ tree-ssa-tail-merge.c (working copy) @@ -1478,6 +1478,8 @@ bb2->frequency = BB_FREQ_MAX; bb1->frequency = 0; + bb2->count += bb1->count; + /* Do updates that use bb1, before deleting bb1. */ release_last_vdef (bb1); same_succ_flush_bb (bb1);