[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