//===--- ARCEntryPointBuilder.h ---------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_LLVMPASSES_ARCENTRYPOINTBUILDER_H
#define SWIFT_LLVMPASSES_ARCENTRYPOINTBUILDER_H

#include "swift/Basic/LLVM.h"
#include "swift/Basic/NullablePtr.h"
#include "swift/Runtime/Config.h"
#include "swift/Runtime/RuntimeFnWrappersGen.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"

namespace swift {

namespace RuntimeConstants {
  const auto ReadNone = llvm::Attribute::ReadNone;
  const auto ReadOnly = llvm::Attribute::ReadOnly;
  const auto NoReturn = llvm::Attribute::NoReturn;
  const auto NoUnwind = llvm::Attribute::NoUnwind;
  const auto ZExt = llvm::Attribute::ZExt;
  const auto FirstParamReturned = llvm::Attribute::Returned;
}

using namespace RuntimeConstants;

/// A class for building ARC entry points. It is a composition wrapper around an
/// IRBuilder and a constant Cache. It cannot be moved or copied. It is meant
/// to be created once and passed around by reference.
class ARCEntryPointBuilder {
  using IRBuilder = llvm::IRBuilder<>;
  using Constant = llvm::Constant;
  using Type = llvm::Type;
  using Function = llvm::Function;
  using Instruction = llvm::Instruction;
  using CallInst = llvm::CallInst;
  using Value = llvm::Value;
  using Module = llvm::Module;
  using AttributeList = llvm::AttributeList;
  using Attribute = llvm::Attribute;
  using APInt = llvm::APInt;
  
  // The builder which we are wrapping.
  IRBuilder B;

  // The constant cache.
  NullablePtr<Constant> Retain;
  NullablePtr<Constant> Release;
  NullablePtr<Constant> CheckUnowned;
  NullablePtr<Constant> RetainN;
  NullablePtr<Constant> ReleaseN;
  NullablePtr<Constant> UnknownObjectRetainN;
  NullablePtr<Constant> UnknownObjectReleaseN;
  NullablePtr<Constant> BridgeRetainN;
  NullablePtr<Constant> BridgeReleaseN;

  // The type cache.
  NullablePtr<Type> ObjectPtrTy;
  NullablePtr<Type> BridgeObjectPtrTy;

  llvm::CallingConv::ID DefaultCC;

  llvm::CallInst *CreateCall(Constant *Fn, Value *V) {
    CallInst *CI = B.CreateCall(Fn, V);
    if (auto Fun = llvm::dyn_cast<llvm::Function>(Fn))
      CI->setCallingConv(Fun->getCallingConv());
    return CI;
  }

  llvm::CallInst *CreateCall(Constant *Fn, llvm::ArrayRef<Value *> Args) {
    CallInst *CI = B.CreateCall(Fn, Args);
    if (auto Fun = llvm::dyn_cast<llvm::Function>(Fn))
      CI->setCallingConv(Fun->getCallingConv());
    return CI;
  }

public:
  ARCEntryPointBuilder(Function &F)
      : B(&*F.begin()), Retain(), ObjectPtrTy(),
        DefaultCC(SWIFT_DEFAULT_LLVM_CC) { }

  ~ARCEntryPointBuilder() = default;
  ARCEntryPointBuilder(ARCEntryPointBuilder &&) = delete;
  ARCEntryPointBuilder(const ARCEntryPointBuilder &) = delete;

  ARCEntryPointBuilder &operator=(const ARCEntryPointBuilder &) = delete;
  void operator=(ARCEntryPointBuilder &&C) = delete;

  void setInsertPoint(Instruction *I) {
    B.SetInsertPoint(I);
  }

  Value *createInsertValue(Value *V1, Value *V2, unsigned Idx) {
    return B.CreateInsertValue(V1, V2, Idx);
  }

  Value *createExtractValue(Value *V, unsigned Idx) {
    return B.CreateExtractValue(V, Idx);
  }

  Value *createIntToPtr(Value *V, Type *Ty) {
    return B.CreateIntToPtr(V, Ty);
  }

