<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Feb 3, 2015, at 9:56 AM, Reid Kleckner <<a href="mailto:rnk@google.com" class="">rnk@google.com</a>> wrote:</div><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Mon, Feb 2, 2015 at 7:05 PM, John McCall <span dir="ltr" class=""><<a href="mailto:rjmccall@apple.com" target="_blank" class="">rjmccall@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">> On Feb 2, 2015, at 6:04 PM, Reid Kleckner <<a href="mailto:rnk@google.com" class="">rnk@google.com</a>> wrote:<br class="">
> I actually like the unified intrinsic approach here. The backend already has to know things about the personality function. Until recently we would assume that the personality function wants an Itanium LSDA, for example, and dump that out into a target-specific section. Now on Windows we look at the personality function and try to figure out what kind of preparation and tables it wants.<br class="">
><br class="">
> It seems reasonable then that we could continue along the lines of classifying some personalities as "Itanium" personalities and lowering these new intrinsics out to __cxa_begin_catch / end_catch.<br class="">
<br class="">
</span>You are over-estimating how similar the code-generation patterns are going to be here.  The information flow from the unwind mechanism to the catch clause can differ quite wildly.<br class="">
<br class="">
Go look at what happens in the different ABIs when an exception with a non-trivial copy constructor is caught.  There’s an entire copy-construction that’s explicit in Itanium but which I believe is done implicitly by the personality equivalent in MSVC (necessarily, if you understand the purpose of __cxa_begin_catch/__cxa_end_catch).<br class=""></blockquote><div class=""><br class=""></div><div class="">Makes sense. LLVM shouldn't be too heroic about papering over the differences.</div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I agree that we should be more explicit about modeling the differences in personality-mandated code generation.  Perhaps if we did this, people would stop talking about the “Itanium LSDA” when they mean the gcc/g++ LSDA.  I just think there is zero benefit in pretending that we can actually model every useful difference between personalities with the name of the personality function.</blockquote><div class=""><br class=""></div><div class="">I guess that was my misunderstanding and I'm guilty of promoting that terminology. :)</div></div></div></div></div></blockquote><div><br class=""></div><div>No worries.  I actually want to apologize for my tone in that email; looking back, it feels over-the-top and rude.  I’m sorry about that.  You'd asked for my opinion in an area where I have a lot of expertise, which is supposed to be a reasonable thing to do. :)</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">The document leads one to believe that the tables are covered later, but now that I look again, I see there is very little information.</div></div></div></div>
</div></blockquote></div><br class=""><div class="">If I remember correctly, ARM actually documents their C++ LSDA layout, but that’s really just ARM indulging their habit of over-documenting stuff.</div><div class=""><br class=""></div><div class="">The key point here is to understand the designed separation between the C++ ABI, libUnwind, and the C++ runtime.  It’s easy to conflate them; the first two were really designed together, and in fact are specified together, and the compiler has to know about several different parts simultaneously.</div><div class=""><br class=""></div><div class="">It’s best to think of libUnwind (the “base exceptions ABI”, in the Itanium ABI’s terminology) as being its own, independent thing.  It’s deliberately designed to be language-independent, even to the point of supporting exception mechanisms (continuable exceptions) that AFAIK aren’t needed by any of the languages they were directly trying to support (C++, Ada).  libUnwind dictates some things as platform ABI, but only what it absolutely needs:</div><div class="">  - the process through which EH tables are found at all,</div><div class="">  - the CFI header on the EH tables, which includes basic information on how to unwind and where to find the personality function,</div><div class="">  - the basic structure of a language-independent exception object, and</div><div class="">  - the basic runtime interface to the unwind library.</div><div class=""><br class=""></div><div class="">Itanium then adds only a pretty small amount of extra, C++-specific ABI to this:</div><div class="">  - some additional structure of C++ exception objects and</div><div class="">  - some additional runtime functions which wrap libUnwind and track whether an exception is currently unwinding (for the purposes of std::uncaught_exception()).</div><div class=""><br class=""></div><div class="">Crucially, Itanium doesn’t describe the language-specific area of C++ EH tables.  Now, this is a part of the ABI document that’s sometimes just incomplete, but in this case, I’m fairly certain that not specifying the layout is intentional.  The ABI specifies the additional structure of C++ exception objects, with the intent that that should be sufficient for an arbitrary personality function to correctly recognize and handle a C++ exception, which is important for language interoperation.  I think the Itanium committee was more concerned about Ada/C++ interop, but to use an example closer to my heart:  consider the Objective-C personality function, which is used even in Objective-C++ modes and must therefore allow both Objective-C and C++ exceptions to be caught.</div><div class=""><br class=""></div><div class="">The C++ runtime library then just implements those functions.  libsupc++ / libc++abi also provide a default personality function, which then implies a particular LSDA layout; we decided to use the same LSDA layout as libsupc++ when implementing libc++abi because it simplified deployment and didn’t require additional compiler support.  But there’s no reason that you couldn’t have multiple “competing” C++ personality functions, because there’s not supposed to be a private contract between the C++ runtime and its personality function; that would preclude other languages from compatibly working with C++ exception objects.</div><div class=""><br class=""></div><div class="">The only things preventing us from using a new personality function for clang are:</div><div class="">  - deployment issues; the new function wouldn’t be guaranteed to exist in the C++ library, so we’d either need to provide it in compiler-rt or restrict it by deployment target, and</div><div class="">  - the usual small issues of finding time to design and implement a new LSDA layout. :)</div><div class=""><br class=""></div><div class="">John.</div></body></html>