• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- OCLUtil.h - OCL Utilities declarations -------------------*- 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 //
35 // This file declares OCL utility functions.
36 //
37 //===----------------------------------------------------------------------===//
38 #include "SPIRVInternal.h"
39 
40 #include <utility>
41 #include <tuple>
42 #include <functional>
43 using namespace SPIRV;
44 using namespace llvm;
45 using namespace spv;
46 
47 namespace OCLUtil {
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 //
51 // Enums
52 //
53 ///////////////////////////////////////////////////////////////////////////////
54 
55 enum OCLMemFenceKind {
56   OCLMF_Local = 1,
57   OCLMF_Global = 2,
58   OCLMF_Image = 4,
59 };
60 
61 enum OCLScopeKind {
62   OCLMS_work_item,
63   OCLMS_work_group,
64   OCLMS_device,
65   OCLMS_all_svm_devices,
66   OCLMS_sub_group,
67 };
68 
69 enum OCLMemOrderKind {
70   OCLMO_relaxed,
71   OCLMO_acquire,
72   OCLMO_release,
73   OCLMO_acq_rel,
74   OCLMO_seq_cst
75 };
76 
77 ///////////////////////////////////////////////////////////////////////////////
78 //
79 // Types
80 //
81 ///////////////////////////////////////////////////////////////////////////////
82 
83 typedef SPIRVMap<OCLMemFenceKind, MemorySemanticsMask>
84   OCLMemFenceMap;
85 
86 typedef SPIRVMap<OCLMemOrderKind, unsigned, MemorySemanticsMask>
87   OCLMemOrderMap;
88 
89 typedef SPIRVMap<OCLScopeKind, Scope>
90   OCLMemScopeMap;
91 
92 typedef SPIRVMap<std::string, SPIRVGroupOperationKind>
93   SPIRSPIRVGroupOperationMap;
94 
95 typedef SPIRVMap<std::string, SPIRVFPRoundingModeKind>
96   SPIRSPIRVFPRoundingModeMap;
97 
98 typedef SPIRVMap<std::string, Op, SPIRVInstruction>
99   OCLSPIRVBuiltinMap;
100 
101 typedef SPIRVMap<std::string, SPIRVBuiltinVariableKind>
102   SPIRSPIRVBuiltinVariableMap;
103 
104 /// Tuple of literals for atomic_work_item_fence (flag, order, scope)
105 typedef std::tuple<unsigned, OCLMemOrderKind, OCLScopeKind>
106   AtomicWorkItemFenceLiterals;
107 
108 /// Tuple of literals for work_group_barrier or sub_group_barrier
109 ///     (flag, mem_scope, exec_scope)
110 typedef std::tuple<unsigned, OCLScopeKind, OCLScopeKind>
111   BarrierLiterals;
112 
113 class OCLOpaqueType;
114 typedef SPIRVMap<std::string, Op, OCLOpaqueType>
115   OCLOpaqueTypeOpCodeMap;
116 
117 /// Information for translating OCL builtin.
118 struct OCLBuiltinTransInfo {
119   std::string UniqName;
120   std::string MangledName;
121   std::string Postfix;      // Postfix to be added
122   /// Postprocessor of operands
123   std::function<void(std::vector<Value *>&)> PostProc;
124   Type* RetTy;              // Return type of the translated function
125   bool isRetSigned;         // When RetTy is int, determines if extensions
126                             // on it should be a sext or zet.
OCLBuiltinTransInfoOCLBuiltinTransInfo127   OCLBuiltinTransInfo() : RetTy(nullptr), isRetSigned(false) {
128     PostProc = [](std::vector<Value *>&){};
129   }
130 };
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 //
134 // Constants
135 //
136 ///////////////////////////////////////////////////////////////////////////////
137 namespace kOCLBuiltinName {
138   const static char All[]                       = "all";
139   const static char Any[]                       = "any";
140   const static char AsyncWorkGroupCopy[]        = "async_work_group_copy";
141   const static char AsyncWorkGroupStridedCopy[] = "async_work_group_strided_copy";
142   const static char AtomPrefix[]         = "atom_";
143   const static char AtomCmpXchg[]        = "atom_cmpxchg";
144   const static char AtomicPrefix[]       = "atomic_";
145   const static char AtomicCmpXchg[]      = "atomic_cmpxchg";
146   const static char AtomicCmpXchgStrong[]         = "atomic_compare_exchange_strong";
147   const static char AtomicCmpXchgStrongExplicit[] = "atomic_compare_exchange_strong_explicit";
148   const static char AtomicCmpXchgWeak[]           = "atomic_compare_exchange_weak";
149   const static char AtomicCmpXchgWeakExplicit[]   = "atomic_compare_exchange_weak_explicit";
150   const static char AtomicInit[]          = "atomic_init";
151   const static char AtomicWorkItemFence[] = "atomic_work_item_fence";
152   const static char Barrier[]            = "barrier";
153   const static char Clamp[]              = "clamp";
154   const static char ConvertPrefix[]      = "convert_";
155   const static char Dot[]                = "dot";
156   const static char EnqueueKernel[]      = "enqueue_kernel";
157   const static char FMax[]               = "fmax";
158   const static char FMin[]               = "fmin";
159   const static char GetFence[]           = "get_fence";
160   const static char GetImageArraySize[]  = "get_image_array_size";
161   const static char GetImageChannelOrder[]    = "get_image_channel_order";
162   const static char GetImageChannelDataType[] = "get_image_channel_data_type";
163   const static char GetImageDepth[]      = "get_image_depth";
164   const static char GetImageDim[]        = "get_image_dim";
165   const static char GetImageHeight[]     = "get_image_height";
166   const static char GetImageWidth[]      = "get_image_width";
167   const static char IsFinite[]           = "isfinite";
168   const static char IsNan[]              = "isnan";
169   const static char IsNormal[]           = "isnormal";
170   const static char IsInf[]              = "isinf";
171   const static char Max[]                = "max";
172   const static char MemFence[]           = "mem_fence";
173   const static char Min[]                = "min";
174   const static char Mix[]                = "mix";
175   const static char NDRangePrefix[]      = "ndrange_";
176   const static char Pipe[]               = "pipe";
177   const static char ReadImage[]          = "read_image";
178   const static char ReadPipe[]           = "read_pipe";
179   const static char RoundingPrefix[]     = "_r";
180   const static char Sampled[]            = "sampled_";
181   const static char SampledReadImage[]   = "sampled_read_image";
182   const static char Signbit[]            = "signbit";
183   const static char SmoothStep[]         = "smoothstep";
184   const static char Step[]               = "step";
185   const static char SubGroupPrefix[]     = "sub_group_";
186   const static char SubGroupBarrier[]    = "sub_group_barrier";
187   const static char SubPrefix[]          = "sub_";
188   const static char ToGlobal[]           = "to_global";
189   const static char ToLocal[]            = "to_local";
190   const static char ToPrivate[]          = "to_private";
191   const static char VLoadPrefix[]        = "vload";
192   const static char VLoadAPrefix[]       = "vloada";
193   const static char VLoadHalf[]          = "vload_half";
194   const static char VStorePrefix[]       = "vstore";
195   const static char VStoreAPrefix[]      = "vstorea";
196   const static char WaitGroupEvent[]     = "wait_group_events";
197   const static char WriteImage[]         = "write_image";
198   const static char WorkGroupBarrier[]   = "work_group_barrier";
199   const static char WritePipe[]          = "write_pipe";
200   const static char WorkGroupPrefix[]    = "work_group_";
201   const static char WorkGroupAll[]       = "work_group_all";
202   const static char WorkGroupAny[]       = "work_group_any";
203   const static char SubGroupAll[]        = "sub_group_all";
204   const static char SubGroupAny[]        = "sub_group_any";
205   const static char WorkPrefix[]         = "work_";
206 }
207 
208 /// Offset for OpenCL image channel order enumeration values.
209 const unsigned int OCLImageChannelOrderOffset = 0x10B0;
210 
211 /// Offset for OpenCL image channel data type enumeration values.
212 const unsigned int OCLImageChannelDataTypeOffset = 0x10D0;
213 
214 /// OCL 1.x atomic memory order when translated to 2.0 atomics.
215 const OCLMemOrderKind OCLLegacyAtomicMemOrder = OCLMO_seq_cst;
216 
217 /// OCL 1.x atomic memory scope when translated to 2.0 atomics.
218 const OCLScopeKind OCLLegacyAtomicMemScope = OCLMS_device;
219 
220 namespace kOCLVer {
221   const unsigned CL12 = 102000;
222   const unsigned CL20 = 200000;
223   const unsigned CL21 = 201000;
224 }
225 
226 namespace OclExt {
227 enum Kind {
228 #define _SPIRV_OP(x) x,
229   _SPIRV_OP(cl_images)
230   _SPIRV_OP(cl_doubles)
231   _SPIRV_OP(cl_khr_int64_base_atomics)
232   _SPIRV_OP(cl_khr_int64_extended_atomics)
233   _SPIRV_OP(cl_khr_fp16)
234   _SPIRV_OP(cl_khr_gl_sharing)
235   _SPIRV_OP(cl_khr_gl_event)
236   _SPIRV_OP(cl_khr_d3d10_sharing)
237   _SPIRV_OP(cl_khr_media_sharing)
238   _SPIRV_OP(cl_khr_d3d11_sharing)
239   _SPIRV_OP(cl_khr_global_int32_base_atomics)
240   _SPIRV_OP(cl_khr_global_int32_extended_atomics)
241   _SPIRV_OP(cl_khr_local_int32_base_atomics)
242   _SPIRV_OP(cl_khr_local_int32_extended_atomics)
243   _SPIRV_OP(cl_khr_byte_addressable_store)
244   _SPIRV_OP(cl_khr_3d_image_writes)
245   _SPIRV_OP(cl_khr_gl_msaa_sharing)
246   _SPIRV_OP(cl_khr_depth_images)
247   _SPIRV_OP(cl_khr_gl_depth_images)
248   _SPIRV_OP(cl_khr_subgroups)
249   _SPIRV_OP(cl_khr_mipmap_image)
250   _SPIRV_OP(cl_khr_mipmap_image_writes)
251   _SPIRV_OP(cl_khr_egl_event)
252   _SPIRV_OP(cl_khr_srgb_image_writes)
253 #undef _SPIRV_OP
254 };
255 }
256 
257 
258 ///////////////////////////////////////////////////////////////////////////////
259 //
260 // Functions
261 //
262 ///////////////////////////////////////////////////////////////////////////////
263 
264 /// Get instruction index for SPIR-V extended instruction for OpenCL.std
265 ///   extended instruction set.
266 /// \param MangledName The mangled name of OpenCL builtin function.
267 /// \param DemangledName The demangled name of OpenCL builtin function if
268 ///   not empty.
269 /// \return instruction index of extended instruction if the OpenCL builtin
270 ///   function is translated to an extended instruction, otherwise ~0U.
271 unsigned getExtOp(StringRef MangledName,
272     const std::string &DemangledName = "");
273 
274 /// Get an empty SPIR-V instruction.
275 std::unique_ptr<SPIRVEntry>
276 getSPIRVInst(const OCLBuiltinTransInfo &Info);
277 
278 /// Get literal arguments of call of atomic_work_item_fence.
279 AtomicWorkItemFenceLiterals getAtomicWorkItemFenceLiterals(CallInst* CI);
280 
281 /// Get literal arguments of call of work_group_barrier or sub_group_barrier.
282 BarrierLiterals getBarrierLiterals(CallInst* CI);
283 
284 /// Get number of memory order arguments for atomic builtin function.
285 size_t getAtomicBuiltinNumMemoryOrderArgs(StringRef Name);
286 
287 /// Get OCL version from metadata opencl.ocl.version.
288 /// \param AllowMulti Allows multiple operands if true.
289 /// \return OCL version encoded as Major*10^5+Minor*10^3+Rev,
290 /// e.g. 201000 for OCL 2.1, 200000 for OCL 2.0, 102000 for OCL 1.2,
291 /// 0 if metadata not found.
292 /// If there are multiple operands, check they are identical.
293 unsigned getOCLVersion(Module *M, bool AllowMulti = false);
294 
295 /// Encode OpenCL version as Major*10^5+Minor*10^3+Rev.
296 unsigned
297 encodeOCLVer(unsigned short Major,
298     unsigned char Minor, unsigned char Rev);
299 
300 /// Decode OpenCL version which is encoded as Major*10^5+Minor*10^3+Rev
301 std::tuple<unsigned short, unsigned char, unsigned char>
302 decodeOCLVer(unsigned Ver);
303 
304 /// Decode a MDNode assuming it contains three integer constants.
305 void decodeMDNode(MDNode* N, unsigned& X, unsigned& Y, unsigned& Z);
306 
307 /// Decode OpenCL vector type hint MDNode and encode it as SPIR-V execution
308 /// mode VecTypeHint.
309 unsigned transVecTypeHint(MDNode* Node);
310 
311 /// Decode SPIR-V encoding of vector type hint execution mode.
312 Type *decodeVecTypeHint(LLVMContext &C, unsigned code);
313 
314 SPIRAddressSpace getOCLOpaqueTypeAddrSpace(Op OpCode);
315 SPIR::TypeAttributeEnum getOCLOpaqueTypeAddrSpace(SPIR::TypePrimitiveEnum prim);
316 
mapOCLMemSemanticToSPIRV(unsigned MemFenceFlag,OCLMemOrderKind Order)317 inline unsigned mapOCLMemSemanticToSPIRV(unsigned MemFenceFlag,
318     OCLMemOrderKind Order) {
319   return OCLMemOrderMap::map(Order) |
320       mapBitMask<OCLMemFenceMap>(MemFenceFlag);
321 }
322 
mapOCLMemFenceFlagToSPIRV(unsigned MemFenceFlag)323 inline unsigned mapOCLMemFenceFlagToSPIRV(unsigned MemFenceFlag) {
324   return mapBitMask<OCLMemFenceMap>(MemFenceFlag);
325 }
326 
327 inline std::pair<unsigned, OCLMemOrderKind>
mapSPIRVMemSemanticToOCL(unsigned Sema)328 mapSPIRVMemSemanticToOCL(unsigned Sema) {
329   return std::make_pair(rmapBitMask<OCLMemFenceMap>(Sema),
330     OCLMemOrderMap::rmap(extractSPIRVMemOrderSemantic(Sema)));
331 }
332 
333 inline OCLMemOrderKind
mapSPIRVMemOrderToOCL(unsigned Sema)334 mapSPIRVMemOrderToOCL(unsigned Sema) {
335   return OCLMemOrderMap::rmap(extractSPIRVMemOrderSemantic(Sema));
336 }
337 
338 /// Mutate call instruction to call OpenCL builtin function.
339 CallInst *
340 mutateCallInstOCL(Module *M, CallInst *CI,
341     std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
342     AttributeSet *Attrs = nullptr);
343 
344 /// Mutate call instruction to call OpenCL builtin function.
345 Instruction *
346 mutateCallInstOCL(Module *M, CallInst *CI,
347     std::function<std::string (CallInst *, std::vector<Value *> &,
348         Type *&RetTy)> ArgMutate,
349     std::function<Instruction *(CallInst *)> RetMutate,
350     AttributeSet *Attrs = nullptr);
351 
352 /// Mutate a function to OpenCL builtin function.
353 void
354 mutateFunctionOCL(Function *F,
355     std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate,
356     AttributeSet *Attrs = nullptr);
357 
358 /// Check if instruction is bitcast from spirv.ConstantSampler to spirv.Sampler
359 bool
360 isSamplerInitializer(Instruction *Inst);
361 
362 /// Check if instruction is bitcast from spirv.ConstantPipeStorage
363 /// to spirv.PipeStorage
364 bool
365 isPipeStorageInitializer(Instruction *Inst);
366 
367 /// Check (isSamplerInitializer || isPipeStorageInitializer)
368 bool
369 isSpecialTypeInitializer(Instruction* Inst);
370 
371 } // namespace OCLUtil
372 
373 ///////////////////////////////////////////////////////////////////////////////
374 //
375 // Map definitions
376 //
377 ///////////////////////////////////////////////////////////////////////////////
378 
379 using namespace OCLUtil;
380 namespace SPIRV {
381 template<> inline void
init()382 SPIRVMap<OCLMemFenceKind, MemorySemanticsMask>::init() {
383   add(OCLMF_Local, MemorySemanticsWorkgroupMemoryMask);
384   add(OCLMF_Global, MemorySemanticsCrossWorkgroupMemoryMask);
385   add(OCLMF_Image, MemorySemanticsImageMemoryMask);
386 }
387 
388 template<> inline void
init()389 SPIRVMap<OCLMemOrderKind, unsigned, MemorySemanticsMask>::init() {
390   add(OCLMO_relaxed, MemorySemanticsMaskNone);
391   add(OCLMO_acquire, MemorySemanticsAcquireMask);
392   add(OCLMO_release, MemorySemanticsReleaseMask);
393   add(OCLMO_acq_rel, MemorySemanticsAcquireReleaseMask);
394   add(OCLMO_seq_cst, MemorySemanticsSequentiallyConsistentMask);
395 }
396 
397 template<> inline void
init()398 SPIRVMap<OCLScopeKind, Scope>::init() {
399   add(OCLMS_work_item, ScopeInvocation);
400   add(OCLMS_work_group, ScopeWorkgroup);
401   add(OCLMS_device, ScopeDevice);
402   add(OCLMS_all_svm_devices, ScopeCrossDevice);
403   add(OCLMS_sub_group, ScopeSubgroup);
404 }
405 
406 template<> inline void
init()407 SPIRVMap<std::string, SPIRVGroupOperationKind>::init() {
408   add("reduce", GroupOperationReduce);
409   add("scan_inclusive", GroupOperationInclusiveScan);
410   add("scan_exclusive", GroupOperationExclusiveScan);
411 }
412 
413 template<> inline void
init()414 SPIRVMap<std::string, SPIRVFPRoundingModeKind>::init() {
415   add("rte", FPRoundingModeRTE);
416   add("rtz", FPRoundingModeRTZ);
417   add("rtp", FPRoundingModeRTP);
418   add("rtn", FPRoundingModeRTN);
419 }
420 
421 template<> inline void
init()422 SPIRVMap<OclExt::Kind, std::string>::init() {
423 #define _SPIRV_OP(x) add(OclExt::x, #x);
424   _SPIRV_OP(cl_images)
425   _SPIRV_OP(cl_doubles)
426   _SPIRV_OP(cl_khr_int64_base_atomics)
427   _SPIRV_OP(cl_khr_int64_extended_atomics)
428   _SPIRV_OP(cl_khr_fp16)
429   _SPIRV_OP(cl_khr_gl_sharing)
430   _SPIRV_OP(cl_khr_gl_event)
431   _SPIRV_OP(cl_khr_d3d10_sharing)
432   _SPIRV_OP(cl_khr_media_sharing)
433   _SPIRV_OP(cl_khr_d3d11_sharing)
434   _SPIRV_OP(cl_khr_global_int32_base_atomics)
435   _SPIRV_OP(cl_khr_global_int32_extended_atomics)
436   _SPIRV_OP(cl_khr_local_int32_base_atomics)
437   _SPIRV_OP(cl_khr_local_int32_extended_atomics)
438   _SPIRV_OP(cl_khr_byte_addressable_store)
439   _SPIRV_OP(cl_khr_3d_image_writes)
440   _SPIRV_OP(cl_khr_gl_msaa_sharing)
441   _SPIRV_OP(cl_khr_depth_images)
442   _SPIRV_OP(cl_khr_gl_depth_images)
443   _SPIRV_OP(cl_khr_subgroups)
444   _SPIRV_OP(cl_khr_mipmap_image)
445   _SPIRV_OP(cl_khr_mipmap_image_writes)
446   _SPIRV_OP(cl_khr_egl_event)
447   _SPIRV_OP(cl_khr_srgb_image_writes)
448 #undef _SPIRV_OP
449 }
450 
451 template<> inline void
init()452 SPIRVMap<OclExt::Kind, SPIRVCapabilityKind>::init() {
453   add(OclExt::cl_images, CapabilityImageBasic);
454   add(OclExt::cl_doubles, CapabilityFloat64);
455   add(OclExt::cl_khr_int64_base_atomics, CapabilityInt64Atomics);
456   add(OclExt::cl_khr_int64_extended_atomics, CapabilityInt64Atomics);
457   add(OclExt::cl_khr_fp16, CapabilityFloat16);
458   add(OclExt::cl_khr_subgroups, CapabilityGroups);
459   add(OclExt::cl_khr_mipmap_image, CapabilityImageMipmap);
460   add(OclExt::cl_khr_mipmap_image_writes, CapabilityImageMipmap);
461 }
462 
463 /// Map OpenCL work functions to SPIR-V builtin variables.
464 template<> inline void
init()465 SPIRVMap<std::string, SPIRVBuiltinVariableKind>::init() {
466   add("get_work_dim", BuiltInWorkDim);
467   add("get_global_size", BuiltInGlobalSize);
468   add("get_global_id", BuiltInGlobalInvocationId);
469   add("get_global_offset", BuiltInGlobalOffset);
470   add("get_local_size", BuiltInWorkgroupSize);
471   add("get_enqueued_local_size", BuiltInEnqueuedWorkgroupSize);
472   add("get_local_id", BuiltInLocalInvocationId);
473   add("get_num_groups", BuiltInNumWorkgroups);
474   add("get_group_id", BuiltInWorkgroupId);
475   add("get_global_linear_id", BuiltInGlobalLinearId);
476   add("get_local_linear_id", BuiltInLocalInvocationIndex);
477   add("get_sub_group_size", BuiltInSubgroupSize);
478   add("get_max_sub_group_size", BuiltInSubgroupMaxSize);
479   add("get_num_sub_groups", BuiltInNumSubgroups);
480   add("get_enqueued_num_sub_groups", BuiltInNumEnqueuedSubgroups);
481   add("get_sub_group_id", BuiltInSubgroupId);
482   add("get_sub_group_local_id", BuiltInSubgroupLocalInvocationId);
483 }
484 
485 // Maps uniqued OCL builtin function name to SPIR-V op code.
486 // A uniqued OCL builtin function name may be different from the real
487 // OCL builtin function name. e.g. instead of atomic_min, atomic_umin
488 // is used for atomic_min with unsigned integer parameter.
489 // work_group_ and sub_group_ functions are unified as group_ functions
490 // except work_group_barrier.
491 class SPIRVInstruction;
492 template<> inline void
init()493 SPIRVMap<std::string, Op, SPIRVInstruction>::init() {
494 #define _SPIRV_OP(x,y) add("atom_"#x, OpAtomic##y);
495 // cl_khr_int64_base_atomics builtins
496 _SPIRV_OP(add, IAdd)
497 _SPIRV_OP(sub, ISub)
498 _SPIRV_OP(xchg, Exchange)
499 _SPIRV_OP(dec, IDecrement)
500 _SPIRV_OP(inc, IIncrement)
501 _SPIRV_OP(cmpxchg, CompareExchange)
502 // cl_khr_int64_extended_atomics builtins
503 _SPIRV_OP(min, SMin)
504 _SPIRV_OP(max, SMax)
505 _SPIRV_OP(and, And)
506 _SPIRV_OP(or, Or)
507 _SPIRV_OP(xor, Xor)
508 #undef _SPIRV_OP
509 #define _SPIRV_OP(x,y) add("atomic_"#x, Op##y);
510 // CL 2.0 atomic builtins
511 _SPIRV_OP(flag_test_and_set_explicit, AtomicFlagTestAndSet)
512 _SPIRV_OP(flag_clear_explicit, AtomicFlagClear)
513 _SPIRV_OP(load_explicit, AtomicLoad)
514 _SPIRV_OP(store_explicit, AtomicStore)
515 _SPIRV_OP(exchange_explicit, AtomicExchange)
516 _SPIRV_OP(compare_exchange_strong_explicit, AtomicCompareExchange)
517 _SPIRV_OP(compare_exchange_weak_explicit, AtomicCompareExchangeWeak)
518 _SPIRV_OP(inc, AtomicIIncrement)
519 _SPIRV_OP(dec, AtomicIDecrement)
520 _SPIRV_OP(fetch_add_explicit, AtomicIAdd)
521 _SPIRV_OP(fetch_sub_explicit, AtomicISub)
522 _SPIRV_OP(fetch_umin_explicit, AtomicUMin)
523 _SPIRV_OP(fetch_umax_explicit, AtomicUMax)
524 _SPIRV_OP(fetch_min_explicit, AtomicSMin)
525 _SPIRV_OP(fetch_max_explicit, AtomicSMax)
526 _SPIRV_OP(fetch_and_explicit, AtomicAnd)
527 _SPIRV_OP(fetch_or_explicit, AtomicOr)
528 _SPIRV_OP(fetch_xor_explicit, AtomicXor)
529 #undef _SPIRV_OP
530 #define _SPIRV_OP(x,y) add(#x, Op##y);
531 _SPIRV_OP(dot, Dot)
532 _SPIRV_OP(async_work_group_copy, GroupAsyncCopy)
533 _SPIRV_OP(async_work_group_strided_copy, GroupAsyncCopy)
534 _SPIRV_OP(wait_group_events, GroupWaitEvents)
535 _SPIRV_OP(isequal, FOrdEqual)
536 _SPIRV_OP(isnotequal, FUnordNotEqual)
537 _SPIRV_OP(isgreater, FOrdGreaterThan)
538 _SPIRV_OP(isgreaterequal, FOrdGreaterThanEqual)
539 _SPIRV_OP(isless, FOrdLessThan)
540 _SPIRV_OP(islessequal, FOrdLessThanEqual)
541 _SPIRV_OP(islessgreater, LessOrGreater)
542 _SPIRV_OP(isordered, Ordered)
543 _SPIRV_OP(isunordered, Unordered)
544 _SPIRV_OP(isfinite, IsFinite)
545 _SPIRV_OP(isinf, IsInf)
546 _SPIRV_OP(isnan, IsNan)
547 _SPIRV_OP(isnormal, IsNormal)
548 _SPIRV_OP(signbit, SignBitSet)
549 _SPIRV_OP(any, Any)
550 _SPIRV_OP(all, All)
551 _SPIRV_OP(get_fence, GenericPtrMemSemantics)
552 // CL 2.0 kernel enqueue builtins
553 _SPIRV_OP(enqueue_marker, EnqueueMarker)
554 _SPIRV_OP(enqueue_kernel, EnqueueKernel)
555 _SPIRV_OP(get_kernel_ndrange_subgroup_count, GetKernelNDrangeSubGroupCount)
556 _SPIRV_OP(get_kernel_ndrange_max_subgroup_count, GetKernelNDrangeMaxSubGroupSize)
557 _SPIRV_OP(get_kernel_work_group_size, GetKernelWorkGroupSize)
558 _SPIRV_OP(get_kernel_preferred_work_group_size_multiple, GetKernelPreferredWorkGroupSizeMultiple)
559 _SPIRV_OP(retain_event, RetainEvent)
560 _SPIRV_OP(release_event, ReleaseEvent)
561 _SPIRV_OP(create_user_event, CreateUserEvent)
562 _SPIRV_OP(is_valid_event, IsValidEvent)
563 _SPIRV_OP(set_user_event_status, SetUserEventStatus)
564 _SPIRV_OP(capture_event_profiling_info, CaptureEventProfilingInfo)
565 _SPIRV_OP(get_default_queue, GetDefaultQueue)
566 _SPIRV_OP(ndrange_1D, BuildNDRange)
567 _SPIRV_OP(ndrange_2D, BuildNDRange)
568 _SPIRV_OP(ndrange_3D, BuildNDRange)
569 // Generic Address Space Casts
570 _SPIRV_OP(to_global, GenericCastToPtrExplicit)
571 _SPIRV_OP(to_local, GenericCastToPtrExplicit)
572 _SPIRV_OP(to_private, GenericCastToPtrExplicit)
573 _SPIRV_OP(work_group_barrier, ControlBarrier)
574 // CL 2.0 pipe builtins
575 _SPIRV_OP(read_pipe, ReadPipe)
576 _SPIRV_OP(write_pipe, WritePipe)
577 _SPIRV_OP(reserved_read_pipe, ReservedReadPipe)
578 _SPIRV_OP(reserved_write_pipe, ReservedWritePipe)
579 _SPIRV_OP(reserve_read_pipe, ReserveReadPipePackets)
580 _SPIRV_OP(reserve_write_pipe, ReserveWritePipePackets)
581 _SPIRV_OP(commit_read_pipe, CommitReadPipe)
582 _SPIRV_OP(commit_write_pipe, CommitWritePipe)
583 _SPIRV_OP(is_valid_reserve_id, IsValidReserveId)
584 _SPIRV_OP(group_reserve_read_pipe, GroupReserveReadPipePackets)
585 _SPIRV_OP(group_reserve_write_pipe, GroupReserveWritePipePackets)
586 _SPIRV_OP(group_commit_read_pipe, GroupCommitReadPipe)
587 _SPIRV_OP(group_commit_write_pipe, GroupCommitWritePipe)
588 _SPIRV_OP(get_pipe_num_packets, GetNumPipePackets)
589 _SPIRV_OP(get_pipe_max_packets, GetMaxPipePackets)
590 // CL 2.0 workgroup builtins
591 _SPIRV_OP(group_all, GroupAll)
592 _SPIRV_OP(group_any, GroupAny)
593 _SPIRV_OP(group_broadcast, GroupBroadcast)
594 _SPIRV_OP(group_iadd, GroupIAdd)
595 _SPIRV_OP(group_fadd, GroupFAdd)
596 _SPIRV_OP(group_fmin, GroupFMin)
597 _SPIRV_OP(group_umin, GroupUMin)
598 _SPIRV_OP(group_smin, GroupSMin)
599 _SPIRV_OP(group_fmax, GroupFMax)
600 _SPIRV_OP(group_umax, GroupUMax)
601 _SPIRV_OP(group_smax, GroupSMax)
602 // CL image builtins
603 _SPIRV_OP(SampledImage, SampledImage)
604 _SPIRV_OP(ImageSampleExplicitLod, ImageSampleExplicitLod)
605 _SPIRV_OP(read_image, ImageRead)
606 _SPIRV_OP(write_image, ImageWrite)
607 _SPIRV_OP(get_image_channel_data_type, ImageQueryFormat)
608 _SPIRV_OP(get_image_channel_order, ImageQueryOrder)
609 _SPIRV_OP(get_image_num_mip_levels, ImageQueryLevels)
610 _SPIRV_OP(get_image_num_samples, ImageQuerySamples)
611 #undef _SPIRV_OP
612 }
613 
614 template<> inline void
init()615 SPIRVMap<std::string, Op, OCLOpaqueType>::init() {
616   add("opencl.event_t", OpTypeEvent);
617   add("opencl.pipe_t", OpTypePipe);
618   add("opencl.clk_event_t", OpTypeDeviceEvent);
619   add("opencl.reserve_id_t", OpTypeReserveId);
620   add("opencl.queue_t", OpTypeQueue);
621 }
622 
623 } // namespace SPIRV
624