> New constructs: > > { exc_ptr, filter } = EH_LANDING_PAD; > > Placeholder for the landing-pad rtl. Has 2 outputs > for both the exception pointer and the filter.
Hmm, EH_LANDING_PAD will still need to be somewhat special (as moving it across eh edge or something will change behaviour) but it indeed seems uite sane representation of fact that the EH/filter is really set by runtime... > > EH_DISPATCH (filter); > > Placeholder for the switch statement that we'll > generate to jump between the alternatives for > different catches. Similarly here, it seemed to me that normal switch would suffice. > > ERT_NOP > > A new type of exception region that merely implies > a different landing pad to the containing region. > Inserting one of these below the "current" region > is how we'll split critical edges, instead of copying > regions. I am not sure how this will work. When you have throwing statement inside several catch...try regions with different types caught, you will have multiple EH edges from that statement. It seems that all those edges are neccesary since runtime can really deliver control flow to any of the try..catch handlers. We might want to redirect edge that does not correspond to the innermost try...catch that is where we need to copy nontrivial chain of EH regions for specific redirection. You intend to represent this by ERT_NOP? > After inlining, we have a new pass that expands both RESX and EH_DISPATCH: > > BB5: > e2 = e1; > f2 = f1; > # succ 7 > > BB7: > switch (f2) > { > case 1: goto BB8; > case 2: goto BB9; > default: goto BB10 > } > # succ 8 9 10 > > BB10: > _Unwind_Resume (e2); Seems sane. Removing fully optimized out cleanups still benefits from RESX not being lowered to _Unwind_Resume, but the lowering can happen somewhere at later half of the optimization queue, it is not probably going to bring that much new optimization oppurtunities. > > There are a couple of advantages that ought to be clear immediately. > First, no more silliness that tree_empty_eh_handler_p has to clean up. > Second, everything can be properly put into SSA form. > Third, we're not too late to easily generate switch statements. See > > /* ??? It is mighty inconvenient to call back into the > switch statement generation code in expand_end_case. > Rapid prototyping sez a sequence of ifs. */ > > which has been in except.c for nearly 10 years. Yep, I also found this comment entertaining ;) > > We decide we want to split edge BB1->BB7, so we modify: > > EH Region Tree: > 1 cleanup -> { e1, f1 }, land = BB7, post-land = BB8 > 2 cleanup -> { e2, f2 }, land = BB5, post-land = BB6 > 3 nop -> { e1, f1 }, land = BB9, post-land = BB8 > > BB1: > bar(); [EH 3] > # succ 2 9(eh) > > BB9: > { e1, f1 } = EH_LANDING_PAD; > # succ 8 > > Which, if I'm not mistaken, duplicates far less code than you > do at present to split these edges. Hmm, if I understand right, edge rediretion now involve creation of new BB. I don't think it is very lucky solution. With current implementation EH redirection behave same way as redirection of normal edges. We don't duplicate code, just pieces of EH tree and when we end up redirecting things back, we cleanup. So passes don't need to care EH edges specially and also critical edge splitting is fully undone by cfg+eh cleanup when nothing is inserted over the split paths. > EH optimization: > > This pass would remove shadowed exception handlers and other > unreachable code. It's supposed to be currently handled in Yes, current way of handling via unreachable code don't work as originally was designed to, so I hoped to move this code away too. We will need to propagate lists of types into every resx and propagate where the resx can be reached, but it don't seem that difficult to do. > (As an aside, the dead handler elimination we attempt in > reachable_next_level doesn't work because the C++ front end > tells us that __cxa_end_catch can throw, which is only true > when the thrown object has a destructor that can throw. With > a single extra check in the front end, we can set the NOTHROW > bit on that __cxa_end_catch call and re-enable this.) Hmm, we probably should fix this... But still there is problem that originally we didn't have RESX->outer region edges as we do now, so regions that has types completely shadowed by inner regions we will still have it reachable from the RESX of inner regions (that no longer have the type info) I will need to look into this tomorrow. Thanks for writting this up! Honza