Skip to content

Commit

Permalink
Implement OpTypeBufferSurfaceINTEL according to the spec published at:
Browse files Browse the repository at this point in the history
  • Loading branch information
NikitaRudenkoIntel authored and AlexeySachkov committed Sep 9, 2020
1 parent adc3cf9 commit 73dfc6d
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 1 deletion.
17 changes: 17 additions & 0 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,12 @@ SPIRVToLLVM::transOCLPipeStorageTypeName(SPIRV::SPIRVTypePipeStorage *PST) {
kSPIRVTypeName::PipeStorage;
}

std::string SPIRVToLLVM::transVCTypeName(SPIRVTypeBufferSurfaceINTEL *PST) {
if (PST->hasAccessQualifier())
return VectorComputeUtil::getVCBufferSurfaceName(PST->getAccessQualifier());
return VectorComputeUtil::getVCBufferSurfaceName();
}

Type *SPIRVToLLVM::transType(SPIRVType *T, bool IsClassMember) {
auto Loc = TypeMap.find(T);
if (Loc != TypeMap.end())
Expand Down Expand Up @@ -517,6 +523,14 @@ Type *SPIRVToLLVM::transType(SPIRVType *T, bool IsClassMember) {
// OpenCL Compiler does not use this instruction
case OpTypeVmeImageINTEL:
return nullptr;

case OpTypeBufferSurfaceINTEL: {
auto PST = static_cast<SPIRVTypeBufferSurfaceINTEL *>(T);
return mapType(T,
getOrCreateOpaquePtrType(M, transVCTypeName(PST),
SPIRAddressSpace::SPIRAS_Global));
}

default: {
auto OC = T->getOpCode();
if (isOpaqueGenericTypeOpCode(OC) || isSubgroupAvcINTELTypeOpCode(OC)) {
Expand Down Expand Up @@ -3630,6 +3644,9 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
if (F->getCallingConv() != CallingConv::SPIR_KERNEL)
return true;

if (BF->hasDecorate(DecorationVectorComputeFunctionINTEL))
return true;

// Generate metadata for kernel_arg_addr_space
addOCLKernelArgumentMetadata(
Context, SPIR_MD_KERNEL_ARG_ADDR_SPACE, BF, F,
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class SPIRVToLLVM {
std::string transOCLPipeStorageTypeName(SPIRV::SPIRVTypePipeStorage *PST);
std::string transOCLImageTypeAccessQualifier(SPIRV::SPIRVTypeImage *ST);
std::string transOCLPipeTypeAccessQualifier(SPIRV::SPIRVTypePipe *ST);
std::string transVCTypeName(SPIRVTypeBufferSurfaceINTEL *PST);

Value *oclTransConstantSampler(SPIRV::SPIRVConstantSampler *BCS,
BasicBlock *BB);
Expand Down
7 changes: 7 additions & 0 deletions lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,13 @@ SPIRVType *LLVMToSPIRV::transType(Type *T) {
return mapType(T, BM->addQueueType());
}
}
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute)) {
if (STName.startswith(kVCType::VCBufferSurface)) {
// VCBufferSurface always have Access Qualifier
auto Access = getAccessQualifier(STName);
return mapType(T, BM->addBufferSurfaceINTELType(Access));
}
}

if (isPointerToOpaqueStructType(T)) {
return mapType(
Expand Down
9 changes: 9 additions & 0 deletions lib/SPIRV/VectorComputeUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,13 @@ getVCGlobalVarAddressSpace(SPIRVStorageClassKind StorageClass) noexcept {
}
}

std::string getVCBufferSurfaceName() {
return std::string(kVCType::VCBufferSurface) + kAccessQualPostfix::Type;
}

std::string getVCBufferSurfaceName(SPIRVAccessQualifierKind Access) {
return std::string(kVCType::VCBufferSurface) +
getAccessQualifierPostfix(Access).str() + kAccessQualPostfix::Type;
}

} // namespace VectorComputeUtil
7 changes: 7 additions & 0 deletions lib/SPIRV/VectorComputeUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ getVCGlobalVarStorageClass(SPIRAddressSpace AddressSpace) noexcept;
SPIRAddressSpace
getVCGlobalVarAddressSpace(SPIRVStorageClassKind StorageClass) noexcept;

std::string getVCBufferSurfaceName();
std::string getVCBufferSurfaceName(SPIRVAccessQualifierKind Access);

} // namespace VectorComputeUtil

///////////////////////////////////////////////////////////////////////////////
Expand All @@ -107,6 +110,10 @@ const static char VCByteOffset[] = "VCByteOffset";
const static char VCSIMTCall[] = "VCSIMTCall";
} // namespace kVCMetadata

namespace kVCType {
const static char VCBufferSurface[] = "intel.buffer";
}

///////////////////////////////////////////////////////////////////////////////
//
// Map definitions
Expand Down
7 changes: 7 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ class SPIRVModuleImpl : public SPIRVModule {
void createForwardPointers() override;
SPIRVType *addSubgroupAvcINTELType(Op) override;
SPIRVTypeVmeImageINTEL *addVmeImageINTELType(SPIRVTypeImage *T) override;
SPIRVTypeBufferSurfaceINTEL *
addBufferSurfaceINTELType(SPIRVAccessQualifierKind Access) override;

// Constant creation functions
SPIRVInstruction *addBranchInst(SPIRVLabel *, SPIRVBasicBlock *) override;
Expand Down Expand Up @@ -963,6 +965,11 @@ SPIRVModuleImpl::addVmeImageINTELType(SPIRVTypeImage *T) {
return addType(new SPIRVTypeVmeImageINTEL(this, getId(), T));
}

SPIRVTypeBufferSurfaceINTEL *
SPIRVModuleImpl::addBufferSurfaceINTELType(SPIRVAccessQualifierKind Access) {
return addType(new SPIRVTypeBufferSurfaceINTEL(this, getId(), Access));
}

SPIRVType *SPIRVModuleImpl::addSubgroupAvcINTELType(Op TheOpCode) {
return addType(new SPIRVTypeSubgroupAvcINTEL(TheOpCode, this, getId()));
}
Expand Down
3 changes: 3 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class SPIRVInstTemplateBase;
class SPIRVAsmTargetINTEL;
class SPIRVAsmINTEL;
class SPIRVAsmCallINTEL;
class SPIRVTypeBufferSurfaceINTEL;

typedef SPIRVBasicBlock SPIRVLabel;
struct SPIRVTypeImageDescriptor;
Expand Down Expand Up @@ -243,6 +244,8 @@ class SPIRVModule {
virtual SPIRVTypePipe *addPipeType() = 0;
virtual SPIRVType *addSubgroupAvcINTELType(Op) = 0;
virtual SPIRVTypeVmeImageINTEL *addVmeImageINTELType(SPIRVTypeImage *) = 0;
virtual SPIRVTypeBufferSurfaceINTEL *
addBufferSurfaceINTELType(SPIRVAccessQualifierKind Access) = 0;
virtual void createForwardPointers() = 0;

// Constants creation functions
Expand Down
5 changes: 4 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRVOpCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,13 @@ inline bool isSubgroupAvcINTELEvaluateOpcode(Op OpCode) {
OC <= OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL);
}

inline bool isVCOpCode(Op OpCode) { return OpCode == OpTypeBufferSurfaceINTEL; }

inline bool isTypeOpCode(Op OpCode) {
unsigned OC = OpCode;
return (OpTypeVoid <= OC && OC <= OpTypePipe) || OC == OpTypePipeStorage ||
isSubgroupAvcINTELTypeOpCode(OpCode) || OC == OpTypeVmeImageINTEL;
isSubgroupAvcINTELTypeOpCode(OpCode) || OC == OpTypeVmeImageINTEL ||
isVCOpCode(OpCode);
}

inline bool isSpecConstantOpCode(Op OpCode) {
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,3 +515,4 @@ _SPIRV_OP(CrossWorkgroupCastToPtrINTEL, 5938)
_SPIRV_OP(ReadPipeBlockingINTEL, 5946)
_SPIRV_OP(WritePipeBlockingINTEL, 5947)
_SPIRV_OP(FPGARegINTEL, 5949)
_SPIRV_OP(TypeBufferSurfaceINTEL, 6086)
45 changes: 45 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVType.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,51 @@ bool isType(const T1 *Ty, unsigned Bits = 0) {
return static_cast<const T2 *>(Ty)->getBitWidth() == Bits;
}

class SPIRVTypeBufferSurfaceINTEL : public SPIRVType {
public:
const static Op OC = OpTypeBufferSurfaceINTEL;
const static SPIRVWord FixedWC = 2;
SPIRVTypeBufferSurfaceINTEL(SPIRVModule *M, SPIRVId TheId,
SPIRVAccessQualifierKind TheAccess)
: SPIRVType(M, FixedWC + 1, OC, TheId), AccessKind(TheAccess) {
validate();
}
SPIRVTypeBufferSurfaceINTEL(SPIRVModule *M, SPIRVId TheId)
: SPIRVType(M, FixedWC, OC, TheId) {
validate();
}
SPIRVTypeBufferSurfaceINTEL() : SPIRVType(OC) {}

SPIRVCapVec getRequiredCapability() const override {
return getVec(CapabilityVectorComputeINTEL);
}

SPIRVExtSet getRequiredExtensions() const override {
return getSet(ExtensionID::SPV_INTEL_vector_compute);
}

bool hasAccessQualifier() const { return AccessKind.hasValue(); }
SPIRVAccessQualifierKind getAccessQualifier() const {
assert(hasAccessQualifier());
return AccessKind.getValue();
}

protected:
_SPIRV_DEF_ENCDEC2(Id, AccessKind)
void validate() const override {
assert(OpCode == OC);
assert(WordCount == FixedWC + (AccessKind ? 1 : 0));
}
void setWordCount(SPIRVWord TheWC) override {
if (TheWC > FixedWC)
AccessKind = SPIRVAccessQualifierKind::AccessQualifierMax;
WordCount = TheWC;
}

private:
llvm::Optional<SPIRVAccessQualifierKind> AccessKind;
};

// SPV_INTEL_device_side_avc_motion_estimation extension types
class SPIRVTypeVmeImageINTEL : public SPIRVType {
public:
Expand Down
5 changes: 5 additions & 0 deletions lib/SPIRV/libSPIRV/spirv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,7 @@ enum Op {
OpReadPipeBlockingINTEL = 5946,
OpWritePipeBlockingINTEL = 5947,
OpFPGARegINTEL = 5949,
OpTypeBufferSurfaceINTEL = 6086,
OpMax = 0x7fffffff,
};

Expand Down Expand Up @@ -2096,6 +2097,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
case OpTypeBufferSurfaceINTEL:
*hasResult = true;
*hasResultType = false;
break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */
Expand Down
82 changes: 82 additions & 0 deletions test/transcoding/buffer_surface_intel.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_vector_compute --spirv-allow-unknown-intrinsics
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
; RUN: llvm-spirv -r %t.spv -o %t.bc
; RUN: llvm-dis %t.bc -o %t.ll
; RUN: FileCheck %s --input-file %t.spt -check-prefix=SPV
; RUN: FileCheck %s --input-file %t.ll -check-prefix=LLVM

target triple = "spir"

; LLVM-DAG: %intel.buffer_ro_t = type opaque
; LLVM-DAG: %intel.buffer_wo_t = type opaque
; LLVM-DAG: %intel.buffer_rw_t = type opaque
; LLVM-DAG: %opencl.image1d_rw_t = type opaque
; LLVM-DAG: %opencl.image1d_buffer_wo_t = type opaque
; LLVM-DAG: %opencl.image2d_wo_t = type opaque
; LLVM-DAG: %opencl.image3d_ro_t = type opaque
%intel.buffer_ro_t = type opaque
%intel.buffer_wo_t = type opaque
%intel.buffer_rw_t = type opaque
%opencl.image1d_rw_t = type opaque
%opencl.image1d_buffer_wo_t = type opaque
%opencl.image2d_wo_t = type opaque
%opencl.image3d_ro_t = type opaque

; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)*)
; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)*)
; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)*)
; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)*)
; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)*)
; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)*)
; LLVM-DAG: declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)*)

declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)*)
declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)*)
declare i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)*)
declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)*)
declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)*)
declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)*)
declare i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)*)

; SPV-DAG: TypeInt [[INT:[0-9]+]] 32 0
; SPV-DAG: TypeVoid [[VOID:[0-9]+]]
; SPV-DAG: TypeBufferSurfaceINTEL [[BUFRO:[0-9]+]] 0{{(^|[^0-9])}}
; SPV-DAG: TypeBufferSurfaceINTEL [[BUFWO:[0-9]+]] 1{{(^|[^0-9])}}
; SPV-DAG: TypeBufferSurfaceINTEL [[BUFRW:[0-9]+]] 2{{(^|[^0-9])}}
; SPV-DAG: TypeImage [[IMAGE1D_RW:[0-9]+]] {{[0-9]+}} 0 0 0 0 0 0 2
; SPV-DAG: TypeImage [[IMAGE1D_BUF_WO:[0-9]+]] {{[0-9]+}} 5 0 0 0 0 0 1
; SPV-DAG: TypeImage [[IMAGE2D_WO:[0-9]+]] {{[0-9]+}} 1 0 0 0 0 0 1
; SPV-DAG: TypeImage [[IMAGE3D_RO:[0-9]+]] {{[0-9]+}} 2 0 0 0 0 0 0
; SPV-DAG: TypeFunction [[BUFINTR_RO:[0-9]+]] [[INT]] [[BUFRO]]{{(^|[^0-9])}}
; SPV-DAG: TypeFunction [[BUFINTR_WO:[0-9]+]] [[INT]] [[BUFWO]]{{(^|[^0-9])}}
; SPV-DAG: TypeFunction [[BUFINTR_RW:[0-9]+]] [[INT]] [[BUFRW]]{{(^|[^0-9])}}
; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE1D_RW]]{{(^|[^0-9])}}
; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE1D_BUF_WO]]{{(^|[^0-9])}}
; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE2D_WO]]{{(^|[^0-9])}}
; SPV-DAG: TypeFunction {{[0-9]+}} [[INT]] [[IMAGE3D_RO]]{{(^|[^0-9])}}
; SPV-DAG: TypeFunction {{[0-9]+}} [[VOID]] [[BUFRO]] [[BUFWO]] [[BUFRW]] [[IMAGE1D_RW]] [[IMAGE1D_BUF_WO]] [[IMAGE2D_WO]] [[IMAGE3D_RO]]{{(^|[^0-9])}}

