[LLVMdev] RFC: Exception Handling Proposal II
John McCall
rjmccall at apple.com
Wed Nov 24 11:18:22 PST 2010
On Nov 24, 2010, at 5:36 AM, Bill Wendling wrote:
> On Nov 24, 2010, at 4:58 AM, John McCall wrote:
>>
>>> The object 'f' is in a different cleanup area than 'b' which, in turn
>>> is in a different area than 'z'. These three regions should point to
>>> three different landing pads (or different offsets in the same landing
>>> pad), which (I believe) are encoded in IR by being declared after
>>> different dispatch instructions, all of which within the same region.
>>
>> Nope. Three regions, three landing pads, three dispatch instructions.
>> (actually four if Foo::Foo() can throw). The Baz-destructing region
>> chains to the Bar-destructing region which chains to the Foo-destructing
>> region which chains to the catching region; the first three are
>> cleanup-only.
>>
> Ah ha! I think I had a different mental model than you did. Or at least I remembered things differently from the discussion. :-) For me, there is one dispatch per region, which is why I had the region number associated with the invokes as well as the "unwind to" edge coming from them. (See my response to Renato for a description.) I'll think more about your model...
Hmm. The difference between our models is actually in what we're calling a region. In your model, adding a cleanup doesn't require a new region; you just create a new landing pad which does the cleanup and then branches to (I guess) the landing pad of its containing cleanup. So landing pads are many-to-one with regions and dispatch instructions. In my model, every independent landing pad is necessarily a region. So in my model, there is also one dispatch per region, but there are more regions.
So, in this example:
A { A(); ~A() throw(); };
void foo() throw() {
A x;
b();
}
Your model has this as follows, modulo syntax:
entry:
%x = alloca %A
invoke void @A::A(%A* %x) to label %succ0 unwind label %lp0 region 0
succ0:
invoke void @b() to label %succ1 unwind label %lp1 region 0
succ1:
call void @A::~A(%A* %x) nounwind
ret void
lp0:
call void @A::~A(%A* %x) nounwind
br label %lp1
lp1:
dispatch region 0 [filter i8* null] # no resume edge
Whereas my model has this as follows:
entry:
%x = alloca %A
invoke void @A::A(%A* %x) to label %succ0 unwind label %lp0 region 0
succ0:
invoke void @b() to label %succ1 unwind label %lp1 region 1
succ1:
call void @A::~A(%A* %x) nounwind
ret void
lp0:
call void @A::~A(%A* %x) nounwind
dispatch region 0 [], resume label %lp1
lp1:
dispatch region 1 [filter i8* null] # no resume edge
I think my model has some nice conceptual advantages; for one, it gives you the constraint that only EH edges and dispatch instructions can lead to landing pads, which I think will simplify what EH preparation has to do. But I could be convinced.
John.
More information about the llvm-dev
mailing list