//===- DwarfEHPrepare - Prepare exception handling for code generation ----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This pass mulches exception handling code into a form adapted to code
// generation. Required if using dwarf exception handling.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/Local.h"
#include <cstddef>

using namespace llvm;

#define DEBUG_TYPE "dwarfehprepare"

STATISTIC(NumResumesLowered, "Number of resume calls lowered");

namespace {

  class DwarfEHPrepare : public FunctionPass {
    // RewindFunction - _Unwind_Resume or the target equivalent.
    FunctionCallee RewindFunction = nullptr;

    CodeGenOpt::Level OptLevel;
    DominatorTree *DT = nullptr;
    const TargetLowering *TLI = nullptr;

    bool InsertUnwindResumeCalls(Function &Fn);
    Value *GetExceptionObject(ResumeInst *RI);
    size_t
    pruneUnreachableResumes(Function &Fn,
                            SmallVectorImpl<ResumeInst *> &Resumes,
                            SmallVectorImpl<LandingPadInst *> &CleanupLPads);

  public:
    static char ID; // Pass identification, replacement for typeid.

    DwarfEHPrepare(CodeGenOpt::Level OptLevel = CodeGenOpt::Default)
      : FunctionPass(ID), OptLevel(OptLevel) {}

    bool runOnFunction(Function &Fn) override;

    bool doFinalization(Module &M) override {
      RewindFunction = nullptr;
      return false;
    }

    void getAnalysisUsage(AnalysisUsage &AU) const override;

    StringRef getPassName() const override {
      return "Exception handling preparation";
    }
  };

} // end anonymous namespace

char DwarfEHPrepare::ID = 0;

INITIALIZE_PASS_BEGIN(DwarfEHPrepare, DEBUG_TYPE,
                      "Prepare DWARF exceptions", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(DwarfEHPrepare, DEBUG_TYPE,
                    "Prepare DWARF exceptions", false, false)

FunctionPass *llvm::createDwarfEHPass(CodeGenOpt::Level OptLevel) {
  return new DwarfEHPrepare(OptLevel);
}

void DwarfEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<TargetPassConfig>();
  AU.addRequired<TargetTransformInfoWrapperPass>();
  if (OptLevel != CodeGenOpt::None)
    AU.addRequired<DominatorTreeWrapperPass>();
}

/// GetExceptionObject - Return the exception object from the value passed into
/// the 'resume' instruction (typically an aggregate). Clean up any dead
/// instructions, including the 'resume' instruction.
Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) {
  Value *V = RI->getOperand(0);
  Value *ExnObj = nullptr;
  InsertValueInst *SelIVI = dyn_cast<InsertValueInst>(V);
  LoadInst *SelLoad = nullptr;
  InsertValueInst *ExcIVI = nullptr;
  bool EraseIVIs = false;

  if (SelIVI) {
    if (SelIVI->getNumIndices() == 1 && *SelIVI->idx_begin() == 1) {
      ExcIVI = dyn_cast<InsertValueInst>(SelIVI->getOperand(0));
      if (ExcIVI && isa<UndefValue>(ExcIVI->getOperand(0)) &&
          ExcIVI->getNumIndices() == 1 && *ExcIVI->idx_begin() == 0) {
        ExnObj = ExcIVI->getOperand(1);
        SelLoad = dyn_cast<LoadInst>(SelIVI->getOperand(1));
        EraseIVIs = true;
      }
    }
  }

  if (!ExnObj)
    ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI);

  RI->eraseFromParent();

  if (EraseIVIs) {
    if (SelIVI->use_empty())
      SelIVI->eraseFromParent();
    if (ExcIVI->use_empty())
      ExcIVI->eraseFromParent();
    if (SelLoad && SelLoad->use_empty())
      SelLoad->eraseFromParent();
  }

  return ExnObj;
}

