http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50243
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |matz at gcc dot gnu.org, | |rth at gcc dot gnu.org --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> 2013-04-03 07:15:30 UTC --- I think the patch in this form looks undesirable, we could often generate worse code (containing many more rethrows than really needed). If we keep the clobbers there, it might prevent EH optimizations from happening. See PR51117 for more details. So, either we'd need to run DSE before the EH optimizations, or perhaps we could just make optimize_clobbers smarter. As in, look through all the clobbers (+ debug stmts) after the externally throwing resx, and when we reach the first, check the VUSE of the first clobber. If the VUSE's VDEF is a PHI at the beginning of block, then optimize all the clobbers away, if the VDEF is in a different bb and the path from that other bb to the current one is through some EH edges, also optimize those away, but if the VDEF is non-PHI in the same bb, keep the clobber around, and similarly if the VDEF is in some other bb and there is no EH (or complex of any kind?) edge in between, keep the clobbers. If there are some other stores, the current EH cleanup pass won't be able to optimize anything anyway, so the clobbers there don't pessimize anything. On this particular testcase we have: <L1>: # .MEM_13 = VDEF <.MEM_4> MEM[(struct iface *)this_2(D)]._vptr.iface = &MEM[(void *)&_ZTV5iface + 16B]; # .MEM_14 = VDEF <.MEM_13> MEM[(struct iface *)this_2(D)] ={v} {CLOBBER}; resx 2 <L2>: # .MEM_10 = VDEF <.MEM_14> *this_2(D) ={v} {CLOBBER}; resx 1 so I'd say we want to remove the second clobber, as it is desirable the EH cleanup considers the bb as empty, but keep the first clobber, there is code before it anyway and it will be useful to attempt to DSE it. It would be nice if we had some later EH cleanup clean it up if we DSE the store. Looking through passes.c, we schedule another pass_cleanup_eh quite late, so that could be taken care of. Another pass that calls optimize_clobbers/sink_clobbers is the lower eh dispatch pass, don't remember what exact changes does it do to the EH depending on whether there is code before resx or not, and whether it is something some other pass (cleanup EH?) is able to optimize later. If not, we should either teach the cleanup empty eh pass to optimize it, if e.g. DSE etc. makes those blocks empty (+ optimize_clobbers), or add a new pass that would do that.