[PATCH] D12353: [WinEH] Update coloring to handle nested cases cleanly
Joseph Tremoulet via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 26 12:47:56 PDT 2015
JosephTremoulet added inline comments.
================
Comment at: test/CodeGen/WinEH/wineh-cloning.ll:269-270
@@ +268,4 @@
+; %inner is a cleanup which appears both as a child of
+; %left and as a child of %right. Since statically we
+; need each funclet to have a single parent, we need to
+; clone the entire %inner funclet so we can have one
----------------
JosephTremoulet wrote:
> JosephTremoulet wrote:
> > majnemer wrote:
> > > When you say each funclet needs to have a single parent, do you mean that it must have a single non-invoke predecessor? It will be quite common for a set of invokes in a try-block to have the same unwind destination.
> > I mean that all of its invoke predecessors, after cloning, must be in the same funclet.
> This might be a more illustrative example:
> ```
> define void @foo() personality etc {
> entry:
> invoke void @f()
> to label %exit unwind label %funcletA
> funcletA:
> %A = catchpad []
> to label %bodyA unwind label %endpad
> bodyA:
> invoke void @g()
> to label %invoke.cont unwind label %endpad
> invoke.cont:
> invoke void @h()
> to label %retA unwind label %funcletB
> retA:
> catchret %A to label %exit
> funcletB:
> %B = cleanuppad []
> call void @i()
> cleanupret %B unwind to caller
> exit:
> ret void
> }
> ```
>
> Say we enter `@foo()` and generate a stack frame for it, then the call to `@f()` raises an exception that is handled by `funcletA`, so the runtime calls `funcletA` (and we generate a stack frame for it). Now there are two `invoke`s in `funcletA`, both of which are handled by `funcletB`, but if the call to `@g()` faults the `endpad` indicates that the runtime needs to unwind out of `funcletA` before calling `funcletB`, whereas if the call to `@h()` faults then the runtime is supposed to invoke `funcletB` while `funcletA`'s frame is still on the stack. I don't think we can expect WinEH targets to support encoding and executing that arrangement without making two copies of `funcletB`.
> (in the case where the call to `@h()` faults, the `cleanupret` that unwinds to caller instead of unwinding to `%retA` is UB, so we'd want to replace it with `unreachable` in that copy of `funcletB`, but I think we still want a copy just in case `@h()` does not return dynamically and so the program never executes UB; similarly, if the input already had `unreachable` there instead of a `cleanupret`, we wouldn't know statically which reporting is correct for `funcletB` and so I'd think would want two copies of it)
sigh... insert
```
endpad:
catchendpad unwind label %funcletB
```
somewhere in `@foo` in the previous example.
http://reviews.llvm.org/D12353
More information about the llvm-commits
mailing list