/// Replace resumes that are not reachable from a cleanup landing pad with
/// unreachable and then simplify those blocks.
size_t DwarfEHPrepare::pruneUnreachableResumes(
    Function &Fn, SmallVectorImpl<ResumeInst *> &Resumes,
    SmallVectorImpl<LandingPadInst *> &CleanupLPads) {
  BitVector ResumeReachable(Resumes.size());
  size_t ResumeIndex = 0;
  for (auto *RI : Resumes) {
    for (auto *LP : CleanupLPads) {
      if (isPotentiallyReachable(LP, RI, nullptr, DT)) {
        ResumeReachable.set(ResumeIndex);
        break;
      }
    }
    ++ResumeIndex;
  }

  // If everything is reachable, there is no change.
  if (ResumeReachable.all())
    return Resumes.size();

  const TargetTransformInfo &TTI =
      getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn);
  LLVMContext &Ctx = Fn.getContext();

  // Otherwise, insert unreachable instructions and call simplifycfg.
  size_t ResumesLeft = 0;
  for (size_t I = 0, E = Resumes.size(); I < E; ++I) {
    ResumeInst *RI = Resumes[I];
    if (ResumeReachable[I]) {
      Resumes[ResumesLeft++] = RI;
    } else {
      BasicBlock *BB = RI->getParent();
      new UnreachableInst(Ctx, RI);
      RI->eraseFromParent();
      simplifyCFG(BB, TTI);
    }
  }
  Resumes.resize(ResumesLeft);
  return ResumesLeft;
}

/// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present
/// into calls to the appropriate _Unwind_Resume function.
bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) {
  SmallVector<ResumeInst*, 16> Resumes;
  SmallVector<LandingPadInst*, 16> CleanupLPads;
  for (BasicBlock &BB : Fn) {
    if (auto *RI = dyn_cast<ResumeInst>(BB.getTerminator()))
      Resumes.push_back(RI);
    if (auto *LP = BB.getLandingPadInst())
      if (LP->isCleanup())
        CleanupLPads.push_back(LP);
  }

  if (Resumes.empty())
    return false;

  // Check the personality, don't do anything if it's scope-based.
  EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn());
  if (isScopedEHPersonality(Pers))
    return false;

  LLVMContext &Ctx = Fn.getContext();

  size_t ResumesLeft = Resumes.size();
  if (OptLevel != CodeGenOpt::None)
    ResumesLeft = pruneUnreachableResumes(Fn, Resumes, CleanupLPads);

  if (ResumesLeft == 0)
    return true; // We pruned them all.

  // Find the rewind function if we didn't already.
  if (!RewindFunction) {
    FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
                                          Type::getInt8PtrTy(Ctx), false);
    const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME);
    RewindFunction = Fn.getParent()->getOrInsertFunction(RewindName, FTy);
  }

  // Create the basic block where the _Unwind_Resume call will live.
  if (ResumesLeft == 1) {
    // Instead of creating a new BB and PHI node, just append the call to
    // _Unwind_Resume to the end of the single resume block.
    ResumeInst *RI = Resumes.front();
    BasicBlock *UnwindBB = RI->getParent();
    Value *ExnObj = GetExceptionObject(RI);

    // Call the _Unwind_Resume function.
    CallInst *CI = CallInst::Create(RewindFunction, ExnObj, "", UnwindBB);
    CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));

    // We never expect _Unwind_Resume to return.
    new UnreachableInst(Ctx, UnwindBB);
    return true;
  }

  BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &Fn);
  PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft,
                                "exn.obj", UnwindBB);

  // Extract the exception object from the ResumeInst and add it to the PHI node
  // that feeds the _Unwind_Resume call.
  for (ResumeInst *RI : Resumes) {
    BasicBlock *Parent = RI->getParent();
    BranchInst::Create(UnwindBB, Parent);

    Value *ExnObj = GetExceptionObject(RI);
    PN->addIncoming(ExnObj, Parent);

    ++NumResumesLowered;
  }

  // Call the function.
  CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB);
  CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));

  // We never expect _Unwind_Resume to return.
  new UnreachableInst(Ctx, UnwindBB);
  return true;
}

bool DwarfEHPrepare::runOnFunction(Function &Fn) {
  const TargetMachine &TM =
      getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
  DT = OptLevel != CodeGenOpt::None
      ? &getAnalysis<DominatorTreeWrapperPass>().getDomTree() : nullptr;
  TLI = TM.getSubtargetImpl(Fn)->getTargetLowering();
  bool Changed = InsertUnwindResumeCalls(Fn);
  DT = nullptr;
  TLI = nullptr;
  return Changed;
}
