[LLVMdev] LLVMdev Digest, Vol 85, Issue 50
wendling at apple.com
Thu Jul 28 01:41:54 PDT 2011
On Jul 27, 2011, at 10:27 AM, Peter Lawrence wrote:
> 1) it is good to see that the "exception regions" idea has been abandoned, it is mathematically
> inconsistent with modern optimization theory, and at best would require extra passes to translate
> into/outof that representation form.
Yeah. I didn't want to obscure the main proposal by inappropriate nomenclature.
> 3.b) I have been thinking about other possible control-flow-graph invariants of the
> landingpad blocks and the catch blocks that they lead to, but so far have not come up
> with very muchl, I wonder if anyone else is thinking about this...?...
> for example cleanups come before __cxa_begin_catch, but it isn't clear what is a cleanup
> and what isn't other than what comes before a __cxa_begin_catch and what comes after ?
As John mentioned, the EH representation is independent (and indeed ignorant) of things like this. The front-ends need to generate the correct code.
> 4.b) it is not at all clear from your write up what the "cleanup" option for a landingpad is, and
> how this is used when both cleanups AND catches are necessary in a given try-catch source
> code statement, including if one of the user specified catches is a catch-all.
It's something I noticed from GCC's exception handling tables. If there's a cleanup that's been inlined, then even if that cleanup has "catches", it still is marked as a cleanup. As John mentioned, it's so that the personality function knows to stop at that function to run the cleanup.
> 5) its not clear from your email what is done with the result value of the landingpad instruction,
> but I presume that your intent is that this does not change from the current scheme where
> the "llvm.eh.typeid.for()" is called and its result is compared with the landingpad instruction's
The values the landingpad returns are those that are set by the personality function upon re-entry into the function. On X86, it's the EAX and EDX registers. One of those values is a pointer to the exception handling object. The other is a "selector" value, that we can then use to determine which (if any) of the clauses should be run.
> ...and then a miracle happens in CodeGen, and most of the intrinsics are thrown away and the
> hard register contents at the resumption at a landingpad from an Unwind include the value that
> llvm.eh.typeid.for() would have returned...
The llvm.eh.typeid.for is a hold-over from the old design. It's returns a constant value that can be compared against the "selector" the personality function returns. It remains because it gives an explicit representation of how the decision table of which catch to call is executed. It's similar to a series of if-then-elses.
> this is the sort of thing I'm talking about when I imply that the current scheme is poorly documented!
Indeed! And one of the outcomes will be much better documentation.
> Also, what is going to happen for the case of cleanup AND catches, currently the result of not
> only the llvm.eh.select() result is cached, but in fact the complete decoding of it relative to
> all the llvm.eh.typeid.for() calls is cached, then the cleanup code executed, THEN finally the
> already decoded value is used to "switch" from the landing pad to the correct catch-block.
> who is going to generate all that code, is it still going to be explicit in the IR, or is CodeGen going
> to now be responsible creating it.
It will be explicit in the IR, as it is now. :)
> 6) it would be nice if the existing UnwindInst could be retained. I wince at naming an instruction
> "Resume" since in the English language it is so ambiguous (resume normal execution following
> the conclusion of handing an exception, verses resume throwing an exception). IE cosmetics
> do matter.
The UnwindInst carries too much history with it to remain, and the new behavior is different than what the 'unwind' instruction. I agree with Chris that a mix of something like "resumeunwind" would make more sense.
> 7) there are still lots of other intrinsics/routines involved:
> __cxa_throw, cxa_rethrow
> __cxa_begin_catch(), __cxa_end_catch
> although these particular ones seem to be the easiest to document as they do seem to be
> translated verbatim (no CodeGen miracles).
It would involve hard-coding language-specific calls and ABIs into LLVM. That's something we try to avoid.
> 8) I really like the idea of "terminate" being one of the options to the landingpad
> instruction, it makes identification of abnormal code more direct (otherwise control-
> flow analysis has to be done to see if __terminate() is reachable to conclude that
> something is abnormal code, and I really don't like that analysis, it seems too error-
> prone as __terminate() might be reachable for other reasons (not that I have come
> up with such a scenario yet, but I think I might be able to), and this conclusion would
> then be ambiguous).
> Even if support for the terminate option required a new __llvm_personality_v0 and
> a new Unwind library function, I am still in favor of having and using it. But I suspect
> that CodeGen can lower this into the same old MC branch to a block that only contains
> __terminate() that we currently see in IR, and a new personality and Unwind
> aren't necessary, but would still be a nice optimization.
After we get the basic functionality down, we can discuss further changes like this. It's good to keep it in mind, though. As John mentioned, it may not be suitable in all cases, but for some it's a potential win.
More information about the llvm-dev