[LLVMdev] Alternative exception handling proposal

John McCall rjmccall at apple.com
Wed Dec 1 15:20:55 PST 2010


On Dec 1, 2010, at 1:37 PM, Duncan Sands wrote:
> Inlining
> --------
> 
> Many a plausible seeming exception handling scheme has fallen by the way-side
> because it interacts poorly with inlining.
> 
> Here is how inlining would work with this scheme.  It's pretty close to how
> it works right now.  Suppose you have
> 
>   invoke void @foo()
>           to label %invcont unwind label %lpad <foo catch info>
> 
> and you want to inline foo.  Suppose foo contains an invoke:
> 
>   invoke void @bar()
>           to label %invcont2 unwind label %lpad2 <bar catch info>
> 
> Then after inlining you have an invoke of bar in which foo's catch info
> has been appended to bar's:
> 
>   invoke void @bar()
>           to label %invcont2 unwind label %lpad2 <joined catch info>
> 
> What does appending <foo catch info> to <bar catch info> mean?  If the
> personality functions are different then you are in trouble and need to
> disallow the inlining!  The cleanup flag is the "or" of the foo and bar
> cleanup flags.  The catches are the bar catches followed by the foo
> catches.

You are greatly underestimating the amount of work the inliner has to do under this proposal.  In fact, the only thing that your proposal simplifies is DwarfEHPrepare.

The inliner would still need to do two extra things: 

1.  It would need to adjust landing pads so that they forward selectors they don't understand to the enclosing landing pad.  Consider the following code:

 void a();
 void b() {
   try { a(); } catch (int i) {}
 }
 void c() {
   try { b(); } catch (float f) {}
 }

The landing pad in b() only has one case to worry about, so it's naturally going to immediately enter the catch handler for 'int'.  This is obviously semantically wrong if the combined invoke unwinds there.

2.  It would need to rewrite calls to _Unwind_Resume on cleanup-only paths if the enclosing invoke has a handler.  The EH machinery does not expect a landing pad which claims to handle an exception to just call _Unwind_Resume before handling it;  that's why we currently have to use hacks to call _Unwind_Resume_or_Rethrow instead.

Also, some platforms provide an alternative to _Unwind_Resume that doesn't require the compiler to pass the exception pointer;  we'd like to be able to use those.

The 'dispatch' instruction simplifies this by presenting an obvious place to rewrite (which doesn't actually require rewriting — you just add/redirect the 'resume' edge to point to the enclosing landing pad).

John.



More information about the llvm-dev mailing list