This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: tail call optimizations
- To: Jeffrey A Law <law at cygnus dot com>
- Subject: Re: tail call optimizations
- From: Richard Henderson <rth at cygnus dot com>
- Date: Wed, 22 Mar 2000 17:55:16 -0800
- Cc: Jason Merrill <jason at cygnus dot com>, gcc-patches at gcc dot gnu dot org
- References: <u98zzaecu9.fsf@yorick.cygnus.com> <14543.953774670@upchuck>
On Wed, Mar 22, 2000 at 06:24:30PM -0700, Jeffrey A Law wrote:
> > This seems to be because the pointer to the
> > exception object is a SAVE_EXPR around a call to __eh_alloc
...
> > so the pointer passed to __cp_push_exception is not the pointer
> > to the object we just initialized.
> In general, if a particular call might throw, then we can not perform
> tail call optimizations.
This is unrelated to Jason's problem. IIRC, __cp_push_exception
*can't* throw. The problem is one of its arguments got evaluated
too many times. Not during the two expansions for the call_placeholder,
but because the same SAVE_EXPR appears in multiple CALL_EXPRs and
we unsaved the result.
> I don't know if this is related to your problem, but it is the primary
> reason why (IMHO) tail calls optimizations are not particularly useful
> for C++.
Previously your code had !flag_exceptions turning off the whole
sibcall thing. I removed that, because the thing you were trying
to protect against -- sibcall with an EH region in scope -- is
handled just fine by the single outgoing edge requirement.
More than once the C++ team has asked us to be more careful not
disabling optimization when there's no EH region. Something that
probably happens a lot more than you're giving credit.
Anyway, this bug could have surfaced in C or anywhere else. I'm
not familiar enough with the C front end to know how to get it to
generate SAVE_EXPRs on demand, but *that* is the crux of the
problem, not the exception handling.
There are two solutions.
One, simply refuse SAVE_EXPRs and RTL_EXPRs. According to my
previous survey, this probably isn't a big loss. We still need
the UNSAVE_EXPR wrappers to clean up after CALL_EXPRs and
TARGET_EXPRs.
Two, pre-evaluate dangerous exprs and put the result in a
temporary VAR_DECL that we _can_ expand multiple times.
r~