; LLVM-DAG: define spir_kernel void @test(%intel.buffer_ro_t addrspace(1)* %buf_ro, %intel.buffer_wo_t addrspace(1)* %buf_wo, %intel.buffer_rw_t addrspace(1)* %buf_rw, %opencl.image1d_rw_t addrspace(1)* %im1d, %opencl.image1d_buffer_wo_t addrspace(1)* %im1db, %opencl.image2d_wo_t addrspace(1)* %im2d, %opencl.image3d_ro_t addrspace(1)* %im3d)
define spir_kernel void @test(%intel.buffer_ro_t addrspace(1)* %buf_ro, %intel.buffer_wo_t addrspace(1)* %buf_wo, %intel.buffer_rw_t addrspace(1)* %buf_rw, %opencl.image1d_rw_t addrspace(1)* %im1d, %opencl.image1d_buffer_wo_t addrspace(1)* %im1db, %opencl.image2d_wo_t addrspace(1)* %im2d, %opencl.image3d_ro_t addrspace(1)* %im3d) #0 {
entry:
; LLVM: %0 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)* %buf_ro)
; LLVM: %1 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)* %buf_wo)
; LLVM: %2 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)* %buf_rw)
; LLVM: %3 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)* %im1d)
; LLVM: %4 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)* %im1db)
; LLVM: %5 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)* %im2d)
; LLVM: %6 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)* %im3d)
; LLVM: ret void
%0 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_ro_t(%intel.buffer_ro_t addrspace(1)* %buf_ro)
%1 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_wo_t(%intel.buffer_wo_t addrspace(1)* %buf_wo)
%2 = call i32 @llvm.some.unknown.intrinsic.i32.p1intel.buffer_rw_t(%intel.buffer_rw_t addrspace(1)* %buf_rw)
%3 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_rw_t(%opencl.image1d_rw_t addrspace(1)* %im1d)
%4 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image1d_buffer_wo_t(%opencl.image1d_buffer_wo_t addrspace(1)* %im1db)
%5 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image2d_wo_t(%opencl.image2d_wo_t addrspace(1)* %im2d)
%6 = call i32 @llvm.some.unknown.intrinsic.i32.p1opencl.image3d_ro_t(%opencl.image3d_ro_t addrspace(1)* %im3d)
ret void
}


attributes #0 = { "VCFunction" }

0 comments on commit 73dfc6d

Please sign in to comment.