Stop calling DwarfEHPrepare from WinEHPrepare
authorReid Kleckner <reid@kleckner.net>
Thu, 12 Mar 2015 00:36:20 +0000 (00:36 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 12 Mar 2015 00:36:20 +0000 (00:36 +0000)
Instead, run both EH preparation passes, and have them both ignore
functions with unrecognized EH personalities. Pass delegation involved
some hacky code for creating an AnalysisResolver that we don't need now.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231995 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/LibCallSemantics.h
lib/Analysis/LibCallSemantics.cpp
lib/CodeGen/DwarfEHPrepare.cpp
lib/CodeGen/Passes.cpp
lib/CodeGen/WinEHPrepare.cpp
test/CodeGen/X86/win_eh_prepare.ll

index e6427a4b2ec4bc6767cfc8d92ba3baf0d375fbda..34831b2849dd0b77328a7ae4928b4de71225585c 100644 (file)
@@ -181,7 +181,31 @@ class InvokeInst;
 
   /// \brief Returns true if this personality function catches asynchronous
   /// exceptions.
-  bool isAsynchronousEHPersonality(EHPersonality Pers);
+  inline bool isAsynchronousEHPersonality(EHPersonality Pers) {
+    // The two SEH personality functions can catch asynch exceptions. We assume
+    // unknown personalities don't catch asynch exceptions.
+    switch (Pers) {
+    case EHPersonality::MSVC_X86SEH:
+    case EHPersonality::MSVC_Win64SEH:
+      return true;
+    default: return false;
+    }
+    llvm_unreachable("invalid enum");
+  }
+
+  /// \brief Returns true if this is an MSVC personality function.
+  inline bool isMSVCEHPersonality(EHPersonality Pers) {
+    // The two SEH personality functions can catch asynch exceptions. We assume
+    // unknown personalities don't catch asynch exceptions.
+    switch (Pers) {
+    case EHPersonality::MSVC_CXX:
+    case EHPersonality::MSVC_X86SEH:
+    case EHPersonality::MSVC_Win64SEH:
+      return true;
+    default: return false;
+    }
+    llvm_unreachable("invalid enum");
+  }
 
   bool canSimplifyInvokeNoUnwind(const InvokeInst *II);
 
index cf752dd8e0e49c1ac98d0b4398eb644e8bbbcd5b..328b186b527a3fe4fc2e13dc43715ff4240b21a6 100644 (file)
@@ -80,18 +80,6 @@ EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
     .Default(EHPersonality::Unknown);
 }
 
