[LLVMdev] RFC: New EH representation for MSVC compatibility

Reid Kleckner
Mon, 18 May 2015 17:32:54 -0000

On Sat, May 16, 2015 at 7:29 AM, Steve Cheng <steve.ckp at gmail.com>
wrote:

> On 2015-05-15 18:37:58 -0400, Reid Kleckner said:
>
>  After a long tale of sorrow and woe, my colleagues and I stand here
>> before you defeated. The Itanium EH representation is not amenable to
>> implementing MSVC-compatible exceptions. We need a new representation
that
>> preserves information about how try-catch blocks are nested.
>>
>
> Hi,
>
> Newbie here. This must be a dumb question, but it's not something I can
> understand from reading the design documents and RFCs.
>
> Why don't we write and use our own personality function, and then we
avoid
> all these restrictions on the interval tables? On Windows, we would still
> have to catch exceptions with SEH, of course. But SEH should be
> language-independent, in the sense that it concerns only unwinding for the
> "low level" parts of the ABI, like restoring non-volatile
registers. It
> doesn't seem to make sense that LLVM, being a language-independent IR,
> should concern itself with personality functions specific to
Microsoft's
> C++ run-time library.
>
> I understand we want to link compatibility with object code from Visual
> Studio, but I didn't think that the personality-specific unwind tables
were
> actually an ABI "artifact". I mean, let's say you compile a
function in
> Visual Studio, the result is a function with some mangled symbol that other
> object code can make references through the linker. But the other object
> code never incestuously refers to the unwind tables of the function it
> calls, right?
>
> I'm speaking from the point of view of an implementor of a new
programming
> language who wants to interoperate with C++. I've already got code that
can
> decode the Microsoft RTTI info coming from C++ exceptions, and the pointers
> to those can be extracted with SEH GetExceptionPointers, etc. To support
> catching exceptions in my language, or at least calling cleanups while
> unwinding, I really don't care about the C++ personality function.
After
> all my language might not even have the concept of (nested) try/catch
> blocks. The custom personality function does have to be supplied as part of
> the run-time, but as a frontend implementor I'm prepared to have to
write a
> run-time anyway.
>

Right, doing our own personality function is possible, but still has half
the challenge of using __CxxFrameHandler3, and introduces a new runtime
dependency that isn't there currently. Given that it won't save that
much
work, I'd rather not introduce a dependency that wasn't there before.

The reason it's still hard is that you have to split the main function up
into more than one subfunction. The exception object is allocated in the
frame of the function calling __CxxThrow, and it has to stay alive until
control leaves the catch block receiving the exception. This is different
from Itanium, where the exception object is constructed in heap memory and
the pointer is saved in TLS. If this were not the case, we'd use the
__gxx_personaltity_v0-style landingpad approach and make a new personality
variant that understands MS RTTI.

We could try to do all this outlining in Clang, but that blocks a lot of
LLVM optimizations. Any object with a destructor (std::string) is now
escaped into the funclet that calls the destructor, and simple
transformations (SROA) require interprocedural analysis. This affects the
code on the normal code path and not just the exceptional path. While EH
constructs like try / catch are fairly rare in C++, destructor cleanups are
very, very common, and I'd rather not pessimize so much code.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20150518/cd2adcd8/attachment.html>