140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que//===-- DwarfEHPrepare - Prepare exception handling for code generation ---===// 240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// 340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// The LLVM Compiler Infrastructure 43f219a2165c5233fa9a0e6d71e6dbdb3fe06d106Simon Que// 540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// This file is distributed under the University of Illinois Open Source 63dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel// License. See LICENSE.TXT for details. 740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// 83dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel//===----------------------------------------------------------------------===// 940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// 1040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// This pass mulches exception handling code into a form adapted to code 1140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// generation. Required if using dwarf exception handling. 1240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que// 1340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que//===----------------------------------------------------------------------===// 1440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 1540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/CodeGen/Passes.h" 1640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/ADT/BitVector.h" 1740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/ADT/Statistic.h" 1840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/Analysis/CFG.h" 1940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/Analysis/EHPersonalities.h" 2040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/Analysis/TargetTransformInfo.h" 2140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/IR/Dominators.h" 2240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/IR/Function.h" 2340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/IR/Instructions.h" 2440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/IR/Module.h" 2540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/Pass.h" 2640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/Target/TargetLowering.h" 2740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/Target/TargetSubtargetInfo.h" 2840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que#include "llvm/Transforms/Utils/Local.h" 2940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Queusing namespace llvm; 3040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 313dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel#define DEBUG_TYPE "dwarfehprepare" 323dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel 333dab8e583cce64f14f728e656798c48ed2ea4143Ilja FriedelSTATISTIC(NumResumesLowered, "Number of resume calls lowered"); 343dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel 3540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Quenamespace { 363dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel class DwarfEHPrepare : public FunctionPass { 3740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que const TargetMachine *TM; 3840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 393f219a2165c5233fa9a0e6d71e6dbdb3fe06d106Simon Que // RewindFunction - _Unwind_Resume or the target equivalent. 403f219a2165c5233fa9a0e6d71e6dbdb3fe06d106Simon Que Constant *RewindFunction; 413f219a2165c5233fa9a0e6d71e6dbdb3fe06d106Simon Que 423dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel DominatorTree *DT; 433dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel const TargetLowering *TLI; 443dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel 453dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel bool InsertUnwindResumeCalls(Function &Fn); 463dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel Value *GetExceptionObject(ResumeInst *RI); 473dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel size_t 483dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel pruneUnreachableResumes(Function &Fn, 493dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel SmallVectorImpl<ResumeInst *> &Resumes, 503dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel SmallVectorImpl<LandingPadInst *> &CleanupLPads); 513f219a2165c5233fa9a0e6d71e6dbdb3fe06d106Simon Que 5240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que public: 5336eff4686c6781384f184cdff65510a5d6234429Simon Que static char ID; // Pass identification, replacement for typeid. 5440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 5540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que // INITIALIZE_TM_PASS requires a default constructor, but it isn't used in 56fd45dc71cfed09edcd30a39ffbd6a4cd441b89ceIlja H. Friedel // practice. 57fd45dc71cfed09edcd30a39ffbd6a4cd441b89ceIlja H. Friedel DwarfEHPrepare() 58fd45dc71cfed09edcd30a39ffbd6a4cd441b89ceIlja H. Friedel : FunctionPass(ID), TM(nullptr), RewindFunction(nullptr), DT(nullptr), 59fd45dc71cfed09edcd30a39ffbd6a4cd441b89ceIlja H. Friedel TLI(nullptr) {} 60fd45dc71cfed09edcd30a39ffbd6a4cd441b89ceIlja H. Friedel 6140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que DwarfEHPrepare(const TargetMachine *TM) 6240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que : FunctionPass(ID), TM(TM), RewindFunction(nullptr), DT(nullptr), 6340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que TLI(nullptr) {} 6440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 6540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que bool runOnFunction(Function &Fn) override; 6640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 6740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que bool doFinalization(Module &M) override { 6840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que RewindFunction = nullptr; 6940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return false; 7040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 7140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 7240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que void getAnalysisUsage(AnalysisUsage &AU) const override; 7340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 7440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que const char *getPassName() const override { 7540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return "Exception handling preparation"; 7640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 7740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que }; 7840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que} // end anonymous namespace 7940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 8040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Quechar DwarfEHPrepare::ID = 0; 8140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon QueINITIALIZE_TM_PASS_BEGIN(DwarfEHPrepare, "dwarfehprepare", 8240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que "Prepare DWARF exceptions", false, false) 8340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon QueINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 8440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon QueINITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) 8540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon QueINITIALIZE_TM_PASS_END(DwarfEHPrepare, "dwarfehprepare", 8640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que "Prepare DWARF exceptions", false, false) 8740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 8840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon QueFunctionPass *llvm::createDwarfEHPass(const TargetMachine *TM) { 8940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return new DwarfEHPrepare(TM); 9040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que} 9140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 9240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Quevoid DwarfEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const { 9340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que AU.addRequired<TargetTransformInfoWrapperPass>(); 943dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel AU.addRequired<DominatorTreeWrapperPass>(); 9540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que} 9640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 9740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que/// GetExceptionObject - Return the exception object from the value passed into 9840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que/// the 'resume' instruction (typically an aggregate). Clean up any dead 9940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que/// instructions, including the 'resume' instruction. 10040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon QueValue *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) { 10140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que Value *V = RI->getOperand(0); 10240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que Value *ExnObj = nullptr; 10340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que InsertValueInst *SelIVI = dyn_cast<InsertValueInst>(V); 10440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que LoadInst *SelLoad = nullptr; 10540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que InsertValueInst *ExcIVI = nullptr; 10640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que bool EraseIVIs = false; 10740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 1083dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel if (SelIVI) { 1093dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel if (SelIVI->getNumIndices() == 1 && *SelIVI->idx_begin() == 1) { 1103dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel ExcIVI = dyn_cast<InsertValueInst>(SelIVI->getOperand(0)); 11140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (ExcIVI && isa<UndefValue>(ExcIVI->getOperand(0)) && 11240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que ExcIVI->getNumIndices() == 1 && *ExcIVI->idx_begin() == 0) { 11340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que ExnObj = ExcIVI->getOperand(1); 11440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que SelLoad = dyn_cast<LoadInst>(SelIVI->getOperand(1)); 11540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que EraseIVIs = true; 11640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 11740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 11840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 11940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 12040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (!ExnObj) 12140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI); 12240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 12340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que RI->eraseFromParent(); 12440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 12540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (EraseIVIs) { 12640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (SelIVI->use_empty()) 1273dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel SelIVI->eraseFromParent(); 1283dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel if (ExcIVI->use_empty()) 12940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que ExcIVI->eraseFromParent(); 13040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (SelLoad && SelLoad->use_empty()) 13140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que SelLoad->eraseFromParent(); 13240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 13340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 13440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return ExnObj; 13540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que} 13640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 13740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que/// Replace resumes that are not reachable from a cleanup landing pad with 13840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que/// unreachable and then simplify those blocks. 13940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Quesize_t DwarfEHPrepare::pruneUnreachableResumes( 14040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que Function &Fn, SmallVectorImpl<ResumeInst *> &Resumes, 14140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que SmallVectorImpl<LandingPadInst *> &CleanupLPads) { 14240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que BitVector ResumeReachable(Resumes.size()); 14340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que size_t ResumeIndex = 0; 14440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que for (auto *RI : Resumes) { 14540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que for (auto *LP : CleanupLPads) { 14640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (isPotentiallyReachable(LP, RI, DT)) { 14740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que ResumeReachable.set(ResumeIndex); 14840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que break; 14940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 150aba1f72618fec4b790af63794f60062fe0c49cd9Simon Que } 15140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que ++ResumeIndex; 15240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 15340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 154aba1f72618fec4b790af63794f60062fe0c49cd9Simon Que // If everything is reachable, there is no change. 15540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (ResumeReachable.all()) 1563dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel return Resumes.size(); 15740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 1583dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel const TargetTransformInfo &TTI = 1593dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn); 1603dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel LLVMContext &Ctx = Fn.getContext(); 16140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 16240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que // Otherwise, insert unreachable instructions and call simplifycfg. 16340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que size_t ResumesLeft = 0; 16440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que for (size_t I = 0, E = Resumes.size(); I < E; ++I) { 16540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que ResumeInst *RI = Resumes[I]; 166aba1f72618fec4b790af63794f60062fe0c49cd9Simon Que if (ResumeReachable[I]) { 16740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que Resumes[ResumesLeft++] = RI; 16840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } else { 16940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que BasicBlock *BB = RI->getParent(); 17040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que new UnreachableInst(Ctx, RI); 17140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que RI->eraseFromParent(); 1723dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel SimplifyCFG(BB, TTI, 1); 1733dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel } 1743dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel } 17540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que Resumes.resize(ResumesLeft); 17640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return ResumesLeft; 177aba1f72618fec4b790af63794f60062fe0c49cd9Simon Que} 1785de8c55bcd38b3317419098d9459e19f1d49a7f9Simon Que 1795de8c55bcd38b3317419098d9459e19f1d49a7f9Simon Que/// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present 1805de8c55bcd38b3317419098d9459e19f1d49a7f9Simon Que/// into calls to the appropriate _Unwind_Resume function. 1815de8c55bcd38b3317419098d9459e19f1d49a7f9Simon Quebool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) { 1825de8c55bcd38b3317419098d9459e19f1d49a7f9Simon Que SmallVector<ResumeInst*, 16> Resumes; 1835de8c55bcd38b3317419098d9459e19f1d49a7f9Simon Que SmallVector<LandingPadInst*, 16> CleanupLPads; 1845de8c55bcd38b3317419098d9459e19f1d49a7f9Simon Que for (BasicBlock &BB : Fn) { 185aba1f72618fec4b790af63794f60062fe0c49cd9Simon Que if (auto *RI = dyn_cast<ResumeInst>(BB.getTerminator())) 186aba1f72618fec4b790af63794f60062fe0c49cd9Simon Que Resumes.push_back(RI); 18740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (auto *LP = BB.getLandingPadInst()) 1883dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel if (LP->isCleanup()) 189aba1f72618fec4b790af63794f60062fe0c49cd9Simon Que CleanupLPads.push_back(LP); 19040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que } 19140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 19240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (Resumes.empty()) 19340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return false; 19440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 19540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que // Check the personality, don't do anything if it's funclet-based. 19640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn()); 19740b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (isFuncletEHPersonality(Pers)) 19840b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return false; 19940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 20040b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que LLVMContext &Ctx = Fn.getContext(); 20140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 20240b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que size_t ResumesLeft = pruneUnreachableResumes(Fn, Resumes, CleanupLPads); 20340b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que if (ResumesLeft == 0) 20440b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que return true; // We pruned them all. 20540b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que 20640b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que // Find the rewind function if we didn't already. 2073dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel if (!RewindFunction) { 2083dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), 20940b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que Type::getInt8PtrTy(Ctx), false); 2103dab8e583cce64f14f728e656798c48ed2ea4143Ilja Friedel const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME); 21140b289060ac9d8bc97299dc6a6f7515fc326a13cSimon Que RewindFunction = Fn.getParent()->getOrInsertFunction(RewindName, FTy); 212 } 213 214 // Create the basic block where the _Unwind_Resume call will live. 215 if (ResumesLeft == 1) { 216 // Instead of creating a new BB and PHI node, just append the call to 217 // _Unwind_Resume to the end of the single resume block. 218 ResumeInst *RI = Resumes.front(); 219 BasicBlock *UnwindBB = RI->getParent(); 220 Value *ExnObj = GetExceptionObject(RI); 221 222 // Call the _Unwind_Resume function. 223 CallInst *CI = CallInst::Create(RewindFunction, ExnObj, "", UnwindBB); 224 CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME)); 225 226 // We never expect _Unwind_Resume to return. 227 new UnreachableInst(Ctx, UnwindBB); 228 return true; 229 } 230 231 BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &Fn); 232 PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft, 233 "exn.obj", UnwindBB); 234 235 // Extract the exception object from the ResumeInst and add it to the PHI node 236 // that feeds the _Unwind_Resume call. 237 for (ResumeInst *RI : Resumes) { 238 BasicBlock *Parent = RI->getParent(); 239 BranchInst::Create(UnwindBB, Parent); 240 241 Value *ExnObj = GetExceptionObject(RI); 242 PN->addIncoming(ExnObj, Parent); 243 244 ++NumResumesLowered; 245 } 246 247 // Call the function. 248 CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB); 249 CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME)); 250 251 // We never expect _Unwind_Resume to return. 252 new UnreachableInst(Ctx, UnwindBB); 253 return true; 254} 255 256bool DwarfEHPrepare::runOnFunction(Function &Fn) { 257 assert(TM && "DWARF EH preparation requires a target machine"); 258 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 259 TLI = TM->getSubtargetImpl(Fn)->getTargetLowering(); 260 bool Changed = InsertUnwindResumeCalls(Fn); 261 DT = nullptr; 262 TLI = nullptr; 263 return Changed; 264} 265