  CallInst *createRetain(Value *V, CallInst *OrigI) {
    // Cast just to make sure that we have the right type.
    V = B.CreatePointerCast(V, getObjectPtrTy());

    // Create the call.
    CallInst *CI = CreateCall(getRetain(OrigI), V);
    return CI;
  }

  CallInst *createRelease(Value *V, CallInst *OrigI) {
    // Cast just to make sure that we have the right type.
    V = B.CreatePointerCast(V, getObjectPtrTy());

    // Create the call.
    CallInst *CI = CreateCall(getRelease(OrigI), V);
    return CI;
  }

  
  CallInst *createCheckUnowned(Value *V, CallInst *OrigI) {
    // Cast just to make sure that we have the right type.
    V = B.CreatePointerCast(V, getObjectPtrTy());
    
    CallInst *CI = CreateCall(getCheckUnowned(OrigI), V);
    return CI;
  }

  CallInst *createRetainN(Value *V, uint32_t n, CallInst *OrigI) {
    // Cast just to make sure that we have the right object type.
    V = B.CreatePointerCast(V, getObjectPtrTy());
    CallInst *CI = CreateCall(getRetainN(OrigI), {V, getIntConstant(n)});
    return CI;
  }

  CallInst *createReleaseN(Value *V, uint32_t n, CallInst *OrigI) {
    // Cast just to make sure we have the right object type.
    V = B.CreatePointerCast(V, getObjectPtrTy());
    CallInst *CI = CreateCall(getReleaseN(OrigI), {V, getIntConstant(n)});
    return CI;
  }

  CallInst *createUnknownObjectRetainN(Value *V, uint32_t n, CallInst *OrigI) {
    // Cast just to make sure that we have the right object type.
    V = B.CreatePointerCast(V, getObjectPtrTy());
    CallInst *CI =
        CreateCall(getUnknownObjectRetainN(OrigI), {V, getIntConstant(n)});
    return CI;
  }

  CallInst *createUnknownObjectReleaseN(Value *V, uint32_t n, CallInst *OrigI) {
    // Cast just to make sure we have the right object type.
    V = B.CreatePointerCast(V, getObjectPtrTy());
    CallInst *CI =
        CreateCall(getUnknownObjectReleaseN(OrigI), {V, getIntConstant(n)});
    return CI;
  }

  CallInst *createBridgeRetainN(Value *V, uint32_t n, CallInst *OrigI) {
    // Cast just to make sure we have the right object type.
    V = B.CreatePointerCast(V, getBridgeObjectPtrTy());
    CallInst *CI = CreateCall(getBridgeRetainN(OrigI), {V, getIntConstant(n)});
    return CI;
  }

  CallInst *createBridgeReleaseN(Value *V, uint32_t n, CallInst *OrigI) {
    // Cast just to make sure we have the right object type.
    V = B.CreatePointerCast(V, getBridgeObjectPtrTy());
    CallInst *CI = CreateCall(getBridgeReleaseN(OrigI), {V, getIntConstant(n)});
    return CI;
  }

  bool isNonAtomic(CallInst *I) {
    // If we have an intrinsic, we know it must be an objc intrinsic. All objc
    // intrinsics are atomic today.
    if (I->getIntrinsicID() != llvm::Intrinsic::not_intrinsic)
      return false;
    return (I->getCalledFunction()->getName().find("nonatomic") !=
            llvm::StringRef::npos);
  }

  bool isAtomic(CallInst *I) {
    return !isNonAtomic(I);
  }

  /// Perform a pointer cast of pointer value \p V to \p Ty if \p V has a
  /// different type than \p Ty. If \p V equals \p Ty, just return V.
  llvm::Value *maybeCast(llvm::Value *V, llvm::Type *Ty) {
    if (V->getType() == Ty)
      return V;
    return B.CreatePointerCast(V, Ty);
  }

private:
  Module &getModule() {
    return *B.GetInsertBlock()->getModule();
  }