-bool llvm::isAsynchronousEHPersonality(EHPersonality Pers) {
-  // The two SEH personality functions can catch asynch exceptions. We assume
-  // unknown personalities don't catch asynch exceptions.
-  switch (Pers) {
-  case EHPersonality::MSVC_X86SEH:
-  case EHPersonality::MSVC_Win64SEH:
-    return true;
-  default: return false;
-  }
-  llvm_unreachable("invalid enum");
-}
-
 bool llvm::canSimplifyInvokeNoUnwind(const InvokeInst *II) {
   const LandingPadInst *LP = II->getLandingPadInst();
   EHPersonality Personality = classifyEHPersonality(LP->getPersonalityFn());
index f58fb59d060c40f7933bd957e415bbf14b5d7756..42656fb08db1aaf2e62ac7d3983a31a5fc49a264 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/LibCallSemantics.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Function.h"
@@ -180,12 +181,22 @@ size_t DwarfEHPrepare::pruneUnreachableResumes(
 bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) {
   SmallVector<ResumeInst*, 16> Resumes;
   SmallVector<LandingPadInst*, 16> CleanupLPads;
+  bool FoundLP = false;
   for (BasicBlock &BB : Fn) {
     if (auto *RI = dyn_cast<ResumeInst>(BB.getTerminator()))
       Resumes.push_back(RI);
-    if (auto *LP = BB.getLandingPadInst())
+    if (auto *LP = BB.getLandingPadInst()) {
       if (LP->isCleanup())
         CleanupLPads.push_back(LP);
+      // Check the personality on the first landingpad. Don't do anything if
+      // it's for MSVC.
+      if (!FoundLP) {
+        FoundLP = true;
+        EHPersonality Pers = classifyEHPersonality(LP->getPersonalityFn());
+        if (isMSVCEHPersonality(Pers))
+          return false;
+      }
+    }
   }
 
   if (Resumes.empty())
index d692862adf4058c416e8f3ab39f3b3a73a0d4128..4fbc4c97307dcf0b92978a5ad7a5c94c8c86ff77 100644 (file)
@@ -422,7 +422,11 @@ void TargetPassConfig::addPassesToHandleExceptions() {
     addPass(createDwarfEHPass(TM));
     break;
   case ExceptionHandling::WinEH:
+    // We support using both GCC-style and MSVC-style exceptions on Windows, so
+    // add both preparation passes. Each pass will only actually run if it
+    // recognizes the personality function.
     addPass(createWinEHPass(TM));
+    addPass(createDwarfEHPass(TM));
     break;
   case ExceptionHandling::None:
     addPass(createLowerInvokePass());
index 05de6bf39faf367c90ec78a77ad4d18b82013ebe..bc3cc6b9b85fedaf3564853849411afc7969c19f 100644 (file)
@@ -20,8 +20,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Analysis/LibCallSemantics.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Dominators.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
@@ -63,12 +61,10 @@ typedef DenseMap<const BasicBlock *, CatchHandler *> CatchHandlerMapTy;
 typedef DenseMap<const BasicBlock *, CleanupHandler *> CleanupHandlerMapTy;
 
 class WinEHPrepare : public FunctionPass {
-  std::unique_ptr<FunctionPass> DwarfPrepare;
-
 public:
   static char ID; // Pass identification, replacement for typeid.
   WinEHPrepare(const TargetMachine *TM = nullptr)
-      : FunctionPass(ID), DwarfPrepare(createDwarfEHPass(TM)) {}
+      : FunctionPass(ID) {}
 
   bool runOnFunction(Function &Fn) override;
 
@@ -323,23 +319,13 @@ private:
 } // end anonymous namespace
 
 char WinEHPrepare::ID = 0;
-INITIALIZE_TM_PASS_BEGIN(WinEHPrepare, "winehprepare",
-                         "Prepare Windows exceptions", false, false)
-INITIALIZE_PASS_DEPENDENCY(DwarfEHPrepare)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
-INITIALIZE_TM_PASS_END(WinEHPrepare, "winehprepare",
-                       "Prepare Windows exceptions", false, false)
+INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
+                   false, false)
 
 FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
   return new WinEHPrepare(TM);
 }
 
-static bool isMSVCPersonality(EHPersonality Pers) {
-  return Pers == EHPersonality::MSVC_Win64SEH ||
-         Pers == EHPersonality::MSVC_CXX;
-}
-
 bool WinEHPrepare::runOnFunction(Function &Fn) {
   SmallVector<LandingPadInst *, 4> LPads;
   SmallVector<ResumeInst *, 4> Resumes;
@@ -357,24 +343,9 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
   // Classify the personality to see what kind of preparation we need.
   EHPersonality Pers = classifyEHPersonality(LPads.back()->getPersonalityFn());
 
-  // Delegate through to the DWARF pass if this is unrecognized.
-  if (!isMSVCPersonality(Pers)) {
-    if (!DwarfPrepare->getResolver()) {
-      // Build an AnalysisResolver with the analyses needed by DwarfEHPrepare.
-      // It will take ownership of the AnalysisResolver.
-      assert(getResolver());
-      auto *AR = new AnalysisResolver(getResolver()->getPMDataManager());
-      AR->addAnalysisImplsPair(
-          &TargetTransformInfoWrapperPass::ID,
-          getResolver()->findImplPass(&TargetTransformInfoWrapperPass::ID));
-      AR->addAnalysisImplsPair(
-          &DominatorTreeWrapperPass::ID,
-          getResolver()->findImplPass(&DominatorTreeWrapperPass::ID));
-      DwarfPrepare->setResolver(AR);
-    }
-
-    return DwarfPrepare->runOnFunction(Fn);
-  }
+  // Do nothing if this is not an MSVC personality.
+  if (!isMSVCEHPersonality(Pers))
+    return false;
 
   // FIXME: This only returns true if the C++ EH handlers were outlined.
   //        When that code is complete, it should always return whatever
@@ -395,12 +366,10 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
 }
 
 bool WinEHPrepare::doFinalization(Module &M) {
-  return DwarfPrepare->doFinalization(M);
+  return false;
 }
 
-void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
-  DwarfPrepare->getAnalysisUsage(AU);
-}
+void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
 
 bool WinEHPrepare::prepareCPPEHHandlers(
     Function &F, SmallVectorImpl<LandingPadInst *> &LPads) {
index b457a41e45269018d23c515134c7106d810f9111..e5a7d055a78427d5c0a39d35911eea2d672ee73b 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: opt -S -winehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
+; RUN: opt -S -winehprepare -dwarfehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
 
 ; FIXME: Add and test outlining here.