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.