1//===- LLVMSPIRVInternal.h -  SPIR-V internal header file --------*- C++ -*-===//
2//
3//                     The LLVM/SPIRV Translator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
9//
10// Permission is hereby granted, free of charge, to any person obtaining a
11// copy of this software and associated documentation files (the "Software"),
12// to deal with the Software without restriction, including without limitation
13// the rights to use, copy, modify, merge, publish, distribute, sublicense,
14// and/or sell copies of the Software, and to permit persons to whom the
15// Software is furnished to do so, subject to the following conditions:
16//
17// Redistributions of source code must retain the above copyright notice,
18// this list of conditions and the following disclaimers.
19// Redistributions in binary form must reproduce the above copyright notice,
20// this list of conditions and the following disclaimers in the documentation
21// and/or other materials provided with the distribution.
22// Neither the names of Advanced Micro Devices, Inc., nor the names of its
23// contributors may be used to endorse or promote products derived from this
24// Software without specific prior written permission.
25// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
31// THE SOFTWARE.
32//
33//===----------------------------------------------------------------------===//
34/// \file
35///
36/// This file declares classes and functions shared by SPIR-V reader/writer.
37///
38//===----------------------------------------------------------------------===//
39#ifndef LLVMSPIRVINTERNAL_HPP_
40#define LLVMSPIRVINTERNAL_HPP_
41
42#include "libSPIRV/SPIRVUtil.h"
43#include "libSPIRV/SPIRVEnum.h"
44#include "libSPIRV/SPIRVNameMapEnum.h"
45#include "libSPIRV/SPIRVError.h"
46#include "libSPIRV/SPIRVType.h"
47#include "NameMangleAPI.h"
48
49#include "llvm/IR/Attributes.h"
50#include "llvm/IR/Constants.h"
51#include "llvm/IR/Instructions.h"
52#include "llvm/Support/SPIRV.h"
53
54#include <utility>
55#include <functional>
56
57using namespace SPIRV;
58using namespace llvm;
59
60namespace SPIRV{
61
62  /// The LLVM/SPIR-V translator version used to fill the lower 16 bits of the
63  /// generator's magic number in the generated SPIR-V module.
64  /// This number should be bumped up whenever the generated SPIR-V changes.
65  const static unsigned short kTranslatorVer = 14;
66
67#define SPCV_TARGET_LLVM_IMAGE_TYPE_ENCODE_ACCESS_QUAL 0
68// Workaround for SPIR 2 producer bug about kernel function calling convention.
69// This workaround checks metadata to determine if a function is kernel.
70#define SPCV_RELAX_KERNEL_CALLING_CONV 1
71
72class SPIRVOpaqueType;
73typedef SPIRVMap<std::string, Op, SPIRVOpaqueType>
74  SPIRVOpaqueTypeOpCodeMap;
75
76// Ad hoc function used by LLVM/SPIRV converter for type casting
77#define SPCV_CAST "spcv.cast"
78#define LLVM_MEMCPY "llvm.memcpy"
79
80namespace kOCLTypeQualifierName {
81  const static char *Const      = "const";
82  const static char *Volatile   = "volatile";
83  const static char *Restrict   = "restrict";
84  const static char *Pipe       = "pipe";
85}
86
87template<> inline void
88SPIRVMap<unsigned, Op>::init() {
89#define _SPIRV_OP(x,y) add(Instruction::x, Op##y);
90  /* Casts */
91    _SPIRV_OP(ZExt, UConvert)
92    _SPIRV_OP(SExt, SConvert)
93    _SPIRV_OP(Trunc, UConvert)
94    _SPIRV_OP(FPToUI, ConvertFToU)
95    _SPIRV_OP(FPToSI, ConvertFToS)
96    _SPIRV_OP(UIToFP, ConvertUToF)
97    _SPIRV_OP(SIToFP, ConvertSToF)
98    _SPIRV_OP(FPTrunc, FConvert)
99    _SPIRV_OP(FPExt, FConvert)
100    _SPIRV_OP(PtrToInt, ConvertPtrToU)
101    _SPIRV_OP(IntToPtr, ConvertUToPtr)
102    _SPIRV_OP(BitCast, Bitcast)
103    _SPIRV_OP(AddrSpaceCast, GenericCastToPtr)
104    _SPIRV_OP(GetElementPtr, AccessChain)
105  /*Binary*/
106    _SPIRV_OP(And, BitwiseAnd)
107    _SPIRV_OP(Or, BitwiseOr)
108    _SPIRV_OP(Xor, BitwiseXor)
109    _SPIRV_OP(Add, IAdd)
110    _SPIRV_OP(FAdd, FAdd)
111    _SPIRV_OP(Sub, ISub)
112    _SPIRV_OP(FSub, FSub)
113    _SPIRV_OP(Mul, IMul)
114    _SPIRV_OP(FMul, FMul)
115    _SPIRV_OP(UDiv, UDiv)
116    _SPIRV_OP(SDiv, SDiv)
117    _SPIRV_OP(FDiv, FDiv)
118    _SPIRV_OP(SRem, SRem)
119    _SPIRV_OP(FRem, FRem)
120    _SPIRV_OP(URem, UMod)
121    _SPIRV_OP(Shl, ShiftLeftLogical)
122    _SPIRV_OP(LShr, ShiftRightLogical)
123    _SPIRV_OP(AShr, ShiftRightArithmetic)
124#undef _SPIRV_OP
125}
126typedef SPIRVMap<unsigned, Op> OpCodeMap;
127
128template<> inline void
129SPIRVMap<CmpInst::Predicate, Op>::init() {
130#define _SPIRV_OP(x,y) add(CmpInst::x, Op##y);
131    _SPIRV_OP(FCMP_OEQ, FOrdEqual)
132    _SPIRV_OP(FCMP_OGT, FOrdGreaterThan)
133    _SPIRV_OP(FCMP_OGE, FOrdGreaterThanEqual)
134    _SPIRV_OP(FCMP_OLT, FOrdLessThan)
135    _SPIRV_OP(FCMP_OLE, FOrdLessThanEqual)
136    _SPIRV_OP(FCMP_ONE, FOrdNotEqual)
137    _SPIRV_OP(FCMP_ORD, Ordered)
138    _SPIRV_OP(FCMP_UNO, Unordered)
139    _SPIRV_OP(FCMP_UEQ, FUnordEqual)
140    _SPIRV_OP(FCMP_UGT, FUnordGreaterThan)
141    _SPIRV_OP(FCMP_UGE, FUnordGreaterThanEqual)
142    _SPIRV_OP(FCMP_ULT, FUnordLessThan)
143    _SPIRV_OP(FCMP_ULE, FUnordLessThanEqual)
144    _SPIRV_OP(FCMP_UNE, FUnordNotEqual)
145    _SPIRV_OP(ICMP_EQ, IEqual)
146    _SPIRV_OP(ICMP_NE, INotEqual)
147    _SPIRV_OP(ICMP_UGT, UGreaterThan)
148    _SPIRV_OP(ICMP_UGE, UGreaterThanEqual)
149    _SPIRV_OP(ICMP_ULT, ULessThan)
150    _SPIRV_OP(ICMP_ULE, ULessThanEqual)
151    _SPIRV_OP(ICMP_SGT, SGreaterThan)
152    _SPIRV_OP(ICMP_SGE, SGreaterThanEqual)
153    _SPIRV_OP(ICMP_SLT, SLessThan)
154    _SPIRV_OP(ICMP_SLE, SLessThanEqual)
155#undef _SPIRV_OP
156}
157typedef SPIRVMap<CmpInst::Predicate, Op> CmpMap;
158
159class IntBoolOpMapId;
160template<> inline void
161SPIRVMap<Op, Op, IntBoolOpMapId>::init() {
162  add(OpNot,         OpLogicalNot);
163  add(OpBitwiseAnd,  OpLogicalAnd);
164  add(OpBitwiseOr,   OpLogicalOr);
165  add(OpBitwiseXor,  OpLogicalNotEqual);
166  add(OpIEqual,      OpLogicalEqual);
167  add(OpINotEqual,   OpLogicalNotEqual);
168}
169typedef SPIRVMap<Op, Op, IntBoolOpMapId> IntBoolOpMap;
170
171#define SPIR_TARGETTRIPLE32 "spir-unknown-unknown"
172#define SPIR_TARGETTRIPLE64 "spir64-unknown-unknown"
173#define SPIR_DATALAYOUT32 "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32"\
174                          "-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32"\
175                          "-v32:32:32-v48:64:64-v64:64:64-v96:128:128"\
176                          "-v128:128:128-v192:256:256-v256:256:256"\
177                          "-v512:512:512-v1024:1024:1024"
178#define SPIR_DATALAYOUT64 "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32"\
179                          "-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32"\
180                          "-v32:32:32-v48:64:64-v64:64:64-v96:128:128"\
181                          "-v128:128:128-v192:256:256-v256:256:256"\
182                          "-v512:512:512-v1024:1024:1024"
183
184enum SPIRAddressSpace {
185  SPIRAS_Private,
186  SPIRAS_Global,
187  SPIRAS_Constant,
188  SPIRAS_Local,
189  SPIRAS_Generic,
190  SPIRAS_Count,
191};
192
193template<>inline void
194SPIRVMap<SPIRAddressSpace, std::string>::init() {
195  add(SPIRAS_Private, "Private");
196  add(SPIRAS_Global, "Global");
197  add(SPIRAS_Constant, "Constant");
198  add(SPIRAS_Local, "Local");
199  add(SPIRAS_Generic, "Generic");
200}
201typedef SPIRVMap<SPIRAddressSpace, SPIRVStorageClassKind>
202  SPIRAddrSpaceCapitalizedNameMap;
203
204template<> inline void
205SPIRVMap<SPIRAddressSpace, SPIRVStorageClassKind>::init() {
206  add(SPIRAS_Private, StorageClassFunction);
207  add(SPIRAS_Global, StorageClassCrossWorkgroup);
208  add(SPIRAS_Constant, StorageClassUniformConstant);
209  add(SPIRAS_Local, StorageClassWorkgroup);
210  add(SPIRAS_Generic, StorageClassGeneric);
211}
212typedef SPIRVMap<SPIRAddressSpace, SPIRVStorageClassKind> SPIRSPIRVAddrSpaceMap;
213
214// Maps OCL builtin function to SPIRV builtin variable.
215template<> inline void
216SPIRVMap<std::string, SPIRVAccessQualifierKind>::init() {
217  add("read_only", AccessQualifierReadOnly);
218  add("write_only", AccessQualifierWriteOnly);
219  add("read_write", AccessQualifierReadWrite);
220}
221typedef SPIRVMap<std::string, SPIRVAccessQualifierKind> SPIRSPIRVAccessQualifierMap;
222
223template<> inline void
224SPIRVMap<Attribute::AttrKind, SPIRVFuncParamAttrKind>::init() {
225  add(Attribute::ZExt, FunctionParameterAttributeZext);
226  add(Attribute::SExt, FunctionParameterAttributeSext);
227  add(Attribute::ByVal, FunctionParameterAttributeByVal);
228  add(Attribute::StructRet, FunctionParameterAttributeSret);
229  add(Attribute::NoAlias, FunctionParameterAttributeNoAlias);
230  add(Attribute::NoCapture, FunctionParameterAttributeNoCapture);
231}
232typedef SPIRVMap<Attribute::AttrKind, SPIRVFuncParamAttrKind>
233  SPIRSPIRVFuncParamAttrMap;
234
235template<> inline void
236SPIRVMap<Attribute::AttrKind, SPIRVFunctionControlMaskKind>::init() {
237  add(Attribute::ReadNone, FunctionControlPureMask);
238  add(Attribute::ReadOnly, FunctionControlConstMask);
239  add(Attribute::AlwaysInline, FunctionControlInlineMask);
240  add(Attribute::NoInline, FunctionControlDontInlineMask);
241}
242typedef SPIRVMap<Attribute::AttrKind, SPIRVFunctionControlMaskKind>
243  SPIRSPIRVFuncCtlMaskMap;
244
245class SPIRVExtSetShortName;
246template<> inline void
247SPIRVMap<SPIRVExtInstSetKind, std::string, SPIRVExtSetShortName>::init() {
248  add(SPIRVEIS_OpenCL, "ocl");
249}
250typedef SPIRVMap<SPIRVExtInstSetKind, std::string, SPIRVExtSetShortName>
251  SPIRVExtSetShortNameMap;
252
253#define SPIR_MD_KERNELS                     "opencl.kernels"
254#define SPIR_MD_COMPILER_OPTIONS            "opencl.compiler.options"
255#define SPIR_MD_KERNEL_ARG_ADDR_SPACE       "kernel_arg_addr_space"
256#define SPIR_MD_KERNEL_ARG_ACCESS_QUAL      "kernel_arg_access_qual"
257#define SPIR_MD_KERNEL_ARG_TYPE             "kernel_arg_type"
258#define SPIR_MD_KERNEL_ARG_BASE_TYPE        "kernel_arg_base_type"
259#define SPIR_MD_KERNEL_ARG_TYPE_QUAL        "kernel_arg_type_qual"
260#define SPIR_MD_KERNEL_ARG_NAME             "kernel_arg_name"
261
262#define OCL_TYPE_NAME_SAMPLER_T             "sampler_t"
263#define SPIR_TYPE_NAME_EVENT_T              "opencl.event_t"
264#define SPIR_TYPE_NAME_CLK_EVENT_T          "opencl.clk_event_t"
265#define SPIR_TYPE_NAME_BLOCK_T              "opencl.block"
266#define SPIR_INTRINSIC_BLOCK_BIND           "spir_block_bind"
267#define SPIR_INTRINSIC_GET_BLOCK_INVOKE     "spir_get_block_invoke"
268#define SPIR_INTRINSIC_GET_BLOCK_CONTEXT    "spir_get_block_context"
269#define SPIR_TEMP_NAME_PREFIX_BLOCK         "block"
270#define SPIR_TEMP_NAME_PREFIX_CALL          "call"
271
272namespace kLLVMTypeName {
273  const static char StructPrefix[] = "struct.";
274}
275
276namespace kSPIRVImageSampledTypeName {
277  const static char Float[] = "float";
278  const static char Half[]  = "half";
279  const static char Int[]   = "int";
280  const static char UInt[]  = "uint";
281  const static char Void[]  = "void";
282}
283
284namespace kSPIRVTypeName {
285  const static char Delimiter             = '.';
286  const static char DeviceEvent[]         = "DeviceEvent";
287  const static char Event[]               = "Event";
288  const static char Image[]               = "Image";
289  const static char Pipe[]                = "Pipe";
290  const static char PostfixDelim          = '_';
291  const static char Prefix[]              = "spirv";
292  const static char PrefixAndDelim[]      = "spirv.";
293  const static char Queue[]               = "Queue";
294  const static char ReserveId[]           = "ReserveId";
295  const static char SampledImg[]          = "SampledImage";
296  const static char Sampler[]             = "Sampler";
297  const static char ConstantSampler[]     = "ConstantSampler";
298  const static char PipeStorage[]         = "PipeStorage";
299  const static char ConstantPipeStorage[] = "ConstantPipeStorage";
300}
301
302namespace kSPR2TypeName {
303  const static char Delimiter   = '.';
304  const static char OCLPrefix[]   = "opencl.";
305  const static char ImagePrefix[] = "opencl.image";
306  const static char Pipe[]        = "opencl.pipe_t";
307  const static char Sampler[]     = "opencl.sampler_t";
308  const static char Event[]       = "opencl.event_t";
309}
310
311namespace kAccessQualName {
312  const static char ReadOnly[]    = "read_only";
313  const static char WriteOnly[]   = "write_only";
314  const static char ReadWrite[]   = "read_write";
315}
316
317namespace kMangledName {
318  const static char Sampler[]               = "11ocl_sampler";
319  const static char AtomicPrefixIncoming[]  = "U7_Atomic";
320  const static char AtomicPrefixInternal[]  = "atomic_";
321}
322
323namespace kSPIRVName {
324  const static char GroupPrefix[]            = "group_";
325  const static char Prefix[]                 = "__spirv_";
326  const static char Postfix[]                = "__";
327  const static char ImageQuerySize[]         = "ImageQuerySize";
328  const static char ImageQuerySizeLod[]      = "ImageQuerySizeLod";
329  const static char ImageSampleExplicitLod[] = "ImageSampleExplicitLod";
330  const static char ReservedPrefix[]         = "reserved_";
331  const static char SampledImage[]           = "SampledImage";
332  const static char TempSampledImage[]       = "TempSampledImage";
333}
334
335namespace kSPIRVPostfix {
336  const static char Sat[]       = "sat";
337  const static char Rtz[]       = "rtz";
338  const static char Rte[]       = "rte";
339  const static char Rtp[]       = "rtp";
340  const static char Rtn[]       = "rtn";
341  const static char Rt[]        = "rt";
342  const static char Return[]    = "R";
343  const static char Divider[]   = "_";
344  /// Divider between extended instruction name and postfix
345  const static char ExtDivider[] = "__";
346}
347
348namespace kSPIRVMD {
349  const static char Capability[]        = "spirv.Capability";
350  const static char EntryPoint[]        = "spirv.EntryPoint";
351  const static char ExecutionMode[]     = "spirv.ExecutionMode";
352  const static char Extension[]         = "spirv.Extension";
353  const static char Generator[]         = "spirv.Generator";
354  const static char Source[]            = "spirv.Source";
355  const static char SourceExtension[]   = "spirv.SourceExtension";
356  const static char MemoryModel[]       = "spirv.MemoryModel";
357}
358
359namespace kSPIR2MD {
360  const static char Extensions[]        = "opencl.used.extensions";
361  const static char FPContract[]        = "opencl.enable.FP_CONTRACT";
362  const static char OCLVer[]            = "opencl.ocl.version";
363  const static char OptFeatures[]       = "opencl.used.optional.core.features";
364  const static char SPIRVer[]           = "opencl.spir.version";
365  const static char VecTyHint[]         = "vec_type_hint";
366  const static char WGSize[]            = "reqd_work_group_size";
367  const static char WGSizeHint[]        = "work_group_size_hint";
368}
369
370enum Spir2SamplerKind {
371  CLK_ADDRESS_NONE            = 0x0000,
372  CLK_ADDRESS_CLAMP           = 0x0004,
373  CLK_ADDRESS_CLAMP_TO_EDGE   = 0x0002,
374  CLK_ADDRESS_REPEAT          = 0x0006,
375  CLK_ADDRESS_MIRRORED_REPEAT = 0x0008,
376  CLK_NORMALIZED_COORDS_FALSE = 0x0000,
377  CLK_NORMALIZED_COORDS_TRUE  = 0x0001,
378  CLK_FILTER_NEAREST          = 0x0010,
379  CLK_FILTER_LINEAR           = 0x0020,
380};
381
382
383/// Additional information for mangling a function argument type.
384struct BuiltinArgTypeMangleInfo {
385  bool IsSigned;
386  bool IsVoidPtr;
387  bool IsEnum;
388  bool IsSampler;
389  bool IsAtomic;
390  bool IsLocalArgBlock;
391  SPIR::TypePrimitiveEnum Enum;
392  unsigned Attr;
393  BuiltinArgTypeMangleInfo():IsSigned(true), IsVoidPtr(false), IsEnum(false),
394                             IsSampler(false), IsAtomic(false), IsLocalArgBlock(false),
395                             Enum(SPIR::PRIMITIVE_NONE), Attr(0)
396  {}
397};
398
399/// Information for mangling builtin function.
400class BuiltinFuncMangleInfo {
401public:
402  /// Translate builtin function name and set
403  /// argument attributes and unsigned args.
404  BuiltinFuncMangleInfo(const std::string &UniqName = "") : LocalArgBlockIdx(-1),
405                                                            VarArgIdx(-1) {
406    if (!UniqName.empty())
407      init(UniqName);
408  }
409  virtual ~BuiltinFuncMangleInfo(){}
410  const std::string &getUnmangledName() const { return UnmangledName;}
411  void addUnsignedArg(int Ndx) { UnsignedArgs.insert(Ndx);}
412  void addVoidPtrArg(int Ndx) { VoidPtrArgs.insert(Ndx);}
413  void addSamplerArg(int Ndx) { SamplerArgs.insert(Ndx);}
414  void addAtomicArg(int Ndx) { AtomicArgs.insert(Ndx);}
415  void setLocalArgBlock(int Ndx) {
416    assert(0 <= Ndx && "it is not allowed to set less than zero index");
417    LocalArgBlockIdx = Ndx;
418  }
419  void setEnumArg(int Ndx, SPIR::TypePrimitiveEnum Enum) {
420    EnumArgs[Ndx] = Enum;}
421  void setArgAttr(int Ndx, unsigned Attr) {
422    Attrs[Ndx] = Attr;}
423  void setVarArg(int Ndx) {
424    assert(0 <= Ndx && "it is not allowed to set less than zero index");
425    VarArgIdx = Ndx;
426  }
427  bool isArgUnsigned(int Ndx) {
428    return UnsignedArgs.count(-1) || UnsignedArgs.count(Ndx);}
429  bool isArgVoidPtr(int Ndx) {
430    return VoidPtrArgs.count(-1) || VoidPtrArgs.count(Ndx);}
431  bool isArgSampler(int Ndx) {
432    return SamplerArgs.count(Ndx);}
433  bool isArgAtomic(int Ndx) {
434    return AtomicArgs.count(Ndx);}
435  bool isLocalArgBlock(int Ndx) {
436    return LocalArgBlockIdx == Ndx;}
437  bool isArgEnum(int Ndx, SPIR::TypePrimitiveEnum *Enum = nullptr) {
438    auto Loc = EnumArgs.find(Ndx);
439    if (Loc == EnumArgs.end())
440      Loc = EnumArgs.find(-1);
441    if (Loc == EnumArgs.end())
442      return false;
443    if (Enum)
444      *Enum = Loc->second;
445    return true;
446  }
447  unsigned getArgAttr(int Ndx) {
448    auto Loc = Attrs.find(Ndx);
449    if (Loc == Attrs.end())
450      Loc = Attrs.find(-1);
451    if (Loc == Attrs.end())
452      return 0;
453    return Loc->second;
454  }
455  // get ellipsis index, single ellipsis at the end of the function is possible only
456  // return value < 0 if none
457  int getVarArg() const {
458    return VarArgIdx;
459  }
460  BuiltinArgTypeMangleInfo getTypeMangleInfo(int Ndx) {
461    BuiltinArgTypeMangleInfo Info;
462    Info.IsSigned = !isArgUnsigned(Ndx);
463    Info.IsVoidPtr = isArgVoidPtr(Ndx);
464    Info.IsEnum = isArgEnum(Ndx, &Info.Enum);
465    Info.IsSampler = isArgSampler(Ndx);
466    Info.IsAtomic = isArgAtomic(Ndx);
467    Info.IsLocalArgBlock = isLocalArgBlock(Ndx);
468    Info.Attr = getArgAttr(Ndx);
469    return Info;
470  }
471  virtual void init(const std::string &UniqUnmangledName){
472    UnmangledName = UniqUnmangledName;
473  }
474protected:
475  std::string UnmangledName;
476  std::set<int> UnsignedArgs; // unsigned arguments, or -1 if all are unsigned
477  std::set<int> VoidPtrArgs;  // void pointer arguments, or -1 if all are void
478                              // pointer
479  std::set<int> SamplerArgs;  // sampler arguments
480  std::set<int> AtomicArgs;   // atomic arguments
481  std::map<int, SPIR::TypePrimitiveEnum> EnumArgs; // enum arguments
482  std::map<int, unsigned> Attrs;                   // argument attributes
483  int LocalArgBlockIdx; // index of a block with local arguments, idx < 0 if none
484  int VarArgIdx;        // index of ellipsis argument, idx < 0 if none
485};
486
487/// \returns a vector of types for a collection of values.
488template<class T>
489std::vector<Type *>
490getTypes(T V) {
491  std::vector<Type *> Tys;
492  for (auto &I:V)
493    Tys.push_back(I->getType());
494  return Tys;
495}
496
497/// Move elements of std::vector from [begin, end) to target.
498template <typename T>
499void move(std::vector<T>& V, size_t begin, size_t end, size_t target) {
500  assert(begin < end && end <= V.size() && target <= V.size() &&
501      !(begin < target && target < end));
502  if (begin <= target && target <= end)
503    return;
504  auto B = V.begin() + begin, E = V.begin() + end;
505  if (target > V.size())
506    target = V.size();
507  if (target > end)
508    target -= (end - begin);
509  std::vector<T> Segment(B, E);
510  V.erase(B, E);
511  V.insert(V.begin() + target, Segment.begin(), Segment.end());
512}
513
514/// Find position of first pointer type value in a vector.
515inline size_t findFirstPtr(const std::vector<Value *> &Args) {
516  auto PtArg = std::find_if(Args.begin(), Args.end(), [](Value *V){
517    return V->getType()->isPointerTy();
518  });
519  return PtArg - Args.begin();
520}
521
522void removeFnAttr(LLVMContext *Context, CallInst *Call,
523    Attribute::AttrKind Attr);
524void addFnAttr(LLVMContext *Context, CallInst *Call,
525    Attribute::AttrKind Attr);
526void saveLLVMModule(Module *M, const std::string &OutputFile);
527std::string mapSPIRVTypeToOCLType(SPIRVType* Ty, bool Signed);
528std::string mapLLVMTypeToOCLType(const Type* Ty, bool Signed);
529SPIRVDecorate *mapPostfixToDecorate(StringRef Postfix, SPIRVEntry *Target);
530
531/// Add decorations to a SPIR-V entry.
532/// \param Decs Each string is a postfix without _ at the beginning.
533SPIRVValue *addDecorations(SPIRVValue *Target,
534    const SmallVectorImpl<std::string>& Decs);
535
536PointerType *getOrCreateOpaquePtrType(Module *M, const std::string &Name,
537    unsigned AddrSpace = SPIRAS_Global);
538PointerType* getSamplerType(Module *M);
539PointerType* getPipeStorageType(Module *M);
540void getFunctionTypeParameterTypes(llvm::FunctionType* FT,
541    std::vector<Type*>& ArgTys);
542Function *getOrCreateFunction(Module *M, Type *RetTy,
543    ArrayRef<Type *> ArgTypes, StringRef Name,
544    BuiltinFuncMangleInfo *Mangle = nullptr,
545    AttributeSet *Attrs = nullptr, bool takeName = true);
546
547/// Get function call arguments.
548/// \param Start Starting index.
549/// \param End Ending index.
550std::vector<Value *> getArguments(CallInst* CI, unsigned Start = 0,
551    unsigned End = 0);
552
553/// Get constant function call argument as an integer.
554/// \param I argument index.
555uint64_t getArgAsInt(CallInst *CI, unsigned I);
556
557/// Get constant function call argument as type \param T.
558/// \param I argument index.
559template<typename T>
560T getArgAs(CallInst *CI, unsigned I){
561  return static_cast<T>(getArgAsInt(CI, I));
562}
563
564/// Get constant function call argument as a Scope enum.
565/// \param I argument index.
566Scope getArgAsScope(CallInst *CI, unsigned I);
567
568/// Get constant function call argument as a Decoration enum.
569/// \param I argument index.
570Decoration getArgAsDecoration(CallInst *CI, unsigned I);
571
572bool isPointerToOpaqueStructType(llvm::Type* Ty);
573bool isPointerToOpaqueStructType(llvm::Type* Ty, const std::string &Name);
574
575/// Check if a type is OCL image type.
576/// \return type name without "opencl." prefix.
577bool isOCLImageType(llvm::Type* Ty, StringRef *Name = nullptr);
578
579/// \param BaseTyName is the type name as in spirv.BaseTyName.Postfixes
580/// \param Postfix contains postfixes extracted from the SPIR-V image
581///   type name as spirv.BaseTyName.Postfixes.
582bool
583isSPIRVType(llvm::Type* Ty, StringRef BaseTyName, StringRef *Postfix = 0);
584
585/// Decorate a function name as __spirv_{Name}_
586std::string decorateSPIRVFunction(const std::string &S);
587
588/// Remove prefix/postfix from __spirv_{Name}_
589std::string undecorateSPIRVFunction(const std::string &S);
590
591/// Check if a function has decorated name as __spirv_{Name}_
592/// and get the original name.
593bool isDecoratedSPIRVFunc(const Function *F, std::string *UndecName = nullptr);
594
595/// Get a canonical function name for a SPIR-V op code.
596std::string getSPIRVFuncName(Op OC, StringRef PostFix = "");
597
598std::string getSPIRVFuncName(Op OC, const Type *pRetTy, bool IsSigned = false);
599
600/// Get a canonical function name for a SPIR-V extended instruction
601std::string getSPIRVExtFuncName(SPIRVExtInstSetKind Set, unsigned ExtOp,
602    StringRef PostFix = "");
603
604/// Get SPIR-V op code given the canonical function name.
605/// Assume \param Name is either IA64 mangled or unmangled, and the unmangled
606/// name takes the __spirv_{OpName}_{Postfixes} format.
607/// \return op code if the unmangled function name is a valid op code name,
608///   otherwise return OpNop.
609/// \param Dec contains decorations decoded from function name if it is
610///   not nullptr.
611Op getSPIRVFuncOC(const std::string& Name,
612    SmallVectorImpl<std::string> *Dec = nullptr);
613
614/// Get SPIR-V builtin variable enum given the canonical builtin name
615/// Assume \param Name is in format __spirv_BuiltIn{Name}
616/// \return false if \param Name is not a valid builtin name.
617bool getSPIRVBuiltin(const std::string &Name, spv::BuiltIn &Builtin);
618
619/// \param Name LLVM function name
620/// \param DemangledName demanged name of the OpenCL built-in function
621/// \returns true if Name is the name of the OpenCL built-in function,
622/// false for other functions
623bool oclIsBuiltin(const StringRef &Name, std::string *DemangledName = nullptr,
624                  bool isCPP = false);
625
626/// Check if a function type is void(void).
627bool isVoidFuncTy(FunctionType *FT);
628
629/// \returns true if \p T is a function pointer type.
630bool isFunctionPointerType(Type *T);
631
632/// \returns true if function \p F has function pointer type argument.
633/// \param AI points to the function pointer type argument if returns true.
634bool hasFunctionPointerArg(Function *F, Function::arg_iterator& AI);
635
636/// \returns true if function \p F has array type argument.
637bool hasArrayArg(Function *F);
638
639/// Mutates function call instruction by changing the arguments.
640/// \param ArgMutate mutates the function arguments.
641/// \return mutated call instruction.
642CallInst *mutateCallInst(Module *M, CallInst *CI,
643    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
644    BuiltinFuncMangleInfo *Mangle = nullptr, AttributeSet *Attrs = nullptr,
645    bool takeName = false);
646
647/// Mutates function call instruction by changing the arguments and return
648/// value.
649/// \param ArgMutate mutates the function arguments.
650/// \param RetMutate mutates the return value.
651/// \return mutated instruction.
652Instruction *mutateCallInst(Module *M, CallInst *CI,
653    std::function<std::string (CallInst *, std::vector<Value *> &,
654        Type *&RetTy)> ArgMutate,
655    std::function<Instruction *(CallInst *)> RetMutate,
656    BuiltinFuncMangleInfo *Mangle = nullptr, AttributeSet *Attrs = nullptr,
657    bool takeName = false);
658
659/// Mutate call instruction to call SPIR-V builtin function.
660CallInst *
661mutateCallInstSPIRV(Module *M, CallInst *CI,
662    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
663    AttributeSet *Attrs = nullptr);
664
665/// Mutate call instruction to call SPIR-V builtin function.
666Instruction *
667mutateCallInstSPIRV(Module *M, CallInst *CI,
668    std::function<std::string (CallInst *, std::vector<Value *> &,
669        Type *&RetTy)> ArgMutate,
670    std::function<Instruction *(CallInst *)> RetMutate,
671    AttributeSet *Attrs = nullptr);
672
673/// Mutate function by change the arguments.
674/// \param ArgMutate mutates the function arguments.
675/// \param TakeName Take the original function's name if a new function with
676///   different type needs to be created.
677void mutateFunction(Function *F,
678    std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
679    BuiltinFuncMangleInfo *Mangle = nullptr, AttributeSet *Attrs = nullptr,
680    bool TakeName = true);
681
682/// Add a call instruction at \p Pos.
683CallInst *addCallInst(Module *M, StringRef FuncName, Type *RetTy,
684    ArrayRef<Value *> Args, AttributeSet *Attrs, Instruction *Pos,
685    BuiltinFuncMangleInfo *Mangle = nullptr,
686    StringRef InstName = SPIR_TEMP_NAME_PREFIX_CALL,
687    bool TakeFuncName = true);
688
689/// Add a call instruction for SPIR-V builtin function.
690CallInst *
691addCallInstSPIRV(Module *M, StringRef FuncName, Type *RetTy,
692    ArrayRef<Value *> Args,
693    AttributeSet *Attrs, Instruction *Pos, StringRef InstName);
694
695/// Add a call of spir_block_bind function.
696CallInst *
697addBlockBind(Module *M, Function *InvokeFunc, Value *BlkCtx, Value *CtxLen,
698    Value *CtxAlign, Instruction *InsPos,
699    StringRef InstName = SPIR_TEMP_NAME_PREFIX_BLOCK);
700
701typedef std::pair<std::vector<Value *>::iterator,
702    std::vector<Value *>::iterator> ValueVecRange;
703
704/// Add a vector at \param InsPos.
705Value *
706addVector(Instruction *InsPos, ValueVecRange Range);
707
708/// Replace scalar values with a vector created at \param InsPos.
709void
710makeVector(Instruction *InsPos, std::vector<Value *> &Ops,
711    ValueVecRange Range);
712
713/// Expand a vector type value in \param Ops at index \param VecPos.
714/// Generate extract element instructions at \param InsPos and replace
715/// the vector type value with scalar type values.
716/// If the value to be expanded is not vector type, do nothing.
717void
718expandVector(Instruction *InsPos, std::vector<Value *> &Ops, size_t VecPos);
719
720/// Get size_t type.
721IntegerType *getSizetType(Module *M);
722
723/// Get void(void) function type.
724Type *getVoidFuncType(Module *M);
725
726/// Get void(void) function pointer type.
727Type *getVoidFuncPtrType(Module *M, unsigned AddrSpace = 0);
728
729/// Get a 64 bit integer constant.
730ConstantInt *getInt64(Module *M, int64_t value);
731
732/// Get a 32 bit integer constant.
733ConstantInt *getInt32(Module *M, int value);
734
735/// Get a 32 bit unsigned integer constant.
736ConstantInt *getUInt32(Module *M, unsigned value);
737
738/// Get a 16 bit unsigned integer constant.
739ConstantInt *getUInt16(Module *M, unsigned short value);
740
741// Get a 32 bit floating point constant.
742Constant *getFloat32(Module *M, float value);
743
744/// Get a 32 bit integer constant vector.
745std::vector<Value *> getInt32(Module *M, const std::vector<int> &value);
746
747/// Get a size_t type constant.
748ConstantInt *getSizet(Module *M, uint64_t value);
749
750/// Get metadata operand as int.
751int getMDOperandAsInt(MDNode* N, unsigned I);
752
753/// Get metadata operand as string.
754std::string getMDOperandAsString(MDNode* N, unsigned I);
755
756/// Get metadata operand as type.
757Type* getMDOperandAsType(MDNode* N, unsigned I);
758
759/// Get a named metadata as a set of string.
760/// Assume the named metadata has one or more operands each of which might
761/// contain set of strings. For instance:
762/// !opencl.used.optional.core.features = !{!0}
763/// !0 = !{!"cl_doubles", !"cl_images"}
764/// or if we linked two modules we may have
765/// !opencl.used.optional.core.features = !{!0, !1}
766/// !0 = !{!"cl_doubles"}
767/// !1 = !{!"cl_images"}
768std::set<std::string> getNamedMDAsStringSet(Module *M,
769                                            const std::string &MDName);
770
771/// Get SPIR-V language by SPIR-V metadata spirv.Source
772std::tuple<unsigned, unsigned, std::string>
773getSPIRVSource(Module *M);
774
775/// Map an unsigned integer constant by applying a function.
776ConstantInt *mapUInt(Module *M, ConstantInt *I,
777    std::function<unsigned(unsigned)> F);
778
779/// Map a signed integer constant by applying a function.
780ConstantInt *mapSInt(Module *M, ConstantInt *I,
781    std::function<int(int)> F);
782
783/// Get postfix for given decoration.
784/// The returned postfix does not include "_" at the beginning.
785std::string getPostfix(Decoration Dec, unsigned Value = 0);
786
787/// Get postfix _R{ReturnType} for return type
788/// The returned postfix does not includ "_" at the beginning
789std::string getPostfixForReturnType(CallInst *CI, bool IsSigned = false);
790std::string getPostfixForReturnType(const Type *pRetTy, bool IsSigned = false);
791
792Constant *
793getScalarOrVectorConstantInt(Type *T, uint64_t V, bool isSigned = false);
794
795/// Get a constant int or a constant int array.
796/// \param T is the type of the constant. It should be an integer type or
797//  an integer pointer type.
798/// \param Len is the length of the array.
799/// \param V is the value to fill the array.
800Value *
801getScalarOrArrayConstantInt(Instruction *P, Type *T, unsigned Len, uint64_t V,
802    bool isSigned = false);
803
804/// Get the array from GEP.
805/// \param V is a GEP whose pointer operand is a pointer to an array of size
806/// \param Size.
807Value *
808getScalarOrArray(Value *V, unsigned Size, Instruction *Pos);
809
810void
811dumpUsers(Value* V, StringRef Prompt = "");
812
813/// Get SPIR-V type name as spirv.BaseTyName.Postfixes.
814std::string
815getSPIRVTypeName(StringRef BaseTyName, StringRef Postfixes = "");
816
817/// Checks if given type name is either ConstantSampler or ConsantPipeStorage.
818bool
819isSPIRVConstantName(StringRef TyName);
820
821/// Get SPIR-V type by changing the type name from spirv.OldName.Postfixes
822/// to spirv.NewName.Postfixes.
823Type *
824getSPIRVTypeByChangeBaseTypeName(Module *M, Type *T, StringRef OldName,
825    StringRef NewName);
826
827/// Get the postfixes of SPIR-V image type name as in spirv.Image.postfixes.
828std::string
829getSPIRVImageTypePostfixes(StringRef SampledType,
830    SPIRVTypeImageDescriptor Desc,
831    SPIRVAccessQualifierKind Acc);
832
833/// Get the sampled type name used in postfix of image type in SPIR-V
834/// friendly LLVM IR.
835std::string
836getSPIRVImageSampledTypeName(SPIRVType *Ty);
837
838/// Translates OpenCL image type names to SPIR-V.
839/// E.g. %opencl.image1d_rw_t -> %spirv.Image._void_0_0_0_0_0_0_2
840Type *getSPIRVImageTypeFromOCL(Module *M, Type *T);
841
842/// Get LLVM type for sampled type of SPIR-V image type by postfix.
843Type*
844getLLVMTypeForSPIRVImageSampledTypePostfix(StringRef Postfix,
845  LLVMContext &Ctx);
846
847/// Map OpenCL opaque type name to SPIR-V type name.
848std::string
849mapOCLTypeNameToSPIRV(StringRef Name, StringRef Acc = "");
850
851/// Check if access qualifier is encoded in the type name.
852bool hasAccessQualifiedName(StringRef TyName);
853
854/// Get access qualifier from the type name.
855StringRef getAccessQualifier(StringRef TyName);
856
857bool
858eraseUselessFunctions(Module *M);
859
860/// Erase a function if it is declaration, has internal linkage and has no use.
861bool
862eraseIfNoUse(Function *F);
863
864void
865eraseIfNoUse(Value *V);
866
867// Check if a mangled type name is unsigned
868bool
869isMangledTypeUnsigned(char Mangled);
870
871// Check if a mangled type name is signed
872bool
873isMangledTypeSigned(char Mangled);
874
875// Check if a mangled type name is floating point (except half)
876bool
877isMangledTypeFP(char Mangled);
878
879// Check if a mangled type name is half
880bool
881isMangledTypeHalf(std::string Mangled);
882
883// Check if \param I is valid vector size: 2, 3, 4, 8, 16.
884bool
885isValidVectorSize(unsigned I);
886
887enum class ParamType
888{
889    FLOAT    = 0,
890    SIGNED   = 1,
891    UNSIGNED = 2,
892    UNKNOWN  = 3
893};
894
895ParamType LastFuncParamType(const std::string& MangledName);
896
897// Check if the last function parameter is signed
898bool
899isLastFuncParamSigned(const std::string& MangledName);
900
901// Check if a mangled function name contains unsigned atomic type
902bool
903containsUnsignedAtomicType(StringRef Name);
904
905/// Mangle builtin function name.
906/// \return \param UniqName if \param BtnInfo is null pointer, otherwise
907///    return IA64 mangled name.
908std::string
909mangleBuiltin(const std::string &UniqName,
910    ArrayRef<Type*> ArgTypes, BuiltinFuncMangleInfo* BtnInfo);
911
912/// Remove cast from a value.
913Value *
914removeCast(Value *V);
915
916/// Cast a function to a void(void) funtion pointer.
917Constant *
918castToVoidFuncPtr(Function *F);
919
920/// Get i8* with the same address space.
921PointerType *getInt8PtrTy(PointerType *T);
922
923/// Cast a value to a i8* by inserting a cast instruction.
924Value *
925castToInt8Ptr(Value *V, Instruction *Pos);
926
927template<> inline void
928SPIRVMap<std::string, Op, SPIRVOpaqueType>::init() {
929  add(kSPIRVTypeName::DeviceEvent, OpTypeDeviceEvent);
930  add(kSPIRVTypeName::Event, OpTypeEvent);
931  add(kSPIRVTypeName::Image, OpTypeImage);
932  add(kSPIRVTypeName::Pipe, OpTypePipe);
933  add(kSPIRVTypeName::Queue, OpTypeQueue);
934  add(kSPIRVTypeName::ReserveId, OpTypeReserveId);
935  add(kSPIRVTypeName::Sampler, OpTypeSampler);
936  add(kSPIRVTypeName::SampledImg, OpTypeSampledImage);
937}
938
939}
940
941#endif
942