  /// getRetain - Return a callable function for swift_retain.
  Constant *getRetain(CallInst *OrigI) {
    if (Retain)
      return Retain.get();
    auto *ObjectPtrTy = getObjectPtrTy();

    llvm::Constant *cache = nullptr;
    Retain = getRuntimeFn(
        getModule(), cache,
        isNonAtomic(OrigI) ? "swift_nonatomic_retain" : "swift_retain",
        DefaultCC, RuntimeAvailability::AlwaysAvailable, {ObjectPtrTy},
        {ObjectPtrTy}, {NoUnwind, FirstParamReturned});

    return Retain.get();
  }

  /// getRelease - Return a callable function for swift_release.
  Constant *getRelease(CallInst *OrigI) {
    if (Release)
      return Release.get();
    auto *ObjectPtrTy = getObjectPtrTy();
    auto *VoidTy = Type::getVoidTy(getModule().getContext());

    llvm::Constant *cache = nullptr;
    Release = getRuntimeFn(getModule(), cache,
                           isNonAtomic(OrigI) ? "swift_nonatomic_release"
                                              : "swift_release",
                           DefaultCC, RuntimeAvailability::AlwaysAvailable,
                           {VoidTy}, {ObjectPtrTy}, {NoUnwind});

    return Release.get();
  }

  Constant *getCheckUnowned(CallInst *OrigI) {
    if (CheckUnowned)
      return CheckUnowned.get();
    
    auto *ObjectPtrTy = getObjectPtrTy();
    auto &M = getModule();
    auto AttrList = AttributeList::get(M.getContext(), 1, Attribute::NoCapture);
    AttrList = AttrList.addAttribute(
        M.getContext(), AttributeList::FunctionIndex, Attribute::NoUnwind);
    CheckUnowned = cast<llvm::Function>(
        M.getOrInsertFunction("swift_checkUnowned", AttrList,
                              Type::getVoidTy(M.getContext()), ObjectPtrTy)
            .getCallee());
    if (llvm::Triple(M.getTargetTriple()).isOSBinFormatCOFF() &&
        !llvm::Triple(M.getTargetTriple()).isOSCygMing())
      if (auto *F = llvm::dyn_cast<llvm::Function>(CheckUnowned.get()))
        F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
    return CheckUnowned.get();
  }

  /// getRetainN - Return a callable function for swift_retain_n.
  Constant *getRetainN(CallInst *OrigI) {
    if (RetainN)
      return RetainN.get();
    auto *ObjectPtrTy = getObjectPtrTy();
    auto *Int32Ty = Type::getInt32Ty(getModule().getContext());

    llvm::Constant *cache = nullptr;
    RetainN = getRuntimeFn(
        getModule(), cache,
        isNonAtomic(OrigI) ? "swift_nonatomic_retain_n" : "swift_retain_n",
        DefaultCC, RuntimeAvailability::AlwaysAvailable, {ObjectPtrTy},
        {ObjectPtrTy, Int32Ty}, {NoUnwind, FirstParamReturned});

    return RetainN.get();
  }

  /// Return a callable function for swift_release_n.
  Constant *getReleaseN(CallInst *OrigI) {
    if (ReleaseN)
      return ReleaseN.get();
    auto *ObjectPtrTy = getObjectPtrTy();
    auto *Int32Ty = Type::getInt32Ty(getModule().getContext());
    auto *VoidTy = Type::getVoidTy(getModule().getContext());

    llvm::Constant *cache = nullptr;
    ReleaseN = getRuntimeFn(getModule(), cache,
                            isNonAtomic(OrigI) ? "swift_nonatomic_release_n"
                                               : "swift_release_n",
                            DefaultCC, RuntimeAvailability::AlwaysAvailable,
                            {VoidTy}, {ObjectPtrTy, Int32Ty}, {NoUnwind});

    return ReleaseN.get();
  }

  /// getUnknownObjectRetainN - Return a callable function for
  /// swift_unknownObjectRetain_n.
  Constant *getUnknownObjectRetainN(CallInst *OrigI) {
    if (UnknownObjectRetainN)
      return UnknownObjectRetainN.get();
    auto *ObjectPtrTy = getObjectPtrTy();
    auto *Int32Ty = Type::getInt32Ty(getModule().getContext());

    llvm::Constant *cache = nullptr;
    UnknownObjectRetainN = getRuntimeFn(
        getModule(), cache,
        isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRetain_n"
                           : "swift_unknownObjectRetain_n",
        DefaultCC, RuntimeAvailability::AlwaysAvailable, {ObjectPtrTy},
        {ObjectPtrTy, Int32Ty}, {NoUnwind, FirstParamReturned});

    return UnknownObjectRetainN.get();
  }

