//===-- ObjCARC.cpp -------------------------------------------------------===//
//
// 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 file implements common infrastructure for libLLVMObjCARCOpts.a, which
// implements several scalar transformations over the LLVM intermediate
// representation, including the C bindings for that library.
//
//===----------------------------------------------------------------------===//

#include "ObjCARC.h"
#include "llvm-c/Initialization.h"
#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"

namespace llvm {
  class PassRegistry;
}

using namespace llvm;
using namespace llvm::objcarc;

/// initializeObjCARCOptsPasses - Initialize all passes linked into the
/// ObjCARCOpts library.
void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
  initializeObjCARCAAWrapperPassPass(Registry);
  initializeObjCARCAPElimPass(Registry);
  initializeObjCARCExpandPass(Registry);
  initializeObjCARCContractLegacyPassPass(Registry);
  initializeObjCARCOptLegacyPassPass(Registry);
  initializePAEvalPass(Registry);
}

void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R) {
  initializeObjCARCOpts(*unwrap(R));
}

CallInst *objcarc::createCallInstWithColors(
    FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,
    Instruction *InsertBefore,
    const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
  FunctionType *FTy = Func.getFunctionType();
  Value *Callee = Func.getCallee();
  SmallVector<OperandBundleDef, 1> OpBundles;

  if (!BlockColors.empty()) {
    const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second;
    assert(CV.size() == 1 && "non-unique color for block!");
    Instruction *EHPad = CV.front()->getFirstNonPHI();
    if (EHPad->isEHPad())
      OpBundles.emplace_back("funclet", EHPad);
  }

  return CallInst::Create(FTy, Callee, Args, OpBundles, NameStr, InsertBefore);
}

std::pair<bool, bool>
BundledRetainClaimRVs::insertAfterInvokes(Function &F, DominatorTree *DT) {
  bool Changed = false, CFGChanged = false;

  for (BasicBlock &BB : F) {
    auto *I = dyn_cast<InvokeInst>(BB.getTerminator());

    if (!I)
      continue;

    if (!objcarc::hasAttachedCallOpBundle(I))
      continue;

    BasicBlock *DestBB = I->getNormalDest();

    if (!DestBB->getSinglePredecessor()) {
      assert(I->getSuccessor(0) == DestBB &&
             "the normal dest is expected to be the first successor");
      DestBB = SplitCriticalEdge(I, 0, CriticalEdgeSplittingOptions(DT));
      CFGChanged = true;
    }

    // We don't have to call insertRVCallWithColors since DestBB is the normal
    // destination of the invoke.
    insertRVCall(&*DestBB->getFirstInsertionPt(), I);
    Changed = true;
  }

  return std::make_pair(Changed, CFGChanged);
}

CallInst *BundledRetainClaimRVs::insertRVCall(Instruction *InsertPt,
                                              CallBase *AnnotatedCall) {
  DenseMap<BasicBlock *, ColorVector> BlockColors;
  return insertRVCallWithColors(InsertPt, AnnotatedCall, BlockColors);
}

CallInst *BundledRetainClaimRVs::insertRVCallWithColors(
    Instruction *InsertPt, CallBase *AnnotatedCall,
    const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
  IRBuilder<> Builder(InsertPt);
  Function *Func = *objcarc::getAttachedARCFunction(AnnotatedCall);
  assert(Func && "operand isn't a Function");
  Type *ParamTy = Func->getArg(0)->getType();
  Value *CallArg = Builder.CreateBitCast(AnnotatedCall, ParamTy);
  auto *Call =
      createCallInstWithColors(Func, CallArg, "", InsertPt, BlockColors);
  RVCalls[Call] = AnnotatedCall;
  return Call;
}

BundledRetainClaimRVs::~BundledRetainClaimRVs() {
  for (auto P : RVCalls) {
    if (ContractPass) {
      CallBase *CB = P.second;
      // At this point, we know that the annotated calls can't be tail calls
      // as they are followed by marker instructions and retainRV/claimRV
      // calls. Mark them as notail so that the backend knows these calls
      // can't be tail calls.
      if (auto *CI = dyn_cast<CallInst>(CB))
        CI->setTailCallKind(CallInst::TCK_NoTail);
    }

    EraseInstruction(P.first);
  }

  RVCalls.clear();
}
