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/Instructions.h"
21 #include "llvm/IR/Intrinsics.h"
22 #include "llvm/Pass.h"
23 #include "llvm/Target/TargetLowering.h"
26 #define DEBUG_TYPE "winehprepare"
29 class WinEHPrepare : public FunctionPass {
30 FunctionPass *DwarfPrepare;
33 static char ID; // Pass identification, replacement for typeid.
34 WinEHPrepare(const TargetMachine *TM = nullptr)
35 : FunctionPass(ID), DwarfPrepare(createDwarfEHPass(TM)) {
36 initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
39 bool runOnFunction(Function &Fn) override;
41 bool doFinalization(Module &M) override;
43 void getAnalysisUsage(AnalysisUsage &AU) const override;
45 const char *getPassName() const override {
46 return "Windows exception handling preparation";
49 } // end anonymous namespace
51 char WinEHPrepare::ID = 0;
52 INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare",
53 "Prepare Windows exceptions", false, false)
55 FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
56 return new WinEHPrepare(TM);
59 static bool isMSVCPersonality(EHPersonality Pers) {
60 return Pers == EHPersonality::MSVC_Win64SEH ||
61 Pers == EHPersonality::MSVC_CXX;
64 bool WinEHPrepare::runOnFunction(Function &Fn) {
65 SmallVector<LandingPadInst *, 4> LPads;
66 SmallVector<ResumeInst *, 4> Resumes;
67 for (BasicBlock &BB : Fn) {
68 if (auto *LP = BB.getLandingPadInst())
70 if (auto *Resume = dyn_cast<ResumeInst>(BB.getTerminator()))
71 Resumes.push_back(Resume);
74 // No need to prepare functions that lack landing pads.
78 // Classify the personality to see what kind of preparation we need.
79 EHPersonality Pers = ClassifyEHPersonality(LPads.back()->getPersonalityFn());
81 // Delegate through to the DWARF pass if this is unrecognized.
82 if (!isMSVCPersonality(Pers))
83 return DwarfPrepare->runOnFunction(Fn);
85 // FIXME: Cleanups are unimplemented. Replace them with calls to @llvm.trap.
89 for (ResumeInst *Resume : Resumes) {
90 IRBuilder<>(Resume).CreateUnreachable();
91 Resume->eraseFromParent();
97 bool WinEHPrepare::doFinalization(Module &M) {
98 return DwarfPrepare->doFinalization(M);
101 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
102 DwarfPrepare->getAnalysisUsage(AU);