1 //===-- WinEHPrepare - Prepare exception handling for code generation ---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This pass lowers LLVM IR exception handling into something closer to what the
11 // backend wants. It snifs the personality function to see which kind of
12 // preparation is necessary. If the personality function uses the Itanium LSDA,
13 // this pass delegates to the DWARF EH preparation pass.
15 //===----------------------------------------------------------------------===//
17 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/Analysis/LibCallSemantics.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/Pass.h"
27 #define DEBUG_TYPE "winehprepare"
30 class WinEHPrepare : public FunctionPass {
31 std::unique_ptr<FunctionPass> DwarfPrepare;
34 static char ID; // Pass identification, replacement for typeid.
35 WinEHPrepare(const TargetMachine *TM = nullptr)
36 : FunctionPass(ID), DwarfPrepare(createDwarfEHPass(TM)) {}
38 bool runOnFunction(Function &Fn) override;
40 bool doFinalization(Module &M) override;
42 void getAnalysisUsage(AnalysisUsage &AU) const override;
44 const char *getPassName() const override {
45 return "Windows exception handling preparation";
48 } // end anonymous namespace
50 char WinEHPrepare::ID = 0;
51 INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare",
52 "Prepare Windows exceptions", false, false)
54 FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
55 return new WinEHPrepare(TM);
58 static bool isMSVCPersonality(EHPersonality Pers) {
59 return Pers == EHPersonality::MSVC_Win64SEH ||
60 Pers == EHPersonality::MSVC_CXX;
63 bool WinEHPrepare::runOnFunction(Function &Fn) {
64 SmallVector<LandingPadInst *, 4> LPads;
65 SmallVector<ResumeInst *, 4> Resumes;
66 for (BasicBlock &BB : Fn) {
67 if (auto *LP = BB.getLandingPadInst())
69 if (auto *Resume = dyn_cast<ResumeInst>(BB.getTerminator()))
70 Resumes.push_back(Resume);
73 // No need to prepare functions that lack landing pads.
77 // Classify the personality to see what kind of preparation we need.
78 EHPersonality Pers = ClassifyEHPersonality(LPads.back()->getPersonalityFn());
80 // Delegate through to the DWARF pass if this is unrecognized.
81 if (!isMSVCPersonality(Pers))
82 return DwarfPrepare->runOnFunction(Fn);
84 // FIXME: Cleanups are unimplemented. Replace them with unreachable.
88 for (ResumeInst *Resume : Resumes) {
89 IRBuilder<>(Resume).CreateUnreachable();
90 Resume->eraseFromParent();
96 bool WinEHPrepare::doFinalization(Module &M) {
97 return DwarfPrepare->doFinalization(M);
100 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
101 DwarfPrepare->getAnalysisUsage(AU);