| //===- OCLUtil.h - OCL Utilities declarations -------------------*- C++ -*-===// |
| // |
| // 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 declares OCL utility functions. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "SPIRVInternal.h" |
| |
| #include <utility> |
| #include <tuple> |
| #include <functional> |
| using namespace SPIRV; |
| using namespace llvm; |
| using namespace spv; |
| |
| namespace OCLUtil { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // Enums |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| enum OCLMemFenceKind { |
| OCLMF_Local = 1, |
| OCLMF_Global = 2, |
| OCLMF_Image = 4, |
| }; |
| |
| enum OCLScopeKind { |
| OCLMS_work_item, |
| OCLMS_work_group, |
| OCLMS_device, |
| OCLMS_all_svm_devices, |
| OCLMS_sub_group, |
| }; |
| |
| enum OCLMemOrderKind { |
| OCLMO_relaxed, |
| OCLMO_acquire, |
| OCLMO_release, |
| OCLMO_acq_rel, |
| OCLMO_seq_cst |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // Types |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| typedef SPIRVMap<OCLMemFenceKind, MemorySemanticsMask> |
| OCLMemFenceMap; |
| |
| typedef SPIRVMap<OCLMemOrderKind, unsigned, MemorySemanticsMask> |
| OCLMemOrderMap; |
| |
| typedef SPIRVMap<OCLScopeKind, Scope> |
| OCLMemScopeMap; |
| |
| typedef SPIRVMap<std::string, SPIRVGroupOperationKind> |
| SPIRSPIRVGroupOperationMap; |
| |
| typedef SPIRVMap<std::string, SPIRVFPRoundingModeKind> |
| SPIRSPIRVFPRoundingModeMap; |
| |
| typedef SPIRVMap<std::string, Op, SPIRVInstruction> |
| OCLSPIRVBuiltinMap; |
| |
| typedef SPIRVMap<std::string, SPIRVBuiltinVariableKind> |
| SPIRSPIRVBuiltinVariableMap; |
| |
| /// Tuple of literals for atomic_work_item_fence (flag, order, scope) |
| typedef std::tuple<unsigned, OCLMemOrderKind, OCLScopeKind> |
| AtomicWorkItemFenceLiterals; |
| |
| /// Tuple of literals for work_group_barrier or sub_group_barrier |
| /// (flag, mem_scope, exec_scope) |
| typedef std::tuple<unsigned, OCLScopeKind, OCLScopeKind> |
| BarrierLiterals; |
| |
| class OCLOpaqueType; |
| typedef SPIRVMap<std::string, Op, OCLOpaqueType> |
| OCLOpaqueTypeOpCodeMap; |
| |
| /// Information for translating OCL builtin. |
| struct OCLBuiltinTransInfo { |
| std::string UniqName; |
| std::string MangledName; |
| std::string Postfix; // Postfix to be added |
| /// Postprocessor of operands |
| std::function<void(std::vector<Value *>&)> PostProc; |
| Type* RetTy; // Return type of the translated function |
| bool isRetSigned; // When RetTy is int, determines if extensions |
| // on it should be a sext or zet. |
| OCLBuiltinTransInfo() : RetTy(nullptr), isRetSigned(false) { |
| PostProc = [](std::vector<Value *>&){}; |
| } |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // Constants |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| namespace kOCLBuiltinName { |
| const static char All[] = "all"; |
| const static char Any[] = "any"; |
| const static char AsyncWorkGroupCopy[] = "async_work_group_copy"; |
| const static char AsyncWorkGroupStridedCopy[] = "async_work_group_strided_copy"; |
| const static char AtomPrefix[] = "atom_"; |
| const static char AtomCmpXchg[] = "atom_cmpxchg"; |
| const static char AtomicPrefix[] = "atomic_"; |
| const static char AtomicCmpXchg[] = "atomic_cmpxchg"; |
| const static char AtomicCmpXchgStrong[] = "atomic_compare_exchange_strong"; |
| const static char AtomicCmpXchgStrongExplicit[] = "atomic_compare_exchange_strong_explicit"; |
| const static char AtomicCmpXchgWeak[] = "atomic_compare_exchange_weak"; |
| const static char AtomicCmpXchgWeakExplicit[] = "atomic_compare_exchange_weak_explicit"; |
| const static char AtomicInit[] = "atomic_init"; |
| const static char AtomicWorkItemFence[] = "atomic_work_item_fence"; |
| const static char Barrier[] = "barrier"; |
| const static char Clamp[] = "clamp"; |
| const static char ConvertPrefix[] = "convert_"; |
| const static char Dot[] = "dot"; |
| const static char EnqueueKernel[] = "enqueue_kernel"; |
| const static char FMax[] = "fmax"; |
| const static char FMin[] = "fmin"; |
| const static char GetFence[] = "get_fence"; |
| const static char GetImageArraySize[] = "get_image_array_size"; |
| const static char GetImageChannelOrder[] = "get_image_channel_order"; |
| const static char GetImageChannelDataType[] = "get_image_channel_data_type"; |
| const static char GetImageDepth[] = "get_image_depth"; |
| const static char GetImageDim[] = "get_image_dim"; |
| const static char GetImageHeight[] = "get_image_height"; |
| const static char GetImageWidth[] = "get_image_width"; |
| const static char IsFinite[] = "isfinite"; |
| const static char IsNan[] = "isnan"; |
| const static char IsNormal[] = "isnormal"; |
| const static char IsInf[] = "isinf"; |
| const static char Max[] = "max"; |
| const static char MemFence[] = "mem_fence"; |
| const static char Min[] = "min"; |
| const static char Mix[] = "mix"; |
| const static char NDRangePrefix[] = "ndrange_"; |
| const static char Pipe[] = "pipe"; |
| const static char ReadImage[] = "read_image"; |
| const static char ReadPipe[] = "read_pipe"; |
| const static char RoundingPrefix[] = "_r"; |
| const static char Sampled[] = "sampled_"; |
| const static char SampledReadImage[] = "sampled_read_image"; |
| const static char Signbit[] = "signbit"; |
| const static char SmoothStep[] = "smoothstep"; |
| const static char Step[] = "step"; |
| const static char SubGroupPrefix[] = "sub_group_"; |
| const static char SubGroupBarrier[] = "sub_group_barrier"; |
| const static char SubPrefix[] = "sub_"; |
| const static char ToGlobal[] = "to_global"; |
| const static char ToLocal[] = "to_local"; |
| const static char ToPrivate[] = "to_private"; |
| const static char VLoadPrefix[] = "vload"; |
| const static char VLoadAPrefix[] = "vloada"; |
| const static char VLoadHalf[] = "vload_half"; |
| const static char VStorePrefix[] = "vstore"; |
| const static char VStoreAPrefix[] = "vstorea"; |
| const static char WaitGroupEvent[] = "wait_group_events"; |
| const static char WriteImage[] = "write_image"; |
| const static char WorkGroupBarrier[] = "work_group_barrier"; |
| const static char WritePipe[] = "write_pipe"; |
| const static char WorkGroupPrefix[] = "work_group_"; |
| const static char WorkGroupAll[] = "work_group_all"; |
| const static char WorkGroupAny[] = "work_group_any"; |
| const static char SubGroupAll[] = "sub_group_all"; |
| const static char SubGroupAny[] = "sub_group_any"; |
| const static char WorkPrefix[] = "work_"; |
| } |
| |
| /// Offset for OpenCL image channel order enumeration values. |
| const unsigned int OCLImageChannelOrderOffset = 0x10B0; |
| |
| /// Offset for OpenCL image channel data type enumeration values. |
| const unsigned int OCLImageChannelDataTypeOffset = 0x10D0; |
| |
| /// OCL 1.x atomic memory order when translated to 2.0 atomics. |
| const OCLMemOrderKind OCLLegacyAtomicMemOrder = OCLMO_seq_cst; |
| |
| /// OCL 1.x atomic memory scope when translated to 2.0 atomics. |
| const OCLScopeKind OCLLegacyAtomicMemScope = OCLMS_device; |
| |
| namespace kOCLVer { |
| const unsigned CL12 = 102000; |
| const unsigned CL20 = 200000; |
| const unsigned CL21 = 201000; |
| } |
| |
| namespace OclExt { |
| enum Kind { |
| #define _SPIRV_OP(x) x, |
| _SPIRV_OP(cl_images) |
| _SPIRV_OP(cl_doubles) |
| _SPIRV_OP(cl_khr_int64_base_atomics) |
| _SPIRV_OP(cl_khr_int64_extended_atomics) |
| _SPIRV_OP(cl_khr_fp16) |
| _SPIRV_OP(cl_khr_gl_sharing) |
| _SPIRV_OP(cl_khr_gl_event) |
| _SPIRV_OP(cl_khr_d3d10_sharing) |
| _SPIRV_OP(cl_khr_media_sharing) |
| _SPIRV_OP(cl_khr_d3d11_sharing) |
| _SPIRV_OP(cl_khr_global_int32_base_atomics) |
| _SPIRV_OP(cl_khr_global_int32_extended_atomics) |
| _SPIRV_OP(cl_khr_local_int32_base_atomics) |
| _SPIRV_OP(cl_khr_local_int32_extended_atomics) |
| _SPIRV_OP(cl_khr_byte_addressable_store) |
| _SPIRV_OP(cl_khr_3d_image_writes) |
| _SPIRV_OP(cl_khr_gl_msaa_sharing) |
| _SPIRV_OP(cl_khr_depth_images) |
| _SPIRV_OP(cl_khr_gl_depth_images) |
| _SPIRV_OP(cl_khr_subgroups) |
| _SPIRV_OP(cl_khr_mipmap_image) |
| _SPIRV_OP(cl_khr_mipmap_image_writes) |
| _SPIRV_OP(cl_khr_egl_event) |
| _SPIRV_OP(cl_khr_srgb_image_writes) |
| #undef _SPIRV_OP |
| }; |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // Functions |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /// Get instruction index for SPIR-V extended instruction for OpenCL.std |
| /// extended instruction set. |
| /// \param MangledName The mangled name of OpenCL builtin function. |
| /// \param DemangledName The demangled name of OpenCL builtin function if |
| /// not empty. |
| /// \return instruction index of extended instruction if the OpenCL builtin |
| /// function is translated to an extended instruction, otherwise ~0U. |
| unsigned getExtOp(StringRef MangledName, |
| const std::string &DemangledName = ""); |
| |
| /// Get an empty SPIR-V instruction. |
| std::unique_ptr<SPIRVEntry> |
| getSPIRVInst(const OCLBuiltinTransInfo &Info); |
| |
| /// Get literal arguments of call of atomic_work_item_fence. |
| AtomicWorkItemFenceLiterals getAtomicWorkItemFenceLiterals(CallInst* CI); |
| |
| /// Get literal arguments of call of work_group_barrier or sub_group_barrier. |
| BarrierLiterals getBarrierLiterals(CallInst* CI); |
| |
| /// Get number of memory order arguments for atomic builtin function. |
| size_t getAtomicBuiltinNumMemoryOrderArgs(StringRef Name); |
| |
| /// Get OCL version from metadata opencl.ocl.version. |
| /// \param AllowMulti Allows multiple operands if true. |
| /// \return OCL version encoded as Major*10^5+Minor*10^3+Rev, |
| /// e.g. 201000 for OCL 2.1, 200000 for OCL 2.0, 102000 for OCL 1.2, |
| /// 0 if metadata not found. |
| /// If there are multiple operands, check they are identical. |
| unsigned getOCLVersion(Module *M, bool AllowMulti = false); |
| |
| /// Encode OpenCL version as Major*10^5+Minor*10^3+Rev. |
| unsigned |
| encodeOCLVer(unsigned short Major, |
| unsigned char Minor, unsigned char Rev); |
| |
| /// Decode OpenCL version which is encoded as Major*10^5+Minor*10^3+Rev |
| std::tuple<unsigned short, unsigned char, unsigned char> |
| decodeOCLVer(unsigned Ver); |
| |
| /// Decode a MDNode assuming it contains three integer constants. |
| void decodeMDNode(MDNode* N, unsigned& X, unsigned& Y, unsigned& Z); |
| |
| /// Decode OpenCL vector type hint MDNode and encode it as SPIR-V execution |
| /// mode VecTypeHint. |
| unsigned transVecTypeHint(MDNode* Node); |
| |
| /// Decode SPIR-V encoding of vector type hint execution mode. |
| Type *decodeVecTypeHint(LLVMContext &C, unsigned code); |
| |
| SPIRAddressSpace getOCLOpaqueTypeAddrSpace(Op OpCode); |
| SPIR::TypeAttributeEnum getOCLOpaqueTypeAddrSpace(SPIR::TypePrimitiveEnum prim); |
| |
| inline unsigned mapOCLMemSemanticToSPIRV(unsigned MemFenceFlag, |
| OCLMemOrderKind Order) { |
| return OCLMemOrderMap::map(Order) | |
| mapBitMask<OCLMemFenceMap>(MemFenceFlag); |
| } |
| |
| inline unsigned mapOCLMemFenceFlagToSPIRV(unsigned MemFenceFlag) { |
| return mapBitMask<OCLMemFenceMap>(MemFenceFlag); |
| } |
| |
| inline std::pair<unsigned, OCLMemOrderKind> |
| mapSPIRVMemSemanticToOCL(unsigned Sema) { |
| return std::make_pair(rmapBitMask<OCLMemFenceMap>(Sema), |
| OCLMemOrderMap::rmap(extractSPIRVMemOrderSemantic(Sema))); |
| } |
| |
| inline OCLMemOrderKind |
| mapSPIRVMemOrderToOCL(unsigned Sema) { |
| return OCLMemOrderMap::rmap(extractSPIRVMemOrderSemantic(Sema)); |
| } |
| |
| /// Mutate call instruction to call OpenCL builtin function. |
| CallInst * |
| mutateCallInstOCL(Module *M, CallInst *CI, |
| std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate, |
| AttributeSet *Attrs = nullptr); |
| |
| /// Mutate call instruction to call OpenCL builtin function. |
| Instruction * |
| mutateCallInstOCL(Module *M, CallInst *CI, |
| std::function<std::string (CallInst *, std::vector<Value *> &, |
| Type *&RetTy)> ArgMutate, |
| std::function<Instruction *(CallInst *)> RetMutate, |
| AttributeSet *Attrs = nullptr); |
| |
| /// Mutate a function to OpenCL builtin function. |
| void |
| mutateFunctionOCL(Function *F, |
| std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate, |
| AttributeSet *Attrs = nullptr); |
| |
| /// Check if instruction is bitcast from spirv.ConstantSampler to spirv.Sampler |
| bool |
| isSamplerInitializer(Instruction *Inst); |
| |
| /// Check if instruction is bitcast from spirv.ConstantPipeStorage |
| /// to spirv.PipeStorage |
| bool |
| isPipeStorageInitializer(Instruction *Inst); |
| |
| /// Check (isSamplerInitializer || isPipeStorageInitializer) |
| bool |
| isSpecialTypeInitializer(Instruction* Inst); |
| |
| } // namespace OCLUtil |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // Map definitions |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| using namespace OCLUtil; |
| namespace SPIRV { |
| template<> inline void |
| SPIRVMap<OCLMemFenceKind, MemorySemanticsMask>::init() { |
| add(OCLMF_Local, MemorySemanticsWorkgroupMemoryMask); |
| add(OCLMF_Global, MemorySemanticsCrossWorkgroupMemoryMask); |
| add(OCLMF_Image, MemorySemanticsImageMemoryMask); |
| } |
| |
| template<> inline void |
| SPIRVMap<OCLMemOrderKind, unsigned, MemorySemanticsMask>::init() { |
| add(OCLMO_relaxed, MemorySemanticsMaskNone); |
| add(OCLMO_acquire, MemorySemanticsAcquireMask); |
| add(OCLMO_release, MemorySemanticsReleaseMask); |
| add(OCLMO_acq_rel, MemorySemanticsAcquireReleaseMask); |
| add(OCLMO_seq_cst, MemorySemanticsSequentiallyConsistentMask); |
| } |
| |
| template<> inline void |
| SPIRVMap<OCLScopeKind, Scope>::init() { |
| add(OCLMS_work_item, ScopeInvocation); |
| add(OCLMS_work_group, ScopeWorkgroup); |
| add(OCLMS_device, ScopeDevice); |
| add(OCLMS_all_svm_devices, ScopeCrossDevice); |
| add(OCLMS_sub_group, ScopeSubgroup); |
| } |
| |
| template<> inline void |
| SPIRVMap<std::string, SPIRVGroupOperationKind>::init() { |
| add("reduce", GroupOperationReduce); |
| add("scan_inclusive", GroupOperationInclusiveScan); |
| add("scan_exclusive", GroupOperationExclusiveScan); |
| } |
| |
| template<> inline void |
| SPIRVMap<std::string, SPIRVFPRoundingModeKind>::init() { |
| add("rte", FPRoundingModeRTE); |
| add("rtz", FPRoundingModeRTZ); |
| add("rtp", FPRoundingModeRTP); |
| add("rtn", FPRoundingModeRTN); |
| } |
| |
| template<> inline void |
| SPIRVMap<OclExt::Kind, std::string>::init() { |
| #define _SPIRV_OP(x) add(OclExt::x, #x); |
| _SPIRV_OP(cl_images) |
| _SPIRV_OP(cl_doubles) |
| _SPIRV_OP(cl_khr_int64_base_atomics) |
| _SPIRV_OP(cl_khr_int64_extended_atomics) |
| _SPIRV_OP(cl_khr_fp16) |
| _SPIRV_OP(cl_khr_gl_sharing) |
| _SPIRV_OP(cl_khr_gl_event) |
| _SPIRV_OP(cl_khr_d3d10_sharing) |
| _SPIRV_OP(cl_khr_media_sharing) |
| _SPIRV_OP(cl_khr_d3d11_sharing) |
| _SPIRV_OP(cl_khr_global_int32_base_atomics) |
| _SPIRV_OP(cl_khr_global_int32_extended_atomics) |
| _SPIRV_OP(cl_khr_local_int32_base_atomics) |
| _SPIRV_OP(cl_khr_local_int32_extended_atomics) |
| _SPIRV_OP(cl_khr_byte_addressable_store) |
| _SPIRV_OP(cl_khr_3d_image_writes) |
| _SPIRV_OP(cl_khr_gl_msaa_sharing) |
| _SPIRV_OP(cl_khr_depth_images) |
| _SPIRV_OP(cl_khr_gl_depth_images) |
| _SPIRV_OP(cl_khr_subgroups) |
| _SPIRV_OP(cl_khr_mipmap_image) |
| _SPIRV_OP(cl_khr_mipmap_image_writes) |
| _SPIRV_OP(cl_khr_egl_event) |
| _SPIRV_OP(cl_khr_srgb_image_writes) |
| #undef _SPIRV_OP |
| } |
| |
| template<> inline void |
| SPIRVMap<OclExt::Kind, SPIRVCapabilityKind>::init() { |
| add(OclExt::cl_images, CapabilityImageBasic); |
| add(OclExt::cl_doubles, CapabilityFloat64); |
| add(OclExt::cl_khr_int64_base_atomics, CapabilityInt64Atomics); |
| add(OclExt::cl_khr_int64_extended_atomics, CapabilityInt64Atomics); |
| add(OclExt::cl_khr_fp16, CapabilityFloat16); |
| add(OclExt::cl_khr_subgroups, CapabilityGroups); |
| add(OclExt::cl_khr_mipmap_image, CapabilityImageMipmap); |
| add(OclExt::cl_khr_mipmap_image_writes, CapabilityImageMipmap); |
| } |
| |
| /// Map OpenCL work functions to SPIR-V builtin variables. |
| template<> inline void |
| SPIRVMap<std::string, SPIRVBuiltinVariableKind>::init() { |
| add("get_work_dim", BuiltInWorkDim); |
| add("get_global_size", BuiltInGlobalSize); |
| add("get_global_id", BuiltInGlobalInvocationId); |
| add("get_global_offset", BuiltInGlobalOffset); |
| add("get_local_size", BuiltInWorkgroupSize); |
| add("get_enqueued_local_size", BuiltInEnqueuedWorkgroupSize); |
| add("get_local_id", BuiltInLocalInvocationId); |
| add("get_num_groups", BuiltInNumWorkgroups); |
| add("get_group_id", BuiltInWorkgroupId); |
| add("get_global_linear_id", BuiltInGlobalLinearId); |
| add("get_local_linear_id", BuiltInLocalInvocationIndex); |
| add("get_sub_group_size", BuiltInSubgroupSize); |
| add("get_max_sub_group_size", BuiltInSubgroupMaxSize); |
| add("get_num_sub_groups", BuiltInNumSubgroups); |
| add("get_enqueued_num_sub_groups", BuiltInNumEnqueuedSubgroups); |
| add("get_sub_group_id", BuiltInSubgroupId); |
| add("get_sub_group_local_id", BuiltInSubgroupLocalInvocationId); |
| } |
| |
| // Maps uniqued OCL builtin function name to SPIR-V op code. |
| // A uniqued OCL builtin function name may be different from the real |
| // OCL builtin function name. e.g. instead of atomic_min, atomic_umin |
| // is used for atomic_min with unsigned integer parameter. |
| // work_group_ and sub_group_ functions are unified as group_ functions |
| // except work_group_barrier. |
| class SPIRVInstruction; |
| template<> inline void |
| SPIRVMap<std::string, Op, SPIRVInstruction>::init() { |
| #define _SPIRV_OP(x,y) add("atom_"#x, OpAtomic##y); |
| // cl_khr_int64_base_atomics builtins |
| _SPIRV_OP(add, IAdd) |
| _SPIRV_OP(sub, ISub) |
| _SPIRV_OP(xchg, Exchange) |
| _SPIRV_OP(dec, IDecrement) |
| _SPIRV_OP(inc, IIncrement) |
| _SPIRV_OP(cmpxchg, CompareExchange) |
| // cl_khr_int64_extended_atomics builtins |
| _SPIRV_OP(min, SMin) |
| _SPIRV_OP(max, SMax) |
| _SPIRV_OP(and, And) |
| _SPIRV_OP(or, Or) |
| _SPIRV_OP(xor, Xor) |
| #undef _SPIRV_OP |
| #define _SPIRV_OP(x,y) add("atomic_"#x, Op##y); |
| // CL 2.0 atomic builtins |
| _SPIRV_OP(flag_test_and_set_explicit, AtomicFlagTestAndSet) |
| _SPIRV_OP(flag_clear_explicit, AtomicFlagClear) |
| _SPIRV_OP(load_explicit, AtomicLoad) |
| _SPIRV_OP(store_explicit, AtomicStore) |
| _SPIRV_OP(exchange_explicit, AtomicExchange) |
| _SPIRV_OP(compare_exchange_strong_explicit, AtomicCompareExchange) |
| _SPIRV_OP(compare_exchange_weak_explicit, AtomicCompareExchangeWeak) |
| _SPIRV_OP(inc, AtomicIIncrement) |
| _SPIRV_OP(dec, AtomicIDecrement) |
| _SPIRV_OP(fetch_add_explicit, AtomicIAdd) |
| _SPIRV_OP(fetch_sub_explicit, AtomicISub) |
| _SPIRV_OP(fetch_umin_explicit, AtomicUMin) |
| _SPIRV_OP(fetch_umax_explicit, AtomicUMax) |
| _SPIRV_OP(fetch_min_explicit, AtomicSMin) |
| _SPIRV_OP(fetch_max_explicit, AtomicSMax) |
| _SPIRV_OP(fetch_and_explicit, AtomicAnd) |
| _SPIRV_OP(fetch_or_explicit, AtomicOr) |
| _SPIRV_OP(fetch_xor_explicit, AtomicXor) |
| #undef _SPIRV_OP |
| #define _SPIRV_OP(x,y) add(#x, Op##y); |
| _SPIRV_OP(dot, Dot) |
| _SPIRV_OP(async_work_group_copy, GroupAsyncCopy) |
| _SPIRV_OP(async_work_group_strided_copy, GroupAsyncCopy) |
| _SPIRV_OP(wait_group_events, GroupWaitEvents) |
| _SPIRV_OP(isequal, FOrdEqual) |
| _SPIRV_OP(isnotequal, FUnordNotEqual) |
| _SPIRV_OP(isgreater, FOrdGreaterThan) |
| _SPIRV_OP(isgreaterequal, FOrdGreaterThanEqual) |
| _SPIRV_OP(isless, FOrdLessThan) |
| _SPIRV_OP(islessequal, FOrdLessThanEqual) |
| _SPIRV_OP(islessgreater, LessOrGreater) |
| _SPIRV_OP(isordered, Ordered) |
| _SPIRV_OP(isunordered, Unordered) |
| _SPIRV_OP(isfinite, IsFinite) |
| _SPIRV_OP(isinf, IsInf) |
| _SPIRV_OP(isnan, IsNan) |
| _SPIRV_OP(isnormal, IsNormal) |
| _SPIRV_OP(signbit, SignBitSet) |
| _SPIRV_OP(any, Any) |
| _SPIRV_OP(all, All) |
| _SPIRV_OP(get_fence, GenericPtrMemSemantics) |
| // CL 2.0 kernel enqueue builtins |
| _SPIRV_OP(enqueue_marker, EnqueueMarker) |
| _SPIRV_OP(enqueue_kernel, EnqueueKernel) |
| _SPIRV_OP(get_kernel_ndrange_subgroup_count, GetKernelNDrangeSubGroupCount) |
| _SPIRV_OP(get_kernel_ndrange_max_subgroup_count, GetKernelNDrangeMaxSubGroupSize) |
| _SPIRV_OP(get_kernel_work_group_size, GetKernelWorkGroupSize) |
| _SPIRV_OP(get_kernel_preferred_work_group_size_multiple, GetKernelPreferredWorkGroupSizeMultiple) |
| _SPIRV_OP(retain_event, RetainEvent) |
| _SPIRV_OP(release_event, ReleaseEvent) |
| _SPIRV_OP(create_user_event, CreateUserEvent) |
| _SPIRV_OP(is_valid_event, IsValidEvent) |
| _SPIRV_OP(set_user_event_status, SetUserEventStatus) |
| _SPIRV_OP(capture_event_profiling_info, CaptureEventProfilingInfo) |
| _SPIRV_OP(get_default_queue, GetDefaultQueue) |
| _SPIRV_OP(ndrange_1D, BuildNDRange) |
| _SPIRV_OP(ndrange_2D, BuildNDRange) |
| _SPIRV_OP(ndrange_3D, BuildNDRange) |
| // Generic Address Space Casts |
| _SPIRV_OP(to_global, GenericCastToPtrExplicit) |
| _SPIRV_OP(to_local, GenericCastToPtrExplicit) |
| _SPIRV_OP(to_private, GenericCastToPtrExplicit) |
| _SPIRV_OP(work_group_barrier, ControlBarrier) |
| // CL 2.0 pipe builtins |
| _SPIRV_OP(read_pipe, ReadPipe) |
| _SPIRV_OP(write_pipe, WritePipe) |
| _SPIRV_OP(reserved_read_pipe, ReservedReadPipe) |
| _SPIRV_OP(reserved_write_pipe, ReservedWritePipe) |
| _SPIRV_OP(reserve_read_pipe, ReserveReadPipePackets) |
| _SPIRV_OP(reserve_write_pipe, ReserveWritePipePackets) |
| _SPIRV_OP(commit_read_pipe, CommitReadPipe) |
| _SPIRV_OP(commit_write_pipe, CommitWritePipe) |
| _SPIRV_OP(is_valid_reserve_id, IsValidReserveId) |
| _SPIRV_OP(group_reserve_read_pipe, GroupReserveReadPipePackets) |
| _SPIRV_OP(group_reserve_write_pipe, GroupReserveWritePipePackets) |
| _SPIRV_OP(group_commit_read_pipe, GroupCommitReadPipe) |
| _SPIRV_OP(group_commit_write_pipe, GroupCommitWritePipe) |
| _SPIRV_OP(get_pipe_num_packets, GetNumPipePackets) |
| _SPIRV_OP(get_pipe_max_packets, GetMaxPipePackets) |
| // CL 2.0 workgroup builtins |
| _SPIRV_OP(group_all, GroupAll) |
| _SPIRV_OP(group_any, GroupAny) |
| _SPIRV_OP(group_broadcast, GroupBroadcast) |
| _SPIRV_OP(group_iadd, GroupIAdd) |
| _SPIRV_OP(group_fadd, GroupFAdd) |
| _SPIRV_OP(group_fmin, GroupFMin) |
| _SPIRV_OP(group_umin, GroupUMin) |
| _SPIRV_OP(group_smin, GroupSMin) |
| _SPIRV_OP(group_fmax, GroupFMax) |
| _SPIRV_OP(group_umax, GroupUMax) |
| _SPIRV_OP(group_smax, GroupSMax) |
| // CL image builtins |
| _SPIRV_OP(SampledImage, SampledImage) |
| _SPIRV_OP(ImageSampleExplicitLod, ImageSampleExplicitLod) |
| _SPIRV_OP(read_image, ImageRead) |
| _SPIRV_OP(write_image, ImageWrite) |
| _SPIRV_OP(get_image_channel_data_type, ImageQueryFormat) |
| _SPIRV_OP(get_image_channel_order, ImageQueryOrder) |
| _SPIRV_OP(get_image_num_mip_levels, ImageQueryLevels) |
| _SPIRV_OP(get_image_num_samples, ImageQuerySamples) |
| #undef _SPIRV_OP |
| } |
| |
| template<> inline void |
| SPIRVMap<std::string, Op, OCLOpaqueType>::init() { |
| add("opencl.event_t", OpTypeEvent); |
| add("opencl.pipe_t", OpTypePipe); |
| add("opencl.clk_event_t", OpTypeDeviceEvent); |
| add("opencl.reserve_id_t", OpTypeReserveId); |
| add("opencl.queue_t", OpTypeQueue); |
| } |
| |
| } // namespace SPIRV |