Skip to content

Commit

Permalink
[SYCL] Use SPIRV-friendly built-in naming scheme
Browse files Browse the repository at this point in the history
This change allows to avoid re-flower pass using.

Signed-off-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
  • Loading branch information
Fznamznon authored and bader committed May 29, 2019
1 parent 7db9ce8 commit a5f2fda
Show file tree
Hide file tree
Showing 17 changed files with 713 additions and 697 deletions.
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ static void buildArgTys(ASTContext &Context, CXXRecordDecl *KernelObj,
assert(InitMethod && "sampler must have __init method");

// sampler __init method has only one parameter
// void __init(__spirv::OpTypeSampler *Sampler)
// void __init(__ocl_sampler_t *Sampler)
auto *FuncDecl = cast<FunctionDecl>(InitMethod);
ParmVarDecl *SamplerArg = FuncDecl->getParamDecl(0);
assert(SamplerArg && "sampler __init method must have sampler parameter");
Expand Down Expand Up @@ -918,7 +918,7 @@ static void populateIntHeader(SYCLIntegrationHeader &H, const StringRef Name,
assert(InitMethod && "sampler must have __init method");

// sampler __init method has only one argument
// void __init(__spirv::OpTypeSampler *Sampler)
// void __init(__ocl_sampler_t *Sampler)
auto *FuncDecl = cast<FunctionDecl>(InitMethod);
ParmVarDecl *SamplerArg = FuncDecl->getParamDecl(0);
assert(SamplerArg && "sampler __init method must have sampler parameter");
Expand Down
150 changes: 81 additions & 69 deletions sycl/include/CL/__spirv/spirv_ops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,52 +12,59 @@
#include <cstdint>
#include <type_traits>

namespace cl {
namespace __spirv {

#ifdef __SYCL_DEVICE_ONLY__

template <typename dataT>
extern OpTypeEvent *
OpGroupAsyncCopy(int32_t Scope, __local dataT *Dest, __global dataT *Src,
size_t NumElements, size_t Stride, OpTypeEvent *E) noexcept;
extern __ocl_event_t __spirv_GroupAsyncCopy(int32_t Scope, __local dataT *Dest,
__global dataT *Src,
size_t NumElements, size_t Stride,
__ocl_event_t E) noexcept;

template <typename dataT>
extern OpTypeEvent *
OpGroupAsyncCopy(int32_t Scope, __global dataT *Dest, __local dataT *Src,
size_t NumElements, size_t Stride, OpTypeEvent *E) noexcept;
extern __ocl_event_t __spirv_GroupAsyncCopy(int32_t Scope, __global dataT *Dest,
__local dataT *Src,
size_t NumElements, size_t Stride,
__ocl_event_t E) noexcept;

#define OpGroupAsyncCopyGlobalToLocal OpGroupAsyncCopy
#define OpGroupAsyncCopyLocalToGlobal OpGroupAsyncCopy
#define OpGroupAsyncCopyGlobalToLocal __spirv_GroupAsyncCopy
#define OpGroupAsyncCopyLocalToGlobal __spirv_GroupAsyncCopy

// Atomic SPIR-V builtins
#define __SPIRV_ATOMIC_LOAD(AS, Type) \
extern Type OpAtomicLoad(AS const Type *P, Scope S, MemorySemantics O);
extern Type __spirv_AtomicLoad(AS const Type *P, Scope S, MemorySemantics O);
#define __SPIRV_ATOMIC_STORE(AS, Type) \
extern void OpAtomicStore(AS Type *P, Scope S, MemorySemantics O, Type V);
extern void __spirv_AtomicStore(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_EXCHANGE(AS, Type) \
extern Type OpAtomicExchange(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicExchange(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_CMP_EXCHANGE(AS, Type) \
extern Type OpAtomicCompareExchange(AS Type *P, Scope S, MemorySemantics E, \
MemorySemantics U, Type V, Type C);
extern Type __spirv_AtomicCompareExchange( \
AS Type *P, Scope S, MemorySemantics E, MemorySemantics U, Type V, \
Type C);
#define __SPIRV_ATOMIC_IADD(AS, Type) \
extern Type OpAtomicIAdd(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicIAdd(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_ISUB(AS, Type) \
extern Type OpAtomicISub(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicISub(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_SMIN(AS, Type) \
extern Type OpAtomicSMin(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicSMin(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_UMIN(AS, Type) \
extern Type OpAtomicUMin(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicUMin(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_SMAX(AS, Type) \
extern Type OpAtomicSMax(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicSMax(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_UMAX(AS, Type) \
extern Type OpAtomicUMax(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicUMax(AS Type *P, Scope S, MemorySemantics O, \
Type V);
#define __SPIRV_ATOMIC_AND(AS, Type) \
extern Type OpAtomicAnd(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicAnd(AS Type *P, Scope S, MemorySemantics O, Type V);
#define __SPIRV_ATOMIC_OR(AS, Type) \
extern Type OpAtomicOr(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicOr(AS Type *P, Scope S, MemorySemantics O, Type V);
#define __SPIRV_ATOMIC_XOR(AS, Type) \
extern Type OpAtomicXor(AS Type *P, Scope S, MemorySemantics O, Type V);
extern Type __spirv_AtomicXor(AS Type *P, Scope S, MemorySemantics O, Type V);

#define __SPIRV_ATOMIC_FLOAT(AS, Type) \
__SPIRV_ATOMIC_LOAD(AS, Type) \
Expand Down Expand Up @@ -87,14 +94,16 @@ OpGroupAsyncCopy(int32_t Scope, __global dataT *Dest, __local dataT *Src,
// of atomic min/max based on the signed-ness of the type
#define __SPIRV_ATOMIC_MINMAX(AS, Op) \
template <typename T> \
typename std::enable_if<std::is_signed<T>::value, T>::type OpAtomic##Op( \
AS T *Ptr, Scope Scope, MemorySemantics Semantics, T Value) { \
return OpAtomicS##Op(Ptr, Scope, Semantics, Value); \
typename std::enable_if<std::is_signed<T>::value, T>::type \
__spirv_Atomic##Op(AS T *Ptr, Scope Scope, MemorySemantics Semantics, \
T Value) { \
return __spirv_AtomicS##Op(Ptr, Scope, Semantics, Value); \
} \
template <typename T> \
typename std::enable_if<!std::is_signed<T>::value, T>::type OpAtomic##Op( \
AS T *Ptr, Scope Scope, MemorySemantics Semantics, T Value) { \
return OpAtomicU##Op(Ptr, Scope, Semantics, Value); \
typename std::enable_if<!std::is_signed<T>::value, T>::type \
__spirv_Atomic##Op(AS T *Ptr, Scope Scope, MemorySemantics Semantics, \
T Value) { \
return __spirv_AtomicU##Op(Ptr, Scope, Semantics, Value); \
}

#define __SPIRV_ATOMICS(macro, Arg) macro(__global, Arg) macro(__local, Arg)
Expand All @@ -109,64 +118,69 @@ __SPIRV_ATOMICS(__SPIRV_ATOMIC_UNSIGNED, unsigned long long)
__SPIRV_ATOMICS(__SPIRV_ATOMIC_MINMAX, Min)
__SPIRV_ATOMICS(__SPIRV_ATOMIC_MINMAX, Max)

extern bool OpGroupAll(int32_t Scope, bool Predicate) noexcept;
extern bool __spirv_GroupAll(int32_t Scope, bool Predicate) noexcept;

extern bool OpGroupAny(int32_t Scope, bool Predicate) noexcept;
extern bool __spirv_GroupAny(int32_t Scope, bool Predicate) noexcept;

template <typename dataT>
extern dataT OpGroupBroadcast(int32_t Scope, dataT Value,
uint32_t LocalId) noexcept;
extern dataT __spirv_GroupBroadcast(int32_t Scope, dataT Value,
uint32_t LocalId) noexcept;

template <typename dataT>
extern dataT OpGroupIAdd(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupIAdd(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpGroupFAdd(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupFAdd(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpGroupUMin(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupUMin(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpGroupSMin(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupSMin(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpGroupFMin(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupFMin(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpGroupUMax(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupUMax(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpGroupSMax(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupSMax(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpGroupFMax(int32_t Scope, int32_t Op, dataT Value) noexcept;
extern dataT __spirv_GroupFMax(int32_t Scope, int32_t Op, dataT Value) noexcept;
template <typename dataT>
extern dataT OpSubgroupShuffleINTEL(dataT Data, uint32_t InvocationId) noexcept;
extern dataT __spirv_SubgroupShuffleINTEL(dataT Data,
uint32_t InvocationId) noexcept;
template <typename dataT>
extern dataT OpSubgroupShuffleDownINTEL(dataT Current, dataT Next,
uint32_t Delta) noexcept;
extern dataT __spirv_SubgroupShuffleDownINTEL(dataT Current, dataT Next,
uint32_t Delta) noexcept;
template <typename dataT>
extern dataT OpSubgroupShuffleUpINTEL(dataT Previous, dataT Current,
uint32_t Delta) noexcept;
extern dataT __spirv_SubgroupShuffleUpINTEL(dataT Previous, dataT Current,
uint32_t Delta) noexcept;
template <typename dataT>
extern dataT OpSubgroupShuffleXorINTEL(dataT Data, uint32_t Value) noexcept;
extern dataT __spirv_SubgroupShuffleXorINTEL(dataT Data,
uint32_t Value) noexcept;

template <typename dataT>
extern dataT OpSubgroupBlockReadINTEL(const __global uint16_t *Ptr) noexcept;
extern dataT
__spirv_SubgroupBlockReadINTEL(const __global uint16_t *Ptr) noexcept;

template <typename dataT>
extern void OpSubgroupBlockWriteINTEL(__global uint16_t *Ptr,
dataT Data) noexcept;
extern void __spirv_SubgroupBlockWriteINTEL(__global uint16_t *Ptr,
dataT Data) noexcept;

template <typename dataT>
extern dataT OpSubgroupBlockReadINTEL(const __global uint32_t *Ptr) noexcept;
extern dataT
__spirv_SubgroupBlockReadINTEL(const __global uint32_t *Ptr) noexcept;

template <typename dataT>
extern void OpSubgroupBlockWriteINTEL(__global uint32_t *Ptr,
dataT Data) noexcept;
extern void __spirv_SubgroupBlockWriteINTEL(__global uint32_t *Ptr,
dataT Data) noexcept;

extern void prefetch(const __global char *Ptr, size_t NumBytes) noexcept;
extern void __spirv_ocl_prefetch(const __global char *Ptr,
size_t NumBytes) noexcept;

#else // if !__SYCL_DEVICE_ONLY__

template <typename dataT>
extern OpTypeEvent *
extern __ocl_event_t
OpGroupAsyncCopyGlobalToLocal(int32_t Scope, dataT *Dest, dataT *Src,
size_t NumElements, size_t Stride,
OpTypeEvent *E) noexcept {
__ocl_event_t E) noexcept {
for (int i = 0; i < NumElements; i++) {
Dest[i] = Src[i * Stride];
}
Expand All @@ -175,28 +189,26 @@ OpGroupAsyncCopyGlobalToLocal(int32_t Scope, dataT *Dest, dataT *Src,
}

template <typename dataT>
extern OpTypeEvent *
extern __ocl_event_t
OpGroupAsyncCopyLocalToGlobal(int32_t Scope, dataT *Dest, dataT *Src,
size_t NumElements, size_t Stride,
OpTypeEvent *E) noexcept {
__ocl_event_t E) noexcept {
for (int i = 0; i < NumElements; i++) {
Dest[i * Stride] = Src[i];
}
// A real instance of the class is not needed, return dummy pointer.
return nullptr;
}

extern void prefetch(const char *Ptr, size_t NumBytes) noexcept;
extern void __spirv_ocl_prefetch(const char *Ptr, size_t NumBytes) noexcept;

#endif // !__SYCL_DEVICE_ONLY__

extern void OpControlBarrier(Scope Execution, Scope Memory,
uint32_t Semantics) noexcept;
extern void __spirv_ControlBarrier(Scope Execution, Scope Memory,
uint32_t Semantics) noexcept;

extern void OpMemoryBarrier(Scope Memory, uint32_t Semantics) noexcept;
extern void __spirv_MemoryBarrier(Scope Memory, uint32_t Semantics) noexcept;

extern void OpGroupWaitEvents(int32_t Scope, uint32_t NumEvents,
OpTypeEvent ** WaitEvents) noexcept;
extern void __spirv_GroupWaitEvents(int32_t Scope, uint32_t NumEvents,
__ocl_event_t *WaitEvents) noexcept;

} // namespace __spirv
} // namespace cl
17 changes: 7 additions & 10 deletions sycl/include/CL/__spirv/spirv_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@

#include <cstdint>

namespace cl {
namespace __spirv {

// TODO: include the header file with SPIR-V declarations from SPIRV-Headers
// project.

enum Scope {
CrossDevice = 0,
Device = 1,
Expand All @@ -23,6 +21,7 @@ enum Scope {
Invocation = 4,
};


enum MemorySemantics {
None = 0x0,
Acquire = 0x2,
Expand All @@ -40,12 +39,10 @@ enum MemorySemantics {
// This class does not have definition, it is only predeclared here.
// The pointers to this class objects can be passed to or returned from
// SPIRV built-in functions.
// Only in such cases the class is recognized as SPIRV type OpTypeEvent.
class OpTypeEvent;

// SPIRV type for sampler class
class OpTypeSampler;
// Only in such cases the class is recognized as SPIRV type __ocl_event_t.
#ifndef __SYCL_DEVICE_ONLY__
typedef void* __ocl_event_t;
typedef void* __ocl_sampler_t;
#endif

enum GroupOperation { Reduce = 0, InclusiveScan = 1, ExclusiveScan = 2 };
} // namespace __spirv
} // namespace cl
35 changes: 15 additions & 20 deletions sycl/include/CL/__spirv/spirv_vars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,19 @@

#ifdef __SYCL_DEVICE_ONLY__

namespace cl {
namespace __spirv {
typedef size_t size_t_vec __attribute__((ext_vector_type(3)));

extern const __constant size_t_vec VarGlobalSize;
extern const __constant size_t_vec VarGlobalInvocationId;
extern const __constant size_t_vec VarWorkgroupSize;
extern const __constant size_t_vec VarLocalInvocationId;
extern const __constant size_t_vec VarWorkgroupId;
extern const __constant size_t_vec VarGlobalOffset;
extern "C" const __constant size_t_vec __spirv_BuiltInGlobalSize;
extern "C" const __constant size_t_vec __spirv_BuiltInGlobalInvocationId;
extern "C" const __constant size_t_vec __spirv_BuiltInWorkgroupSize;
extern "C" const __constant size_t_vec __spirv_BuiltInLocalInvocationId;
extern "C" const __constant size_t_vec __spirv_BuiltInWorkgroupId;
extern "C" const __constant size_t_vec __spirv_BuiltInGlobalOffset;

#define DEFINE_INT_ID_TO_XYZ_CONVERTER(POSTFIX) \
template <int ID> static size_t get##POSTFIX(); \
template <> size_t get##POSTFIX<0>() { return Var##POSTFIX.x; } \
template <> size_t get##POSTFIX<1>() { return Var##POSTFIX.y; } \
template <> size_t get##POSTFIX<2>() { return Var##POSTFIX.z; }
template <> size_t get##POSTFIX<0>() { return __spirv_BuiltIn##POSTFIX.x; } \
template <> size_t get##POSTFIX<1>() { return __spirv_BuiltIn##POSTFIX.y; } \
template <> size_t get##POSTFIX<2>() { return __spirv_BuiltIn##POSTFIX.z; }

DEFINE_INT_ID_TO_XYZ_CONVERTER(GlobalSize);
DEFINE_INT_ID_TO_XYZ_CONVERTER(GlobalInvocationId)
Expand All @@ -36,13 +33,11 @@ DEFINE_INT_ID_TO_XYZ_CONVERTER(GlobalOffset)

#undef DEFINE_INT_ID_TO_XYZ_CONVERTER

extern const __constant uint32_t VarSubgroupSize;
extern const __constant uint32_t VarSubgroupMaxSize;
extern const __constant uint32_t VarNumSubgroups;
extern const __constant uint32_t VarNumEnqueuedSubgroups;
extern const __constant uint32_t VarSubgroupId;
extern const __constant uint32_t VarSubgroupLocalInvocationId;
extern "C" const __constant uint32_t __spirv_BuiltInSubgroupSize;
extern "C" const __constant uint32_t __spirv_BuiltInSubgroupMaxSize;
extern "C" const __constant uint32_t __spirv_BuiltInNumSubgroups;
extern "C" const __constant uint32_t __spirv_BuiltInNumEnqueuedSubgroups;
extern "C" const __constant uint32_t __spirv_BuiltInSubgroupId;
extern "C" const __constant uint32_t __spirv_BuiltInSubgroupLocalInvocationId;

} // namespace __spirv
} // namespace cl
#endif // __SYCL_DEVICE_ONLY__
Loading

0 comments on commit a5f2fda

Please sign in to comment.