This is an archive of the discontinued LLVM Phabricator instance.

[WinEH] Create a separate MBB for funclet prologues
ClosedPublic

Authored by majnemer on Oct 4 2015, 11:47 AM.

Details

Summary

Our current emission strategy is to emit the funclet prologue in the
CatchPad's normal destination. This is problematic because
intra-funclet control flow to the normal destination is not erroneous
and results in us reevaluating the prologue if said control flow is
taken.

Instead, use the CatchPad's location for the funclet prologue. This
correctly models our desire to have unwind edges evaluate the prologue
but edges to the normal destination result in typical control flow.

Diff Detail

Event Timeline

majnemer updated this revision to Diff 36472.Oct 4 2015, 11:47 AM
majnemer retitled this revision from to [WinEH] Create a separate MBB for funclet prologues.
majnemer updated this object.
majnemer added reviewers: rnk, JosephTremoulet.
majnemer added a subscriber: llvm-commits.
JosephTremoulet added inline comments.Oct 5 2015, 7:56 AM
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
223

One the one hand, it seems odd to allow PHIs in catchpads; in the IR each catchpad happens before the next, so it would be legal to have a use of this PHI in another PHI in a subsequent catchpad, whereas the MBB you're creating for the next catchpad's prolog won't have the MBB for this catchpad's prolog as a predecessor.

On the other hand, at the IR level, the catchpad is the only place that has invokes as predecessors but doesn't have backedges to the normal dest as predecessors and so is the only place to put the sort of PHI that we need...

This suggests to me that maybe instead of what you're doing here, we simply want EHPrep to split critical catchpad-normal-dest edges (before it mucks with PHIs)?

majnemer added inline comments.Oct 5 2015, 9:35 AM
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
223

I think we have problems with PHIs in catchpad predecessors regardless of this change because the catchpad predecessor isn't a CFG predecessor. Our solution to that problem was to use further preparation to clean-up the PHIs.

rnk added inline comments.Oct 5 2015, 10:01 AM
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
219–220

I guess we could enable tail merging, for example, on functions with SEH __try/__except only. Alternatively, we could reinterpret this variable as something like usesWindowsEH to indicate that it's using something other than the landingpad scheme for EH.

The minimal change is to add a comment like this and deal with it in another change:

// FIXME: Don't mark SEH functions without __finally blocks as having funclets.
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
1163–1192

If we're going to change the way we do catchpad lowering for the personality, then we should eventually change the way we do SEH lowering to handle this IR:

  invoke void @crash()
    to .... unwind label %catchpad
catchpad:
  %p = catchpad ...
    to label %catchit ...
catchit:
  call void @code_before_the_catchret()
  catchret %p label %parentbb

Right now code_before_the_catchret in 32-bit SEH will run without the stack frame being setup correctly.

Basically, for SEH, we should terminate the catchpad block with a CATCHRET SD node, and codegen catchret instructions to branches. Should be easy.

1175–1176

Huh, I didn't realize we had fallthroughs in the machine CFG this early... We should change the way we do 32-bit CATCHRETs in X86FrameLowering to use fallthrough next.

1266–1267

We aren't stopping, though. We're continuing around the loop, unlike the lpad or cleanup case.

lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
223

Right, ok, so in my example the MBB for the second catchpad would have the transitive preds and so it would have pulled in all the incoming values from the first catchpad.

But then I'm still confused:

  1. That seems like something that changes with the eager demotion -> no-demotion change; why is this assertion changing as part of creating MBBs for catchpads?
  2. Aren't we doing the same for catchendpad/cleanupendpad? Why do we need to assert against their PHIs?
majnemer added inline comments.Oct 5 2015, 10:57 AM
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
223

OK, I see where the miscommunication has happened. I only cared about the continue, not the assertion. We can reenable the assertion for CatchPad.

majnemer updated this revision to Diff 36674.Oct 6 2015, 4:21 PM
  • Address review comments
rnk accepted this revision.Oct 6 2015, 4:31 PM
rnk edited edge metadata.

lgtm

This revision is now accepted and ready to land.Oct 6 2015, 4:31 PM
This revision was automatically updated to reflect the committed changes.