[LLVMdev] Inlining and exception handling in LLVM and GCC

Bill Wendling wendling at apple.com
Mon Dec 13 13:42:25 PST 2010


On Dec 7, 2010, at 12:20 PM, Duncan Sands wrote:

> In the case of Bill's proposal this property holds because of special rules
> about what you are allowed to do with landing pads: you are not allowed to move
> a dispatch instruction out of a landing pad etc.

I hope I didn't misstate this, but you can move it out of a landing pad, however the landing pad must dominate the dispatch. For instance, code like this:

lpad: landingpad
  call void @a_cleanup_function()
  dispatch …

may inline the @a_cleanup_function() call, which may result in the dispatch no longer being in the landing pad.

> These rules could actually
> be applied to eh.selector without any IR changes providing much the same effect
> without a new instruction.  However the reason for not doing this is that it
> then makes some optimizations impossible, for example when you inline a call
> to _Unwind_Resume through an invoke you would like to turn it into a branch to
> the landing pad, but this would result in eh.selector calls that fail the rules.
> It's not clear to me if the dispatch instruction has this problem too, I need
> to ask Bill about it.
> 
> In fact Bill's proposal mostly seems to be about replacing the current explicit
> sequence of comparisons that llvm-gcc uses to find which handler to run (I guess
> everyone who has looked at LLVM IR with exception handling in it has seen all
> the calls to eh.typeid.for, the comparisons and the branching that I'm talking
> about here) with a more compact representation that is easier to analyse.  As
> such, from my point of view it doesn't really have much to do with the inlining
> issue, which is not to say it doesn't have merit on other grounds.

The compactness of information and ease of analysis are what I think of as the key advantages of my proposal. Also, it doesn't rely upon intrinsics, but builds the EH into the IR explicitly.

> An interesting point is that Bill's dispatch instruction is quite analogous to
> GCC's gimple_eh_dispatch statement.  This statement represents the transfer of
> control to the appropriate catch handler for an exception region, and is at a
> fairly high level of abstraction.  It takes an exception handling try region as
> an argument (it can also have an "allowed exceptions" region as an argument,
> but there's no added value in discussing that).  Since the list of associated
> catches is stored in the region info, there is no need for it to explicitly
> list tries and where to branch to, while Bill is obliged to put the info that
> GCC stores in the region directly into his dispatch instruction.
> 
> Once GCC has finished running the inliner it runs the lower_eh_dispatch pass,
> which removes all gimple_eh_dispatch statements by turning them into explicit
> control flow: a sequence of comparisons and branches (exactly like the code
> llvm-gcc/clang produce right now, comparing the selector value with the result
> of eh.typeid.for calls).  Since my proposal doesn't change this aspect of LLVM,
> you can consider that before this pass GCC's representation is like Bill's and
> after it is like in my proposal.

Interesting. . . How do they handle LTO with exception handling if the gimple_eh_dispatch statements are all ready lowered?

>> So, in view of their equivalence, I think Bill's proposal is better
>> for two reasons:
>> 
>>   1. It eases the future elimination of invoke, or at least, the
>> treatment of current instruction-level exception (as in Java) in a
>> cleaner way.
> 
> I don't see what is cleaner about it, except that it is overall at a higher
> level of abstraction (see above).

I also think that both of our proposals are flexible enough to handle the future elimination of invokes and support of basic block throws (as you explained in a future email).

>>   2. It reinforces the idea of having one personality function for
>> each EH table (ie. per function), especially when inlining code from
>> different paradigms (if that's possible).
> 
> According to Bill's proposal each dispatch instruction can specify a different
> personality function, so it's just the same as my proposal in this respect.

Yeah. Multiple personality functions per function is something Chris has a mild interest in. The devil is in the details, of course.

>> However, your proposal is better in two other accounts:
>> 
>>   1. If we do want to support EH tables with multiple personalities in
>> the future.
> 
> As mentioned above, Bill's proposal also supports multiple personalities per
> function.
> 
>>   2. It's less invasive and closer to the problem it meant to fix in
>> the first place. So it'll be faster and easier to do that way.
>> 
>> 
>> It's more of a design decision, IMO.
> 
> Exactly, and this brings up the question of what criteria should be used to
> decide which proposal is best.  Presumably, all else being equal, whichever
> one makes it easiest to optimize the IR.  I didn't yet think about the
> advantages and disadvantages of each proposal in this respect.


I have my own opinions, of course. But I think there are two criteria which should be met:

1. Firstly, it must work and work well. I.e., it will solve all of our current EH problems – it's slow, it doesn't follow any ABI, it's fragile, it requires expensive transformations before code-gen – and

2. It must be flexible enough for future changes.

Here are some of the things I would like to have:

1. Limited use of intrinsics.
   Reasoning: Intrinsics are indistinguishable from calls. And as such are harder to work with than IR instructions.

2. EH metadata shouldn't be encoded in the CFG if at all possible.
   Reasoning: The IR is meant for executable instructions. As such, transformations don't know about or care about any EH metadata there.

3. The front-ends should be able to emit the EH data easily.
   Reasoning: The front-end guys are just down the hall from me and I sit with my back to the door. :-)

-bw

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20101213/385d8a19/attachment.html>


More information about the llvm-dev mailing list