[LLVMdev] RFC: Exception Handling Proposal II

Renato Golin renato.golin at arm.com
Wed Nov 24 02:59:14 PST 2010


Hi Bill,

First, I like the idea of being more expressive in IR, since the old
exception handling style didn't quite express exception handling, but
alternate paths (resume/unwind). That made DwarfException.cpp a big
hack. ;)

It also makes the front-end engineer's life a lot easier, since there
is less need to keep a long list of global state for all current
landing pads, clean up areas, terminate handlers, etc.


If I got it right, the dispatch instruction will tell the
instructions/calls to unwind to specific landing pads (cleanup areas,
terminate), but the region number will encode try/catch areas, so that
all those cleanup landing pads should ultimately end up in the catch
area for that region.

If that's so, how do you encode which which landing pad is to be
followed per region?

Consider the following code:

try {
  Foo f();
  f.run(); // can throw exception
  Bar b();
  b.run(); // can throw exception
  Baz z();
  z.run(); // can throw exception
} catch (...) {
}

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.

So, if the dispatch instruction points to a catch area, how do you
differentiate between clean-up areas? If they point to clean-up areas,
how to you specify a catch area per group, to go after cleaning?


My second question is, why did you keep the invoke?

As far as I got it, you have a dispatch instruction inside a basic
block, and whatever throws an exception there should unwind to the
dispatch area (if it matches the filters), in order of appearance,
ending in the "resume unwinding" path if none matches.

If that's so, why do you still have the invoke call? Why should you
treat call-exceptions any differently than instruction-exceptions?

Since this is a major refactoring of the IR (new back-ends won't
understand old IRs at all), there is no point of keeping
compatibility...


> * The "catchall", "catches", and "filters" clauses are optional. If none are
>  specified, then the landing pad is implicitly a "cleanup."
>
> * The <resumedest> basic block is the destination to unwind to if the type
>  thrown isn't matched to any of the choices.
>
> * The "catches" clause is a list of types which the region can catch and the
>  destinations to jump to for each type.
>
> * The "catchall" clause is the place to jump to if the exception type doesn't
>  match any of the types in the "catches" clause.
>
> * The "region" value is an integer, similar to the "addrspace" value, and is
>  unique to each dispatch in a function. IR objects reference this value to
>  indicate that they belong to the same region.
>
> * The "filters" clause lists the types of exceptions which may be thrown by the
>  region.

These are major enhancements over the current model, as the back-end
doesn't have to guess anything. Both C++ and Java have those concepts
explicit in the language and (AFAIK) that was somewhat lost in the
"encoding".


best,
--renato




More information about the llvm-dev mailing list