Hi Chris,>>> Is it intended that "cleanup ty_1, ty_2" potentially be different to >>> "cleanup ty_1 cleanup ty_2"? Perhaps this is useful for funky personality >>> functions. >>> >> Yeah. One can basically interleave the catches and filters. But having two catch or two filter clauses in a row should be semantically the same as the clauses being merged into one. (E.g., your examples would be equivalent.) > > Let me rephrase the question then. Why not make the grammar be either: > >>>> <clause> :>>>> cleanup >>>> | catch<ty_1> >>>> | filter<ty_1> > > .. forcing "catch" or "filter" before each entry. If you don't like that, why not make the grammar be something like: > >>>> %res = landingpad<somety> personality<ty> <pers_fn> (catch<ty>+)? (filter<ty>+)? > > Is there anything specific about the ordering of catch or filter clauses that affect semantics? If so, the first alternative seems cleaner. If not, the second does.yes there is something about the order :) When front-ends output code, all catches come before filters, but after inlining you can get: catches, filters, catches, filters etc and this ordering needs to be preserved. Also, filters are different from catches: filter ty_1, ty_2, ..., ty_N matches any exception that would not be caught by any of ty_1, ty_2, ..., ty_N. This is quite different to filter ty_1, filter ty_2, ..., filter ty_N. For example, suppose you throw ty_2. Then the filter ty_1, ty_2, ..., ty_N wouldn't match that, but filter ty_1 would. So filter ty_1, ..., ty_N makes sense; but I don't think catch ty_1, ..., ty_N makes sense.>>> Another comment is: rather than using a function pointer for the personality >>> function (and requiring a declaration for the personality), maybe it could >>> just be a string? After all, you don't actually do anything much with it: >>> you just dump the name into the assembler. Perhaps the same goes for catches >>> and so on: is a global really needed and not its name? >>> >> I'm hesitant to do this because the machinery for printing out the correct global value's representation in assembly is already in the code. > > IMO, it is clearly the right thing to have a GV here instead of a string.I agree :)>>> Finally, rather than baking cleanups, filters etc into the IR, I suppose the >>> landingpad instruction could just be: >>> >>> %res = landingpad<some type> data<ty> >>> >>> For standard setups "data" could be a struct type, with fields for the >>> personality function, a cleanup flag, lists of catches and filters and so on. >>> >> True, but this makes the IR less readable for me. I would have to look at a global to understand what this instruction is doing. Plus, we have problems with the "funky personality function" situation. With the proposal, we can interleave the clauses. With the 'data' option, we would have to have a non-IR way of interpreting the struct. So we're kind of back to the situation we have with the intrinsics... > > I agree with Bill in this case. The reason for landingpad to be an instruction is a) make it clear that it is magic in several ways (e.g. pinned to the start of a block), and b) so that LandingPadInst can have a bunch of useful accessors on it.The idea wasn't to not make it be an instruction, it was to stick all the catches and filters in a global, so that they don't have to be baked into the definition of the instruction. However I now think that that's not a good idea - I'm happy with the original version of the instruction (modulo tweaks like those discussed above). Ciao, Duncan.
On Aug 2, 2011, at 10:28 AM, Duncan Sands wrote:>>>> Is it intended that "cleanup ty_1, ty_2" potentially be different to >>>> "cleanup ty_1 cleanup ty_2"? Perhaps this is useful for funky personality >>>> functions. >>>> >>> Yeah. One can basically interleave the catches and filters. But having two catch or two filter clauses in a row should be semantically the same as the clauses being merged into one. (E.g., your examples would be equivalent.) >> >> Let me rephrase the question then. Why not make the grammar be either: >> >>>>> <clause> :>>>>> cleanup >>>>> | catch<ty_1> >>>>> | filter<ty_1> >> >> .. forcing "catch" or "filter" before each entry. If you don't like that, why not make the grammar be something like: >> >>>>> %res = landingpad<somety> personality<ty> <pers_fn> (catch<ty>+)? (filter<ty>+)? >> >> Is there anything specific about the ordering of catch or filter clauses that affect semantics? If so, the first alternative seems cleaner. If not, the second does. > > yes there is something about the order :) When front-ends output code, all > catches come before filters, but after inlining you can get: catches, filters, > catches, filters etc and this ordering needs to be preserved. Also, filters > are different from catches: filter ty_1, ty_2, ..., ty_N matches any exception > that would not be caught by any of ty_1, ty_2, ..., ty_N. This is quite > different to filter ty_1, filter ty_2, ..., filter ty_N. For example, suppose > you throw ty_2. Then the filter ty_1, ty_2, ..., ty_N wouldn't match that, > but filter ty_1 would. > > So filter ty_1, ..., ty_N makes sense; but I don't think catch ty_1, ..., ty_N > makes sense.Agreed. Other notes: a zero-type filter is meaningful (and pretty common — it's the result of 'throw()'), but the ordering of the cleanup bit is not, so I would suggest this grammar: Instruction ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? LandingPadClause* LandingPadClause ::= 'catch' TypeAndValue LandingPadClause ::= 'filter' TypeAndValue* John.
On Aug 2, 2011, at 4:43 PM, John McCall wrote:> On Aug 2, 2011, at 10:28 AM, Duncan Sands wrote: >>>>> Is it intended that "cleanup ty_1, ty_2" potentially be different to >>>>> "cleanup ty_1 cleanup ty_2"? Perhaps this is useful for funky personality >>>>> functions. >>>>> >>>> Yeah. One can basically interleave the catches and filters. But having two catch or two filter clauses in a row should be semantically the same as the clauses being merged into one. (E.g., your examples would be equivalent.) >>> >>> Let me rephrase the question then. Why not make the grammar be either: >>> >>>>>> <clause> :>>>>>> cleanup >>>>>> | catch<ty_1> >>>>>> | filter<ty_1> >>> >>> .. forcing "catch" or "filter" before each entry. If you don't like that, why not make the grammar be something like: >>> >>>>>> %res = landingpad<somety> personality<ty> <pers_fn> (catch<ty>+)? (filter<ty>+)? >>> >>> Is there anything specific about the ordering of catch or filter clauses that affect semantics? If so, the first alternative seems cleaner. If not, the second does. >> >> yes there is something about the order :) When front-ends output code, all >> catches come before filters, but after inlining you can get: catches, filters, >> catches, filters etc and this ordering needs to be preserved. Also, filters >> are different from catches: filter ty_1, ty_2, ..., ty_N matches any exception >> that would not be caught by any of ty_1, ty_2, ..., ty_N. This is quite >> different to filter ty_1, filter ty_2, ..., filter ty_N. For example, suppose >> you throw ty_2. Then the filter ty_1, ty_2, ..., ty_N wouldn't match that, >> but filter ty_1 would. >> >> So filter ty_1, ..., ty_N makes sense; but I don't think catch ty_1, ..., ty_N >> makes sense. > > Agreed. Other notes: a zero-type filter is meaningful (and pretty > common — it's the result of 'throw()'), but the ordering of the cleanup > bit is not, so I would suggest this grammar: > > Instruction ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? LandingPadClause* > LandingPadClause ::= 'catch' TypeAndValue > LandingPadClause ::= 'filter' TypeAndValue* >*smacks forehead* Duncan and John are exactly right with regards to filters. In my zeal today, I took out the code that would parse the 'filter' clause correctly. I'll add that back in and submit a corrected patch. -bw