This is an archive of the discontinued LLVM Phabricator instance.

Outline C++ exception handlers for MSVC targets.
ClosedPublic

Authored by andrew.w.kaylor on Feb 2 2015, 3:34 PM.

Details

Summary

This patch adds code to outline the catch handlers for Windows C++ exception handling support.

These changes are obviously derived from my earlier patch D6556, but since the direction has changed (from SEH to C++EH) it seemed reasonable to start a new differential.

The test cases are based on clang-generated IR for the listed code using an x86_64-pc-linux target, but I have edited this IR to match expected windows-msvc output.

I edited the IR to remove redundant store and load of the EH object and to replace invokes within a catch block with equivalent calls if the unwind destination does nothing but resume. I have code to perform both of these transformations, but I am holding it back for a later review.

The following things are not yet implemented:

Intrinsic support for llvm.eh.begincatch/llvm.eh.endcatch
Removal of outlined catch handlers.
Use of frame variables within a catch block.
Removal (from the parent function) of frame variables which are only used in catch blocks.
Outlining of unwind handlers.
Chained catch handlers (catching an exception from within a catch handler).
Sharing of blocks between several landing pads.
Production of intrinsics to support .xdata table generation.

I think that making the begin/end catch calls intrinsics is the only thing that should block the current patch. I'll submit a separate patch for that shortly.

Diff Detail

Repository
rL LLVM

Event Timeline

andrew.w.kaylor retitled this revision from to Outline C++ exception handlers for MSVC targets..
andrew.w.kaylor updated this object.
andrew.w.kaylor edited the test plan for this revision. (Show Details)
andrew.w.kaylor added a reviewer: rnk.
andrew.w.kaylor set the repository for this revision to rL LLVM.
andrew.w.kaylor added a subscriber: Unknown Object (MLST).
rnk added a reviewer: majnemer.Feb 3 2015, 2:41 PM
rnk accepted this revision.Feb 3 2015, 2:44 PM
rnk edited edge metadata.

Looks like a good incremental step to me.

I added David Majnemer to see if he has anything.

lib/CodeGen/WinEHPrepare.cpp
61–93 ↗(On Diff #19193)

I'd rather we went with a clang-format indentation here, as it's the dominant style across LLVM.

This revision is now accepted and ready to land.Feb 3 2015, 2:44 PM
andrew.w.kaylor added a reviewer: ABataev.

Rebased and cleaned up formatting.
Updated to use llvm.eh.begincatch and llvm.eh.endcatch intrinsics.

I was waiting for that change before committing this, but I think it should be ready now. I also have outlining of cleanup handlers ready to review as soon as this lands and some other implementation details that should be ready soon thereafter.

majnemer added inline comments.Feb 12 2015, 2:20 PM
include/llvm/Transforms/Utils/Cloning.h
140–141 ↗(On Diff #19706)

Style nit, please move the curly brace on the same line as the tag name.

lib/CodeGen/WinEHPrepare.cpp
54 ↗(On Diff #19706)

I'd make this SmallVectorImpl.

123 ↗(On Diff #19706)

Perhaps: This only returns true if...

150 ↗(On Diff #19706)

SmallVectorImpl

156 ↗(On Diff #19706)

You shouldn't have variables of type twine. They should be used directly in the expression which consumes them.

167–171 ↗(On Diff #19706)

It would be more idiomatic to do:

if (auto *Call = dyn_cast<CallInst>(&Inst))
  if (Call->getCalledFunction->getName() == "llvm.eh.actions")
215 ↗(On Diff #19706)

This might deserve a comment.

278–279 ↗(On Diff #19706)

Please fold this into a single line.

295–296 ↗(On Diff #19706)

Please fold this into a single line.

316–318 ↗(On Diff #19706)

You can simplify this by using if (match(Inst, m_Intrinsic<Intrinsic::eh_begincatch>()))

328 ↗(On Diff #19706)

Likewise here with if (match(Inst, m_Intrinsic<Intrinsic::eh_endcatch>()))

lib/Transforms/Utils/CloneFunction.cpp
684 ↗(On Diff #19706)

SmallVectorImpl<ReturnInst *>

Cleanup based on review feedback.

rnk added a comment.Feb 17 2015, 3:19 PM

Looks good, please commit.

This revision was automatically updated to reflect the committed changes.