//===- OCLUtil.cpp - OCL Utilities ----------------------------------------===//
//
//                     The LLVM/SPIRV Translator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal with the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimers.
// Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimers in the documentation
// and/or other materials provided with the distribution.
// Neither the names of Advanced Micro Devices, Inc., nor the names of its
// contributors may be used to endorse or promote products derived from this
// Software without specific prior written permission.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
// THE SOFTWARE.
//
//===----------------------------------------------------------------------===//
//
// This file implements OCL utility functions.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "oclutil"

#include "SPIRVInternal.h"
#include "OCLUtil.h"
#include "SPIRVEntry.h"
#include "SPIRVFunction.h"
#include "SPIRVInstruction.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Pass.h"
#include "llvm/PassSupport.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace SPIRV;

namespace OCLUtil {


#ifndef SPIRV_OCL_SPECIAL_TYPES_DEFAULT_ADDR_SPACE
  #define SPIRV_OCL_SPECIAL_TYPES_DEFAULT_ADDR_SPACE SPIRAS_Private
#endif

#ifndef SPIRV_QUEUE_T_ADDR_SPACE
  #define SPIRV_QUEUE_T_ADDR_SPACE SPIRV_OCL_SPECIAL_TYPES_DEFAULT_ADDR_SPACE
#endif

#ifndef SPIRV_EVENT_T_ADDR_SPACE
  #define SPIRV_EVENT_T_ADDR_SPACE SPIRV_OCL_SPECIAL_TYPES_DEFAULT_ADDR_SPACE
#endif

#ifndef SPIRV_CLK_EVENT_T_ADDR_SPACE
  #define SPIRV_CLK_EVENT_T_ADDR_SPACE SPIRV_OCL_SPECIAL_TYPES_DEFAULT_ADDR_SPACE
#endif

#ifndef SPIRV_RESERVE_ID_T_ADDR_SPACE
  #define SPIRV_RESERVE_ID_T_ADDR_SPACE SPIRV_OCL_SPECIAL_TYPES_DEFAULT_ADDR_SPACE
#endif
// Excerpt from SPIR 2.0 spec.:
//   Pipe objects are represented using pointers to the opaque %opencl.pipe LLVM structure type
//   which reside in the global address space.
#ifndef SPIRV_PIPE_ADDR_SPACE
  #define SPIRV_PIPE_ADDR_SPACE SPIRAS_Global
#endif
// Excerpt from SPIR 2.0 spec.:
//   Note: Images data types reside in global memory and hence should be marked as such in the
//   "kernel arg addr space" metadata.
#ifndef SPIRV_IMAGE_ADDR_SPACE
  #define SPIRV_IMAGE_ADDR_SPACE SPIRAS_Global
#endif

///////////////////////////////////////////////////////////////////////////////
//
// Functions for getting builtin call info
//
///////////////////////////////////////////////////////////////////////////////
AtomicWorkItemFenceLiterals getAtomicWorkItemFenceLiterals(CallInst* CI) {
  return std::make_tuple(getArgAsInt(CI, 0),
    static_cast<OCLMemOrderKind>(getArgAsInt(CI, 1)),
    static_cast<OCLScopeKind>(getArgAsInt(CI, 2)));
}

size_t getAtomicBuiltinNumMemoryOrderArgs(StringRef Name) {
  if (Name.startswith("atomic_compare_exchange"))
    return 2;
  return 1;
}

BarrierLiterals getBarrierLiterals(CallInst* CI){
  auto N = CI->getNumArgOperands();
  assert (N == 1 || N == 2);

  std::string DemangledName;
  if (!oclIsBuiltin(CI->getCalledFunction()->getName(), &DemangledName)) {
    assert(0 && "call must a builtin (work_group_barrier or sub_group_barrier)");
  }

  OCLScopeKind scope = OCLMS_work_group;
  if (DemangledName == kOCLBuiltinName::SubGroupBarrier) {
    scope = OCLMS_sub_group;
  }

  return std::make_tuple(getArgAsInt(CI, 0),
    N == 1 ? OCLMS_work_group : static_cast<OCLScopeKind>(getArgAsInt(CI, 1)),
    scope);
}

unsigned
getExtOp(StringRef OrigName, const std::string &GivenDemangledName) {
  std::string DemangledName = GivenDemangledName;
  if (!oclIsBuiltin(OrigName, DemangledName.empty() ? &DemangledName : nullptr))
    return ~0U;
  DEBUG(dbgs() << "getExtOp: demangled name: " << DemangledName << '\n');
  OCLExtOpKind EOC;
  bool Found = OCLExtOpMap::rfind(DemangledName, &EOC);
  if (!Found) {
    std::string Prefix;
    switch (LastFuncParamType(OrigName)) {
    case ParamType::UNSIGNED:
      Prefix = "u_";
      break;
    case ParamType::SIGNED:
      Prefix = "s_";
      break;
    case ParamType::FLOAT:
      Prefix = "f";
      break;
    default:
      llvm_unreachable("unknown mangling!");
    }
    Found = OCLExtOpMap::rfind(Prefix + DemangledName, &EOC);
  }
  if (Found)
    return EOC;
  else
    return ~0U;
}

std::unique_ptr<SPIRVEntry>
getSPIRVInst(const OCLBuiltinTransInfo &Info) {
  Op OC = OpNop;
  unsigned ExtOp = ~0U;
  SPIRVEntry *Entry = nullptr;
  if (OCLSPIRVBuiltinMap::find(Info.UniqName, &OC))
    Entry = SPIRVEntry::create(OC);
  else if ((ExtOp = getExtOp(Info.MangledName, Info.UniqName)) != ~0U)
    Entry = static_cast<SPIRVEntry*>(
        SPIRVEntry::create_unique(SPIRVEIS_OpenCL, ExtOp).get());
  return std::unique_ptr<SPIRVEntry>(Entry);
}

///////////////////////////////////////////////////////////////////////////////
//
// Functions for getting module info
//
///////////////////////////////////////////////////////////////////////////////

unsigned
encodeOCLVer(unsigned short Major,
    unsigned char Minor, unsigned char Rev) {
  return (Major * 100 + Minor) * 1000 + Rev;
}

std::tuple<unsigned short, unsigned char, unsigned char>
decodeOCLVer(unsigned Ver) {
  unsigned short Major = Ver / 100000;
  unsigned char Minor = (Ver % 100000) / 1000;
  unsigned char Rev = Ver % 1000;
  return std::make_tuple(Major, Minor, Rev);
}

unsigned getOCLVersion(Module *M, bool AllowMulti) {
  NamedMDNode *NamedMD = M->getNamedMetadata(kSPIR2MD::OCLVer);
  if (!NamedMD)
    return 0;
  assert (NamedMD->getNumOperands() > 0 && "Invalid SPIR");
  if (!AllowMulti && NamedMD->getNumOperands() != 1)
    report_fatal_error("Multiple OCL version metadata not allowed");

  // If the module was linked with another module, there may be multiple
  // operands.
  auto getVer = [=](unsigned I) {
    auto MD = NamedMD->getOperand(I);
    return std::make_pair(getMDOperandAsInt(MD, 0), getMDOperandAsInt(MD, 1));
  };
  auto Ver = getVer(0);
  for (unsigned I = 1, E = NamedMD->getNumOperands(); I != E; ++I)
    if (Ver != getVer(I))
      report_fatal_error("OCL version mismatch");

  return encodeOCLVer(Ver.first, Ver.second, 0);
}

void
decodeMDNode(MDNode* N, unsigned& X, unsigned& Y, unsigned& Z) {
  if (N == NULL)
    return;
  X = getMDOperandAsInt(N, 1);
  Y = getMDOperandAsInt(N, 2);
  Z = getMDOperandAsInt(N, 3);
}

/// Encode LLVM type by SPIR-V execution mode VecTypeHint
unsigned
encodeVecTypeHint(Type *Ty){
  if (Ty->isHalfTy())
    return 4;
  if (Ty->isFloatTy())
    return 5;
  if (Ty->isDoubleTy())
    return 6;
  if (IntegerType* intTy = dyn_cast<IntegerType>(Ty)) {
    switch (intTy->getIntegerBitWidth()) {
    case 8:
      return 0;
    case 16:
      return 1;
    case 32:
      return 2;
    case 64:
      return 3;
    default:
      llvm_unreachable("invalid integer type");
    }
  }
  if (VectorType* VecTy = dyn_cast<VectorType>(Ty)) {
    Type* EleTy = VecTy->getElementType();
    unsigned Size = VecTy->getVectorNumElements();
    return Size << 16 | encodeVecTypeHint(EleTy);
  }
  llvm_unreachable("invalid type");
}

Type *
decodeVecTypeHint(LLVMContext &C, unsigned code) {
  unsigned VecWidth = code >> 16;
  unsigned Scalar = code & 0xFFFF;
  Type *ST = nullptr;
  switch(Scalar) {
  case 0:
  case 1:
  case 2:
  case 3:
    ST = IntegerType::get(C, 1 << (3 + Scalar));
    break;
  case 4:
    ST = Type::getHalfTy(C);
    break;
  case 5:
    ST = Type::getFloatTy(C);
    break;
  case 6:
    ST = Type::getDoubleTy(C);
    break;
  default:
    llvm_unreachable("Invalid vec type hint");
  }
  if (VecWidth < 1)
    return ST;
  return VectorType::get(ST, VecWidth);
}

unsigned
transVecTypeHint(MDNode* Node) {
  return encodeVecTypeHint(getMDOperandAsType(Node, 1));
}

SPIRAddressSpace
getOCLOpaqueTypeAddrSpace(Op OpCode) {
  switch (OpCode) {
  case OpTypeQueue:
    return SPIRV_QUEUE_T_ADDR_SPACE;
  case OpTypeEvent:
    return SPIRV_EVENT_T_ADDR_SPACE;
  case OpTypeDeviceEvent:
    return SPIRV_CLK_EVENT_T_ADDR_SPACE;
  case OpTypeReserveId:
    return SPIRV_RESERVE_ID_T_ADDR_SPACE;
  case OpTypePipe:
  case OpTypePipeStorage:
    return SPIRV_PIPE_ADDR_SPACE;
  case OpTypeImage:
  case OpTypeSampledImage:
    return SPIRV_IMAGE_ADDR_SPACE;
  default:
    assert(false && "No address space is determined for some OCL type");
    return SPIRV_OCL_SPECIAL_TYPES_DEFAULT_ADDR_SPACE;
  }
}

static SPIR::TypeAttributeEnum
mapAddrSpaceEnums(SPIRAddressSpace addrspace)
{
  switch (addrspace) {
  case SPIRAS_Private:
    return SPIR::ATTR_PRIVATE;
  case SPIRAS_Global:
    return SPIR::ATTR_GLOBAL;
  case SPIRAS_Constant:
    return SPIR::ATTR_CONSTANT;
  case SPIRAS_Local:
    return SPIR::ATTR_LOCAL;
  case SPIRAS_Generic:
    return SPIR::ATTR_GENERIC;
  default:
    llvm_unreachable("Invalid addrspace enum member");
  }
}

SPIR::TypeAttributeEnum
getOCLOpaqueTypeAddrSpace(SPIR::TypePrimitiveEnum prim) {
  switch (prim) {
  case SPIR::PRIMITIVE_QUEUE_T:
    return mapAddrSpaceEnums(SPIRV_QUEUE_T_ADDR_SPACE);
  case SPIR::PRIMITIVE_EVENT_T:
    return mapAddrSpaceEnums(SPIRV_EVENT_T_ADDR_SPACE);
  case SPIR::PRIMITIVE_CLK_EVENT_T:
    return mapAddrSpaceEnums(SPIRV_CLK_EVENT_T_ADDR_SPACE);
  case SPIR::PRIMITIVE_RESERVE_ID_T:
    return mapAddrSpaceEnums(SPIRV_RESERVE_ID_T_ADDR_SPACE);
  case SPIR::PRIMITIVE_PIPE_T:
    return mapAddrSpaceEnums(SPIRV_PIPE_ADDR_SPACE);
  case SPIR::PRIMITIVE_IMAGE_1D_T:
  case SPIR::PRIMITIVE_IMAGE_1D_ARRAY_T:
  case SPIR::PRIMITIVE_IMAGE_1D_BUFFER_T:
  case SPIR::PRIMITIVE_IMAGE_2D_T:
  case SPIR::PRIMITIVE_IMAGE_2D_ARRAY_T:
  case SPIR::PRIMITIVE_IMAGE_3D_T:
  case SPIR::PRIMITIVE_IMAGE_2D_MSAA_T:
  case SPIR::PRIMITIVE_IMAGE_2D_ARRAY_MSAA_T:
  case SPIR::PRIMITIVE_IMAGE_2D_MSAA_DEPTH_T:
  case SPIR::PRIMITIVE_IMAGE_2D_ARRAY_MSAA_DEPTH_T:
  case SPIR::PRIMITIVE_IMAGE_2D_DEPTH_T:
  case SPIR::PRIMITIVE_IMAGE_2D_ARRAY_DEPTH_T:
    return mapAddrSpaceEnums(SPIRV_IMAGE_ADDR_SPACE);
  default:
    llvm_unreachable("No address space is determined for a SPIR primitive");
  }
}

// Fetch type of invoke function passed to device execution built-ins
static FunctionType *
getBlockInvokeTy(Function * F, unsigned blockIdx) {
    auto params = F->getFunctionType()->params();
    PointerType * funcPtr = cast<PointerType>(params[blockIdx]);
    return cast<FunctionType>(funcPtr->getElementType());
}

class OCLBuiltinFuncMangleInfo : public SPIRV::BuiltinFuncMangleInfo {
public:
  OCLBuiltinFuncMangleInfo(Function * f) : F(f) {}
  void init(const std::string &UniqName) {
  UnmangledName = UniqName;
  size_t Pos = std::string::npos;

  if (UnmangledName.find("async_work_group") == 0) {
    addUnsignedArg(-1);
    setArgAttr(1, SPIR::ATTR_CONST);
  } else if (UnmangledName.find("write_imageui") == 0)
      addUnsignedArg(2);
  else if (UnmangledName == "prefetch") {
    addUnsignedArg(1);
    setArgAttr(0, SPIR::ATTR_CONST);
  } else if(UnmangledName == "get_kernel_work_group_size" ||
            UnmangledName == "get_kernel_preferred_work_group_size_multiple") {
    assert(F && "lack of necessary information");
    const size_t blockArgIdx = 0;
    FunctionType * InvokeTy = getBlockInvokeTy(F, blockArgIdx);
    if(InvokeTy->getNumParams() > 1) setLocalArgBlock(blockArgIdx);
  } else if (UnmangledName == "enqueue_kernel") {
    assert(F && "lack of necessary information");
    setEnumArg(1, SPIR::PRIMITIVE_KERNEL_ENQUEUE_FLAGS_T);
    addUnsignedArg(3);
    setArgAttr(4, SPIR::ATTR_CONST);
    // If there are arguments other then block context then these are pointers
    // to local memory so this built-in must be mangled accordingly.
    const size_t blockArgIdx = 6;
    FunctionType * InvokeTy = getBlockInvokeTy(F, blockArgIdx);
    if(InvokeTy->getNumParams() > 1) {
       setLocalArgBlock(blockArgIdx);
       addUnsignedArg(blockArgIdx + 1);
       setVarArg(blockArgIdx + 2);
    }
  } else if (UnmangledName.find("get_") == 0 ||
      UnmangledName == "nan" ||
      UnmangledName == "mem_fence" ||
      UnmangledName.find("shuffle") == 0){
    addUnsignedArg(-1);
    if (UnmangledName.find(kOCLBuiltinName::GetFence) == 0){
      setArgAttr(0, SPIR::ATTR_CONST);
      addVoidPtrArg(0);
    }
  } else if (UnmangledName.find("barrier") == 0 ||
             UnmangledName.find("work_group_barrier") == 0 ||
             UnmangledName.find("sub_group_barrier") == 0) {
    addUnsignedArg(0);
  } else if (UnmangledName.find("atomic_work_item_fence") == 0) {
    addUnsignedArg(0);
  } else if (UnmangledName.find("atomic") == 0) {
    setArgAttr(0, SPIR::ATTR_VOLATILE);
    if (UnmangledName.find("atomic_umax") == 0 ||
        UnmangledName.find("atomic_umin") == 0) {
      addUnsignedArg(0);
      addUnsignedArg(1);
      UnmangledName.erase(7, 1);
    } else if (UnmangledName.find("atomic_fetch_umin") == 0 ||
               UnmangledName.find("atomic_fetch_umax") == 0) {
      addUnsignedArg(0);
      addUnsignedArg(1);
      UnmangledName.erase(13, 1);
    }
    // Don't set atomic property to the first argument of 1.2 atomic built-ins.
    if(UnmangledName.find("atomic_add")  != 0 && UnmangledName.find("atomic_sub") != 0 &&
       UnmangledName.find("atomic_xchg") != 0 && UnmangledName.find("atomic_inc") != 0 &&
       UnmangledName.find("atomic_dec")  != 0 && UnmangledName.find("atomic_cmpxchg") != 0 &&
       UnmangledName.find("atomic_min")  != 0 && UnmangledName.find("atomic_max") != 0 &&
       UnmangledName.find("atomic_and")  != 0 && UnmangledName.find("atomic_or") != 0 &&
       UnmangledName.find("atomic_xor")  != 0 && UnmangledName.find("atom_") != 0) {
      addAtomicArg(0);
    }

  } else if (UnmangledName.find("uconvert_") == 0) {
    addUnsignedArg(0);
    UnmangledName.erase(0, 1);
  } else if (UnmangledName.find("s_") == 0) {
    UnmangledName.erase(0, 2);
  } else if (UnmangledName.find("u_") == 0) {
    addUnsignedArg(-1);
    UnmangledName.erase(0, 2);
  } else if (UnmangledName == "fclamp") {
    UnmangledName.erase(0, 1);
  } else if (UnmangledName == "read_pipe" || UnmangledName == "write_pipe") {
    assert(F && "lack of necessary information");
    // handle [read|write]pipe builtins (plus two i32 literal args
    // required by SPIR 2.0 provisional specification):
    if (F->getArgumentList().size() == 6) {
      // with 4 arguments (plus two i32 literals):
      // int read_pipe (read_only pipe gentype p, reserve_id_t reserve_id, uint index, gentype *ptr)
      // int write_pipe (write_only pipe gentype p, reserve_id_t reserve_id, uint index, const gentype *ptr)
      addUnsignedArg(2);
      addVoidPtrArg(3);
      addUnsignedArg(4);
      addUnsignedArg(5);
    } else if (F->getArgumentList().size() == 4) {
      // with 2 arguments (plus two i32 literals):
      // int read_pipe (read_only pipe gentype p, gentype *ptr)
      // int write_pipe (write_only pipe gentype p, const gentype *ptr)
      addVoidPtrArg(1);
      addUnsignedArg(2);
      addUnsignedArg(3);
    } else {
      llvm_unreachable("read/write pipe builtin with unexpected number of arguments");
    }
  } else if (UnmangledName.find("reserve_read_pipe") != std::string::npos ||
             UnmangledName.find("reserve_write_pipe") != std::string::npos) {
    // process [|work_group|sub_group]reserve[read|write]pipe builtins
    addUnsignedArg(1);
    addUnsignedArg(2);
    addUnsignedArg(3);
  } else if (UnmangledName.find("commit_read_pipe") != std::string::npos ||
             UnmangledName.find("commit_write_pipe") != std::string::npos) {
    // process [|work_group|sub_group]commit[read|write]pipe builtins
    addUnsignedArg(2);
    addUnsignedArg(3);
  } else if (UnmangledName == "capture_event_profiling_info") {
    addVoidPtrArg(2);
    setEnumArg(1, SPIR::PRIMITIVE_CLK_PROFILING_INFO);
  } else if (UnmangledName == "enqueue_marker") {
    setArgAttr(2, SPIR::ATTR_CONST);
    addUnsignedArg(1);
  } else if (UnmangledName.find("vload") == 0) {
    addUnsignedArg(0);
    setArgAttr(1, SPIR::ATTR_CONST);
  } else if (UnmangledName.find("vstore") == 0 ){
    addUnsignedArg(1);
  } else if (UnmangledName.find("ndrange_") == 0) {
    addUnsignedArg(-1);
    if (UnmangledName[8] == '2' || UnmangledName[8] == '3') {
      setArgAttr(-1, SPIR::ATTR_CONST);
    }
  } else if ((Pos = UnmangledName.find("umax")) != std::string::npos ||
             (Pos = UnmangledName.find("umin")) != std::string::npos) {
    addUnsignedArg(-1);
    UnmangledName.erase(Pos, 1);
  } else if (UnmangledName.find("broadcast") != std::string::npos)
    addUnsignedArg(-1);
  else if (UnmangledName.find(kOCLBuiltinName::SampledReadImage) == 0) {
    UnmangledName.erase(0, strlen(kOCLBuiltinName::Sampled));
    addSamplerArg(1);
  }
}
// Auxiliarry information, it is expected what it is relevant at the moment
// the init method is called.
Function * F; // SPIRV decorated function
};

CallInst *
mutateCallInstOCL(Module *M, CallInst *CI,
    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
    AttributeSet *Attrs) {
  OCLBuiltinFuncMangleInfo BtnInfo(CI->getCalledFunction());
  return mutateCallInst(M, CI, ArgMutate, &BtnInfo, Attrs);
}

Instruction *
mutateCallInstOCL(Module *M, CallInst *CI,
    std::function<std::string (CallInst *, std::vector<Value *> &,
        Type *&RetTy)> ArgMutate,
    std::function<Instruction *(CallInst *)> RetMutate,
    AttributeSet *Attrs) {
  OCLBuiltinFuncMangleInfo BtnInfo(CI->getCalledFunction());
  return mutateCallInst(M, CI, ArgMutate, RetMutate, &BtnInfo, Attrs);
}

void
mutateFunctionOCL(Function *F,
    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
    AttributeSet *Attrs) {
  OCLBuiltinFuncMangleInfo BtnInfo(F);
  return mutateFunction(F, ArgMutate, &BtnInfo, Attrs, false);
}

static std::pair<StringRef, StringRef>
getSrcAndDstElememntTypeName(BitCastInst* BIC) {
  if (!BIC)
    return std::pair<StringRef, StringRef>("", "");

  Type *SrcTy = BIC->getSrcTy();
  Type *DstTy = BIC->getDestTy();
  if (SrcTy->isPointerTy())
    SrcTy = SrcTy->getPointerElementType();
  if (DstTy->isPointerTy())
    DstTy = DstTy->getPointerElementType();
  auto SrcST = dyn_cast<StructType>(SrcTy);
  auto DstST = dyn_cast<StructType>(DstTy);
  if (!DstST || !DstST->hasName() || !SrcST || !SrcST->hasName())
    return std::pair<StringRef, StringRef>("", "");

  return std::make_pair(SrcST->getName(), DstST->getName());
}

bool
isSamplerInitializer(Instruction *Inst) {
  BitCastInst *BIC = dyn_cast<BitCastInst>(Inst);
  auto Names = getSrcAndDstElememntTypeName(BIC);
  if (Names.second == getSPIRVTypeName(kSPIRVTypeName::Sampler) &&
      Names.first == getSPIRVTypeName(kSPIRVTypeName::ConstantSampler))
    return true;
  
  return false;
}

bool
isPipeStorageInitializer(Instruction *Inst) {
  BitCastInst *BIC = dyn_cast<BitCastInst>(Inst);
  auto Names = getSrcAndDstElememntTypeName(BIC);
  if (Names.second == getSPIRVTypeName(kSPIRVTypeName::PipeStorage) &&
    Names.first == getSPIRVTypeName(kSPIRVTypeName::ConstantPipeStorage))
    return true;

  return false;
}

bool
isSpecialTypeInitializer(Instruction* Inst) {
  return isSamplerInitializer(Inst) || isPipeStorageInitializer(Inst);
}

} // namespace OCLUtil

void
llvm::MangleOpenCLBuiltin(const std::string &UniqName,
    ArrayRef<Type*> ArgTypes, std::string &MangledName) {
  OCLUtil::OCLBuiltinFuncMangleInfo BtnInfo(nullptr);
  MangledName = SPIRV::mangleBuiltin(UniqName, ArgTypes, &BtnInfo);
}