  /// Return a callable function for swift_unknownObjectRelease_n.
  Constant *getUnknownObjectReleaseN(CallInst *OrigI) {
    if (UnknownObjectReleaseN)
      return UnknownObjectReleaseN.get();
    auto *ObjectPtrTy = getObjectPtrTy();
    auto *Int32Ty = Type::getInt32Ty(getModule().getContext());
    auto *VoidTy = Type::getVoidTy(getModule().getContext());

    llvm::Constant *cache = nullptr;
    UnknownObjectReleaseN = getRuntimeFn(
        getModule(), cache,
        isNonAtomic(OrigI) ? "swift_nonatomic_unknownObjectRelease_n"
                           : "swift_unknownObjectRelease_n",
        DefaultCC, RuntimeAvailability::AlwaysAvailable, {VoidTy},
        {ObjectPtrTy, Int32Ty}, {NoUnwind});

    return UnknownObjectReleaseN.get();
  }

  /// Return a callable function for swift_bridgeRetain_n.
  Constant *getBridgeRetainN(CallInst *OrigI) {
    if (BridgeRetainN)
      return BridgeRetainN.get();
    auto *BridgeObjectPtrTy = getBridgeObjectPtrTy();
    auto *Int32Ty = Type::getInt32Ty(getModule().getContext());

    llvm::Constant *cache = nullptr;
    BridgeRetainN = getRuntimeFn(
        getModule(), cache,
        isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRetain_n"
                           : "swift_bridgeObjectRetain_n",
        DefaultCC, RuntimeAvailability::AlwaysAvailable, {BridgeObjectPtrTy},
        {BridgeObjectPtrTy, Int32Ty}, {NoUnwind});
    return BridgeRetainN.get();
  }

  /// Return a callable function for swift_bridgeRelease_n.
  Constant *getBridgeReleaseN(CallInst *OrigI) {
    if (BridgeReleaseN)
      return BridgeReleaseN.get();

    auto *BridgeObjectPtrTy = getBridgeObjectPtrTy();
    auto *Int32Ty = Type::getInt32Ty(getModule().getContext());
    auto *VoidTy = Type::getVoidTy(getModule().getContext());

    llvm::Constant *cache = nullptr;
    BridgeReleaseN = getRuntimeFn(
        getModule(), cache,
        isNonAtomic(OrigI) ? "swift_nonatomic_bridgeObjectRelease_n"
                           : "swift_bridgeObjectRelease_n",
        DefaultCC, RuntimeAvailability::AlwaysAvailable, {VoidTy},
        {BridgeObjectPtrTy, Int32Ty}, {NoUnwind});
    return BridgeReleaseN.get();
  }

  Type *getNamedOpaquePtrTy(StringRef name) {
    auto &M = getModule();
    if (auto *ty = M.getTypeByName(name)) {
      return ty->getPointerTo();
    }

    // Otherwise, create an anonymous struct type.
    auto *ty = llvm::StructType::create(M.getContext(), name);
    return ty->getPointerTo();
  }

  Type *getObjectPtrTy() {
    if (ObjectPtrTy)
      return ObjectPtrTy.get();
    ObjectPtrTy = getNamedOpaquePtrTy("swift.refcounted");
    return ObjectPtrTy.get();
  }

  Type *getBridgeObjectPtrTy() {
    if (BridgeObjectPtrTy)
      return BridgeObjectPtrTy.get();
    BridgeObjectPtrTy = getNamedOpaquePtrTy("swift.bridge");
    return BridgeObjectPtrTy.get();
  }

  Constant *getIntConstant(uint32_t constant) {
    auto &M = getModule();
    auto *Int32Ty = Type::getInt32Ty(M.getContext());
    return Constant::getIntegerValue(Int32Ty, APInt(32, constant));
  }
};

} // end swift namespace

#endif

