Hi Bill, this proposal seems strangely complicated. I don't see the advantage
of the dispatch instruction over just attaching the information to each invoke.
Right now you have
invoke void @_Z3foov()
to label %invcont unwind label %catch.handlers
catch.handlers: landingpad
dispatch resume to label %...
catches [
%struct.__fundamental_type_info_pseudo* @_ZTIi, label %ch.int
%struct.__pointer_type_info_pseudo* @_ZTIPKc, label %ch.str
]
catchall [i8* null, label % ch.ca]
Why not combine this into:
invoke void @_Z3foov()
to label %invcont unwind resume to label %...
catches [
%struct.__fundamental_type_info_pseudo* @_ZTIi, label %ch.int
%struct.__pointer_type_info_pseudo* @_ZTIPKc, label %ch.str
]
catchall [i8* null, label % ch.ca]
? That would get rid of the "landingpad" basic block attribute, and rules about
what can branch to landing pads, that these cannot be split etc. Your rules
mean that you can uniquely associate a dispatch instruction with each invoke
unwind edge, so why not directly attach the dispatch information to the edge,
i.e. to the invoke?
Syntax:
dispatch resume to label<resumedest>
How do you say: if nothing is matched, keep unwinding out of the function?
Actually I don't see why <resumedest> is useful at all, since you can always
place a complete set of all handlers into one dispatch, so redispatching is
not needed. That said, it might be handy for reducing code duplication.
catches [
<type> <val>, label<dest1>
...
]
catchall [<type> <val>, label<dest> ]
personality [<type> <value>]
filters [
<type> <val>,<type> <val>, ...
You also need labels for filters. I know it may not look like it, but
if you inline a function with a filter into a function with handlers
then the filter ends up being nested inside outer handlers, resulting
in the need for a destination. In fact inlining also means that you
can't just list filters after catches, you need to consider maybe
having some catches, then a filter, then some other catches etc. Or
perhaps you want to take care of it by chaining dispatches via the
resumedest?
]
The `catches', `catchall', and `filters' clauses are optional. If neither `catches' nor `catchall' is specified, then the landing pad is implicitly a cleanup.
You may have cleanups to run even if there are handlers, how do you distinguish
between "have handlers, plus a cleanup to run in any case" and "have handlers,
no cleanup needs to be run if handlers don't match, just unwind straight
through"?
• The `filters' clause lists the types of exceptions which may be thrown by the
region.
What is "a region"?
onto.catch.handlers:
dispatch resume to %lpad
What is %lpad?
As a general remark, I don't see how this is superior to gcc's region scheme,
which could be adapted to LLVM by (in essence) attaching to an invoke the list
of all regions (and their info like list of catches) that contain the invoke.
If you do that then you get something rather close to your proposal, only the
dispatch instructions have become part of the invokes, you don't need the funny
landing pad special semantics etc.
Ciao,
Duncan.