[llvm] r247848 - [WinEHPrepare] Turn terminatepad into a cleanuppad + call + cleanupret

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 13:42:16 PDT 2015


Author: majnemer
Date: Wed Sep 16 15:42:16 2015
New Revision: 247848

URL: http://llvm.org/viewvc/llvm-project?rev=247848&view=rev
Log:
[WinEHPrepare] Turn terminatepad into a cleanuppad + call + cleanupret

The MSVC doesn't really support exception specifications so let's just
turn these into cleanuppads.  Later, we might use terminatepad to more
efficiently encode the "noexcept"-ness of a function body.

Modified:
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
    llvm/trunk/test/CodeGen/WinEH/wineh-no-demotion.ll

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=247848&r1=247847&r2=247848&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Wed Sep 16 15:42:16 2015
@@ -144,6 +144,7 @@ private:
                           Function &F);
   bool prepareExplicitEH(Function &F,
                          SmallVectorImpl<BasicBlock *> &EntryBlocks);
+  void replaceTerminatePadWithCleanup(Function &F);
   void colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks);
   void demotePHIsOnFunclets(Function &F);
   void demoteUsesBetweenFunclets(Function &F);
@@ -3206,6 +3207,44 @@ void llvm::calculateWinCXXEHStateNumbers
     Num.processCallSite(None, ImmutableCallSite());
 }
 
+void WinEHPrepare::replaceTerminatePadWithCleanup(Function &F) {
+  if (Personality != EHPersonality::MSVC_CXX)
+    return;
+  for (BasicBlock &BB : F) {
+    Instruction *First = BB.getFirstNonPHI();
+    auto *TPI = dyn_cast<TerminatePadInst>(First);
+    if (!TPI)
+      continue;
+
+    if (TPI->getNumArgOperands() != 1)
+      report_fatal_error(
+          "Expected a unary terminatepad for MSVC C++ personalities!");
+
+    auto *TerminateFn = dyn_cast<Function>(TPI->getArgOperand(0));
+    if (!TerminateFn)
+      report_fatal_error("Function operand expected in terminatepad for MSVC "
+                         "C++ personalities!");
+
+    // Insert the cleanuppad instruction.
+    auto *CPI = CleanupPadInst::Create(
+        BB.getContext(), {}, Twine("terminatepad.for.", BB.getName()), &BB);
+
+    // Insert the call to the terminate instruction.
+    auto *CallTerminate = CallInst::Create(TerminateFn, {}, &BB);
+    CallTerminate->setDoesNotThrow();
+    CallTerminate->setDoesNotReturn();
+    CallTerminate->setCallingConv(TerminateFn->getCallingConv());
+
+    // Insert a new terminator for the cleanuppad using the same successor as
+    // the terminatepad.
+    CleanupReturnInst::Create(CPI, TPI->getUnwindDest(), &BB);
+
+    // Let's remove the terminatepad now that we've inserted the new
+    // instructions.
+    TPI->eraseFromParent();
+  }
+}
+
 void WinEHPrepare::colorFunclets(Function &F,
                                  SmallVectorImpl<BasicBlock *> &EntryBlocks) {
   SmallVector<std::pair<BasicBlock *, BasicBlock *>, 16> Worklist;
@@ -3560,6 +3599,8 @@ bool WinEHPrepare::prepareExplicitEH(
   // not.
   removeUnreachableBlocks(F);
 
+  replaceTerminatePadWithCleanup(F);
+
   // Determine which blocks are reachable from which funclet entries.
   colorFunclets(F, EntryBlocks);
 

Modified: llvm/trunk/test/CodeGen/WinEH/wineh-no-demotion.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-no-demotion.ll?rev=247848&r1=247847&r2=247848&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-no-demotion.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-no-demotion.ll Wed Sep 16 15:42:16 2015
@@ -85,3 +85,21 @@ inner:
 exit:
   unreachable
 }
+
+; CHECK-LABEL: @test3(
+define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  invoke void @f()
+          to label %invoke.cont unwind label %terminate
+
+invoke.cont:
+  ret void
+
+terminate:
+; CHECK:  cleanuppad []
+; CHECK:  call void @__std_terminate()
+; CHECK:  unreachable
+  terminatepad [void ()* @__std_terminate] unwind to caller
+}
+
+declare void @__std_terminate()




More information about the llvm-commits mailing list