llvm.org GIT mirror llvm / 7dedaab
Stop calling DwarfEHPrepare from WinEHPrepare 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 Reid Kleckner 5 years ago
6 changed file(s) with 52 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
180180
181181 /// \brief Returns true if this personality function catches asynchronous
182182 /// exceptions.
183 bool isAsynchronousEHPersonality(EHPersonality Pers);
183 inline bool isAsynchronousEHPersonality(EHPersonality Pers) {
184 // The two SEH personality functions can catch asynch exceptions. We assume
185 // unknown personalities don't catch asynch exceptions.
186 switch (Pers) {
187 case EHPersonality::MSVC_X86SEH:
188 case EHPersonality::MSVC_Win64SEH:
189 return true;
190 default: return false;
191 }
192 llvm_unreachable("invalid enum");
193 }
194
195 /// \brief Returns true if this is an MSVC personality function.
196 inline bool isMSVCEHPersonality(EHPersonality Pers) {
197 // The two SEH personality functions can catch asynch exceptions. We assume
198 // unknown personalities don't catch asynch exceptions.
199 switch (Pers) {
200 case EHPersonality::MSVC_CXX:
201 case EHPersonality::MSVC_X86SEH:
202 case EHPersonality::MSVC_Win64SEH:
203 return true;
204 default: return false;
205 }
206 llvm_unreachable("invalid enum");
207 }
184208
185209 bool canSimplifyInvokeNoUnwind(const InvokeInst *II);
186210
7979 .Default(EHPersonality::Unknown);
8080 }
8181
82 bool llvm::isAsynchronousEHPersonality(EHPersonality Pers) {
83 // The two SEH personality functions can catch asynch exceptions. We assume
84 // unknown personalities don't catch asynch exceptions.
85 switch (Pers) {
86 case EHPersonality::MSVC_X86SEH:
87 case EHPersonality::MSVC_Win64SEH:
88 return true;
89 default: return false;
90 }
91 llvm_unreachable("invalid enum");
92 }
93
9482 bool llvm::canSimplifyInvokeNoUnwind(const InvokeInst *II) {
9583 const LandingPadInst *LP = II->getLandingPadInst();
9684 EHPersonality Personality = classifyEHPersonality(LP->getPersonalityFn());
1515 #include "llvm/ADT/BitVector.h"
1616 #include "llvm/ADT/Statistic.h"
1717 #include "llvm/Analysis/CFG.h"
18 #include "llvm/Analysis/LibCallSemantics.h"
1819 #include "llvm/Analysis/TargetTransformInfo.h"
1920 #include "llvm/IR/Dominators.h"
2021 #include "llvm/IR/Function.h"
179180 bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) {
180181 SmallVector Resumes;
181182 SmallVector CleanupLPads;
183 bool FoundLP = false;
182184 for (BasicBlock &BB : Fn) {
183185 if (auto *RI = dyn_cast(BB.getTerminator()))
184186 Resumes.push_back(RI);
185 if (auto *LP = BB.getLandingPadInst())
187 if (auto *LP = BB.getLandingPadInst()) {
186188 if (LP->isCleanup())
187189 CleanupLPads.push_back(LP);
190 // Check the personality on the first landingpad. Don't do anything if
191 // it's for MSVC.
192 if (!FoundLP) {
193 FoundLP = true;
194 EHPersonality Pers = classifyEHPersonality(LP->getPersonalityFn());
195 if (isMSVCEHPersonality(Pers))
196 return false;
197 }
198 }
188199 }
189200
190201 if (Resumes.empty())
421421 addPass(createDwarfEHPass(TM));
422422 break;
423423 case ExceptionHandling::WinEH:
424 // We support using both GCC-style and MSVC-style exceptions on Windows, so
425 // add both preparation passes. Each pass will only actually run if it
426 // recognizes the personality function.
424427 addPass(createWinEHPass(TM));
428 addPass(createDwarfEHPass(TM));
425429 break;
426430 case ExceptionHandling::None:
427431 addPass(createLowerInvokePass());
1919 #include "llvm/ADT/STLExtras.h"
2020 #include "llvm/ADT/TinyPtrVector.h"
2121 #include "llvm/Analysis/LibCallSemantics.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
23 #include "llvm/IR/Dominators.h"
2422 #include "llvm/IR/Function.h"
2523 #include "llvm/IR/IRBuilder.h"
2624 #include "llvm/IR/Instructions.h"
6260 typedef DenseMap CleanupHandlerMapTy;
6361
6462 class WinEHPrepare : public FunctionPass {
65 std::unique_ptr DwarfPrepare;
66
6763 public:
6864 static char ID; // Pass identification, replacement for typeid.
6965 WinEHPrepare(const TargetMachine *TM = nullptr)
70 : FunctionPass(ID), DwarfPrepare(createDwarfEHPass(TM)) {}
66 : FunctionPass(ID) {}
7167
7268 bool runOnFunction(Function &Fn) override;
7369
322318 } // end anonymous namespace
323319
324320 char WinEHPrepare::ID = 0;
325 INITIALIZE_TM_PASS_BEGIN(WinEHPrepare, "winehprepare",
326 "Prepare Windows exceptions", false, false)
327 INITIALIZE_PASS_DEPENDENCY(DwarfEHPrepare)
328 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
329 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
330 INITIALIZE_TM_PASS_END(WinEHPrepare, "winehprepare",
331 "Prepare Windows exceptions", false, false)
321 INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
322 false, false)
332323
333324 FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
334325 return new WinEHPrepare(TM);
335 }
336
337 static bool isMSVCPersonality(EHPersonality Pers) {
338 return Pers == EHPersonality::MSVC_Win64SEH ||
339 Pers == EHPersonality::MSVC_CXX;
340326 }
341327
342328 bool WinEHPrepare::runOnFunction(Function &Fn) {
356342 // Classify the personality to see what kind of preparation we need.
357343 EHPersonality Pers = classifyEHPersonality(LPads.back()->getPersonalityFn());
358344
359 // Delegate through to the DWARF pass if this is unrecognized.
360 if (!isMSVCPersonality(Pers)) {
361 if (!DwarfPrepare->getResolver()) {
362 // Build an AnalysisResolver with the analyses needed by DwarfEHPrepare.
363 // It will take ownership of the AnalysisResolver.
364 assert(getResolver());
365 auto *AR = new AnalysisResolver(getResolver()->getPMDataManager());
366 AR->addAnalysisImplsPair(
367 &TargetTransformInfoWrapperPass::ID,
368 getResolver()->findImplPass(&TargetTransformInfoWrapperPass::ID));
369 AR->addAnalysisImplsPair(
370 &DominatorTreeWrapperPass::ID,
371 getResolver()->findImplPass(&DominatorTreeWrapperPass::ID));
372 DwarfPrepare->setResolver(AR);
373 }
374
375 return DwarfPrepare->runOnFunction(Fn);
376 }
345 // Do nothing if this is not an MSVC personality.
346 if (!isMSVCEHPersonality(Pers))
347 return false;
377348
378349 // FIXME: This only returns true if the C++ EH handlers were outlined.
379350 // When that code is complete, it should always return whatever
394365 }
395366
396367 bool WinEHPrepare::doFinalization(Module &M) {
397 return DwarfPrepare->doFinalization(M);
398 }
399
400 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
401 DwarfPrepare->getAnalysisUsage(AU);
402 }
368 return false;
369 }
370
371 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
403372
404373 bool WinEHPrepare::prepareCPPEHHandlers(
405374 Function &F, SmallVectorImpl &LPads) {
None ; RUN: opt -S -winehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
0 ; RUN: opt -S -winehprepare -dwarfehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
11
22 ; FIXME: Add and test outlining here.
33