//===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
/// \file
/// This file defines common definitions/declarations used by the ObjC ARC
/// Optimizer. ARC stands for Automatic Reference Counting and is a system for
/// managing reference counts for objects in Objective C.
///
/// WARNING: This file knows about certain library functions. It recognizes them
/// by name, and hardwires knowledge of their semantics.
///
/// WARNING: This file knows about how certain Objective-C library functions are
/// used. Naive LLVM IR transformations which would otherwise be
/// behavior-preserving may break these assumptions.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H

#include "ARCRuntimeEntryPoints.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/Transforms/Utils/Local.h"

namespace llvm {
namespace objcarc {

/// Erase the given instruction.
///
/// Many ObjC calls return their argument verbatim,
/// so if it's such a call and the return value has users, replace them with the
/// argument value.
///
static inline void EraseInstruction(Instruction *CI) {
  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);

  bool Unused = CI->use_empty();

  if (!Unused) {
    // Replace the return value with the argument.
    assert((IsForwarding(GetBasicARCInstKind(CI)) ||
            (IsNoopOnNull(GetBasicARCInstKind(CI)) &&
             IsNullOrUndef(OldArg->stripPointerCasts()))) &&
           "Can't delete non-forwarding instruction with users!");
    CI->replaceAllUsesWith(OldArg);
  }

  CI->eraseFromParent();

  if (Unused)
    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
}

/// If Inst is a ReturnRV and its operand is a call or invoke, return the
/// operand. Otherwise return null.
static inline const Instruction *getreturnRVOperand(const Instruction &Inst,
                                                    ARCInstKind Class) {
  if (Class != ARCInstKind::RetainRV)
    return nullptr;

  const auto *Opnd = Inst.getOperand(0)->stripPointerCasts();
  if (const auto *C = dyn_cast<CallInst>(Opnd))
    return C;
  return dyn_cast<InvokeInst>(Opnd);
}

/// Return the list of PHI nodes that are equivalent to PN.
template<class PHINodeTy, class VectorTy>
void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) {
  auto *BB = PN.getParent();
  for (auto &P : BB->phis()) {
    if (&P == &PN) // Do not add PN to the list.
      continue;
    unsigned I = 0, E = PN.getNumIncomingValues();
    for (; I < E; ++I) {
      auto *BB = PN.getIncomingBlock(I);
      auto *PNOpnd = PN.getIncomingValue(I)->stripPointerCasts();
      auto *POpnd = P.getIncomingValueForBlock(BB)->stripPointerCasts();
      if (PNOpnd != POpnd)
        break;
    }
    if (I == E)
      PHIList.push_back(&P);
  }
}

static inline MDString *getRVInstMarker(Module &M) {
  const char *MarkerKey = getRVMarkerModuleFlagStr();
  return dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
}

/// Create a call instruction with the correct funclet token. This should be
/// called instead of calling CallInst::Create directly unless the call is
/// going to be removed from the IR before WinEHPrepare.
CallInst *createCallInstWithColors(
    FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,
    Instruction *InsertBefore,
    const DenseMap<BasicBlock *, ColorVector> &BlockColors);

class BundledRetainClaimRVs {
public:
  BundledRetainClaimRVs(ARCRuntimeEntryPoints &P, bool ContractPass)
      : EP(P), ContractPass(ContractPass) {}
  ~BundledRetainClaimRVs();

  /// Insert a retainRV/claimRV call to the normal destination blocks of invokes
  /// with operand bundle "clang.arc.attachedcall". If the edge to the normal
  /// destination block is a critical edge, split it.
  std::pair<bool, bool> insertAfterInvokes(Function &F, DominatorTree *DT);

  /// Insert a retainRV/claimRV call.
  CallInst *insertRVCall(Instruction *InsertPt, CallBase *AnnotatedCall);

  /// Insert a retainRV/claimRV call with colors.
  CallInst *insertRVCallWithColors(
      Instruction *InsertPt, CallBase *AnnotatedCall,
      const DenseMap<BasicBlock *, ColorVector> &BlockColors);

  /// See if an instruction is a bundled retainRV/claimRV call.
  bool contains(const Instruction *I) const {
    if (auto *CI = dyn_cast<CallInst>(I))
      return RVCalls.count(CI);
    return false;
  }

  /// Remove a retainRV/claimRV call entirely.
  void eraseInst(CallInst *CI) {
    auto It = RVCalls.find(CI);
    if (It != RVCalls.end()) {
      // Remove call to @llvm.objc.clang.arc.noop.use.
      for (auto U = It->second->user_begin(), E = It->second->user_end(); U != E; ++U)
        if (auto *CI = dyn_cast<CallInst>(*U))
          if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) {
            CI->eraseFromParent();
            break;
          }

      auto *NewCall = CallBase::removeOperandBundle(
          It->second, LLVMContext::OB_clang_arc_attachedcall, It->second);
      NewCall->copyMetadata(*It->second);
      It->second->replaceAllUsesWith(NewCall);
      It->second->eraseFromParent();
      RVCalls.erase(It);
    }
    EraseInstruction(CI);
  }

private:
  /// A map of inserted retainRV/claimRV calls to annotated calls/invokes.
  DenseMap<CallInst *, CallBase *> RVCalls;

  ARCRuntimeEntryPoints &EP;
  bool ContractPass;
};

} // end namespace objcarc
} // end namespace llvm

#endif
