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. 127 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 317 inline unsigned mapOCLMemSemanticToSPIRV(unsigned MemFenceFlag, 318 OCLMemOrderKind Order) { 319 return OCLMemOrderMap::map(Order) | 320 mapBitMask<OCLMemFenceMap>(MemFenceFlag); 321 } 322 323 inline unsigned mapOCLMemFenceFlagToSPIRV(unsigned MemFenceFlag) { 324 return mapBitMask<OCLMemFenceMap>(MemFenceFlag); 325 } 326 327 inline std::pair<unsigned, OCLMemOrderKind> 328 mapSPIRVMemSemanticToOCL(unsigned Sema) { 329 return std::make_pair(rmapBitMask<OCLMemFenceMap>(Sema), 330 OCLMemOrderMap::rmap(extractSPIRVMemOrderSemantic(Sema))); 331 } 332 333 inline OCLMemOrderKind 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 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 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 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 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 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 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 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 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 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 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