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