Message ID | 4E6F786E.6080407@codesourcery.com |
---|---|
State | New |
Headers | show |
On 09/13/2011 08:36 AM, Bernd Schmidt wrote: > On 09/13/11 15:05, Richard Sandiford wrote: >> It just feels like checking for trap_if or turning off cross-jumping >> are working around problems in the representation of shrink-wrapped >> functions. There should be something in the IL to say that those >> two blocks cannot be merged for CFI reasons. > > There is - JUMP_LABELs and such, and the simple_return vs return > distinction. This works for essentially all the interesting cases. The > problem here is that we don't have a jump as the last insn. So how about > the solution in crossjumping as below? > >> Maybe two flags on >> the basic block to say whether they start (resp. end) with the >> "wrapped" version of the CFI? (Which unfortunately would need >> to be checked explicitly.) > > I think that's overdesigning it, and it breaks as soon as something > discards the bb info (reorg...) or puts a label in the middle of a > prologue or epilogue. Keeping that up-to-date would be much more > fragile than just manually dealing with the few cases where we can't > tell what's going on. > >> OTOH, if another reviewer thinks that's unreasnable, I'll happily >> defer to them. > > Cc'ing rth for a second opinion... It feels hacky, but I don't have anything better to suggest. I think the patch is ok. r~
Index: gcc/cfgcleanup.c =================================================================== --- gcc/cfgcleanup.c (revision 178734) +++ gcc/cfgcleanup.c (working copy) @@ -1488,6 +1488,16 @@ outgoing_edges_match (int mode, basic_bl edge e1, e2; edge_iterator ei; + /* If we performed shrink-wrapping, edges to the EXIT_BLOCK_PTR can + only be distinguished for JUMP_INSNs. The two paths may differ in + whether they went through the prologue. Sibcalls are fine, we know + that we either didn't need or inserted an epilogue before them. */ + if (flag_shrink_wrap + && single_succ_p (bb1) && single_succ (bb1) == EXIT_BLOCK_PTR + && !JUMP_P (BB_END (bb1)) + && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1)))) + return false; + /* If BB1 has only one successor, we may be looking at either an unconditional jump, or a fake edge to exit. */ if (single_succ_p (bb1)