Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions lib/SPIRV/PreprocessMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,38 @@ void PreprocessMetadataBase::visit(Module *M) {
if (MDNode *Interface =
Kernel.getMetadata(kSPIR2MD::IntelFPGAIPInterface)) {
std::set<std::string> InterfaceStrSet;
// Default mode is 'csr' aka !ip_interface !N
// !N = !{!”csr”}
// don't emit any particular SPIR-V for it
for (size_t I = 0; I != Interface->getNumOperands(); ++I)
InterfaceStrSet.insert(getMDOperandAsString(Interface, I).str());

// ip_interface metadata will either have Register Map metadata or
// Streaming metadata.
//
// Register Map mode metadata:
// Not 'WaitForDoneWrite' mode (to be mapped on '0' literal)
// !ip_interface !N
// !N = !{!"csr"}
// 'WaitForDoneWrite' mode (to be mapped on '1' literal)
// !ip_interface !N
// !N = !{!"csr", !"wait_for_done_write"}
if (InterfaceStrSet.find("csr") != InterfaceStrSet.end()) {
int32_t InterfaceMode = 0;
if (InterfaceStrSet.find("wait_for_done_write") !=
InterfaceStrSet.end())
InterfaceMode = 1;
EM.addOp()
.add(&Kernel)
.add(spv::ExecutionModeRegisterMapInterfaceINTEL)
.add(InterfaceMode)
.done();
}

// Streaming mode metadata be like:
// Not 'stall free' mode (to be mapped on '0' literal)
// !ip_interface !N
// !N = !{!"streaming"}
// 'stall free' mode (to be mapped on '1' literal)
// !ip_interface !N
// !N = !{!"streaming", !"stall_free_return"}
for (size_t I = 0; I != Interface->getNumOperands(); ++I)
InterfaceStrSet.insert(getMDOperandAsString(Interface, I).str());
if (InterfaceStrSet.find("streaming") != InterfaceStrSet.end()) {
int32_t InterfaceMode = 0;
if (InterfaceStrSet.find("stall_free_return") != InterfaceStrSet.end())
Expand Down Expand Up @@ -324,17 +344,16 @@ void PreprocessMetadataBase::preprocessVectorComputeMetadata(Module *M,
FPRoundingModeExecModeMap::map(getFPRoundingMode(Mode));
spv::ExecutionMode ExecFloatMode =
FPOperationModeExecModeMap::map(getFPOperationMode(Mode));
VCFloatTypeSizeMap::foreach (
[&](VCFloatType FloatType, unsigned TargetWidth) {
EM.addOp().add(&F).add(ExecRoundMode).add(TargetWidth).done();
EM.addOp().add(&F).add(ExecFloatMode).add(TargetWidth).done();
EM.addOp()
.add(&F)
.add(FPDenormModeExecModeMap::map(
getFPDenormMode(Mode, FloatType)))
.add(TargetWidth)
.done();
});
VCFloatTypeSizeMap::foreach ([&](VCFloatType FloatType,
unsigned TargetWidth) {
EM.addOp().add(&F).add(ExecRoundMode).add(TargetWidth).done();
EM.addOp().add(&F).add(ExecFloatMode).add(TargetWidth).done();
EM.addOp()
.add(&F)
.add(FPDenormModeExecModeMap::map(getFPDenormMode(Mode, FloatType)))
.add(TargetWidth)
.done();
});
}
if (Attrs.hasFnAttr(kVCMetadata::VCSLMSize)) {
SPIRVWord SLMSize = 0;
Expand Down
31 changes: 26 additions & 5 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ static void replaceOperandWithAnnotationIntrinsicCallResult(Value *&V) {
template <typename SPIRVInstType>
void SPIRVToLLVM::transAliasingMemAccess(SPIRVInstType *BI, Instruction *I) {
static_assert(std::is_same<SPIRVInstType, SPIRVStore>::value ||
std::is_same<SPIRVInstType, SPIRVLoad>::value,
std::is_same<SPIRVInstType, SPIRVLoad>::value,
"Only stores and loads can be aliased by memory access mask");
if (BI->SPIRVMemoryAccess::isNoAlias())
addMemAliasMetadata(I, BI->SPIRVMemoryAccess::getNoAliasInstID(),
Expand Down Expand Up @@ -2032,10 +2032,10 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,

case 4: {
for (int Idx = 0; Idx < 4; ++Idx) {
Value *V1 = Builder.CreateShuffleVector(
MCache[0], MCache[1], ArrayRef<int>{Idx, Idx + 4});
Value *V2 = Builder.CreateShuffleVector(
MCache[2], MCache[3], ArrayRef<int>{Idx, Idx + 4});
Value *V1 = Builder.CreateShuffleVector(MCache[0], MCache[1],
ArrayRef<int>{Idx, Idx + 4});
Value *V2 = Builder.CreateShuffleVector(MCache[2], MCache[3],
ArrayRef<int>{Idx, Idx + 4});
Value *V3 =
Builder.CreateShuffleVector(V1, V2, ArrayRef<int>{0, 1, 2, 3});
V = Builder.CreateInsertValue(V, V3, Idx);
Expand Down Expand Up @@ -4009,6 +4009,27 @@ bool SPIRVToLLVM::transMetadata() {
F->setMetadata(kSPIR2MD::FmaxMhz,
getMDNodeStringIntVec(Context, EM->getLiterals()));
}
// Generate metadata for Intel FPGA register map interface
if (auto *EM =
BF->getExecutionMode(ExecutionModeRegisterMapInterfaceINTEL)) {
std::vector<uint32_t> InterfaceVec = EM->getLiterals();
assert(InterfaceVec.size() == 1 &&
"Expected RegisterMapInterfaceINTEL to have exactly 1 literal");
std::vector<Metadata *> InterfaceMDVec =
[&]() -> std::vector<Metadata *> {
switch (InterfaceVec[0]) {
case 0:
return {MDString::get(*Context, "csr")};
case 1:
return {MDString::get(*Context, "csr"),
MDString::get(*Context, "wait_for_done_write")};
default:
llvm_unreachable("Invalid register map interface mode");
}
}();
F->setMetadata(kSPIR2MD::IntelFPGAIPInterface,
MDNode::get(*Context, InterfaceMDVec));
}
// Generate metadata for Intel FPGA streaming interface
if (auto *EM = BF->getExecutionMode(ExecutionModeStreamingInterfaceINTEL)) {
std::vector<uint32_t> InterfaceVec = EM->getLiterals();
Expand Down
13 changes: 13 additions & 0 deletions lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4964,6 +4964,19 @@ bool LLVMToSPIRVBase::transExecutionMode() {
case spv::ExecutionModeNumSIMDWorkitemsINTEL:
case spv::ExecutionModeSchedulerTargetFmaxMhzINTEL:
case spv::ExecutionModeMaxWorkDimINTEL:
case spv::ExecutionModeRegisterMapInterfaceINTEL: {
if (!BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_kernel_attributes))
break;
AddSingleArgExecutionMode(static_cast<ExecutionMode>(EMode));
BM->addExtension(ExtensionID::SPV_INTEL_kernel_attributes);
BM->addCapability(CapabilityFPGAKernelAttributesINTEL);
// RegisterMapInterfaceINTEL mode is defined by the
// CapabilityFPGAKernelAttributesv2INTEL capability and that
// capability implicitly defines CapabilityFPGAKernelAttributesINTEL
if (EMode == spv::ExecutionModeRegisterMapInterfaceINTEL)
BM->addCapability(CapabilityFPGAKernelAttributesv2INTEL);
} break;
case spv::ExecutionModeStreamingInterfaceINTEL: {
if (!BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_kernel_attributes))
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/libSPIRV/SPIRVEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,7 @@ void SPIRVExecutionMode::decode(std::istream &I) {
case ExecutionModeMaxWorkDimINTEL:
case ExecutionModeNumSIMDWorkitemsINTEL:
case ExecutionModeSchedulerTargetFmaxMhzINTEL:
case ExecutionModeRegisterMapInterfaceINTEL:
case ExecutionModeStreamingInterfaceINTEL:
WordLiterals.resize(1);
break;
Expand Down
2 changes: 2 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ template <> inline void SPIRVMap<SPIRVExecutionModeKind, SPIRVCapVec>::init() {
{CapabilityVectorComputeINTEL});
ADD_VEC_INIT(internal::ExecutionModeFastCompositeKernelINTEL,
{internal::CapabilityFastCompositeINTEL});
ADD_VEC_INIT(ExecutionModeRegisterMapInterfaceINTEL,
{CapabilityFPGAKernelAttributesv2INTEL});
ADD_VEC_INIT(ExecutionModeStreamingInterfaceINTEL,
{CapabilityFPGAKernelAttributesINTEL});
ADD_VEC_INIT(ExecutionModeNamedBarrierCountINTEL,
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ inline bool isValid(spv::ExecutionModel V) {
case ExecutionModelClosestHitKHR:
case ExecutionModelMissKHR:
case ExecutionModelCallableKHR:
case ExecutionModeRegisterMapInterfaceINTEL:
case ExecutionModeStreamingInterfaceINTEL:
return true;
default:
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
add(CapabilityFPGALoopControlsINTEL, "FPGALoopControlsINTEL");
add(CapabilityKernelAttributesINTEL, "KernelAttributesINTEL");
add(CapabilityFPGAKernelAttributesINTEL, "FPGAKernelAttributesINTEL");
add(CapabilityFPGAKernelAttributesv2INTEL, "FPGAKernelAttributesv2INTEL");
add(CapabilityFPGAMemoryAccessesINTEL, "FPGAMemoryAccessesINTEL");
add(CapabilityFPGAClusterAttributesINTEL, "FPGAClusterAttributesINTEL");
add(CapabilityLoopFuseINTEL, "LoopFuseINTEL");
Expand Down
2 changes: 1 addition & 1 deletion spirv-headers-tag.conf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
36c7694279dfb3ea7e6e086e368bb8bee076792a
295cf5fb3bfe2454360e82b26bae7fc0de699abe
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_kernel_attributes -o %t.spv
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV

; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM

; FPGAKernelAttributesv2INTEL implicitly defines FPGAKernelAttributesINTEL
; CHECK-SPIRV: Capability FPGAKernelAttributesINTEL
; CHECK-SPIRV: Capability FPGAKernelAttributesv2INTEL
; CHECK-SPIRV: Extension "SPV_INTEL_kernel_attributes"
; CHECK-SPIRV: EntryPoint [[#]] [[#KERNEL1:]] "test_1"
; CHECK-SPIRV: EntryPoint [[#]] [[#KERNEL2:]] "test_2"
; CHECK-SPIRV: ExecutionMode [[#KERNEL1]] 6160 0
; CHECK-SPIRV: ExecutionMode [[#KERNEL2]] 6160 1
; CHECK-SPIRV: Function [[#]] [[#KERNEL1]]
; CHECK-SPIRV: Function [[#]] [[#KERNEL2]]

; CHECK-LLVM: define spir_kernel void @test_1{{.*}} !ip_interface ![[#NOWAITFORDONEWRITE:]]
; CHECK-LLVM: define spir_kernel void @test_2{{.*}} !ip_interface ![[#WAITFORDONEWRITE:]]
; CHECK-LLVM: ![[#NOWAITFORDONEWRITE:]] = !{!"csr"}
; CHECK-LLVM: ![[#WAITFORDONEWRITE:]] = !{!"csr", !"wait_for_done_write"}

; ModuleID = 'test.bc'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024"
target triple = "spir64-unknown-unknown"

; Function Attrs: nounwind
define spir_kernel void @test_1() #0 !ip_interface !0
{
entry:
ret void
}

; Function Attrs: nounwind
define spir_kernel void @test_2() #0 !ip_interface !1
{
entry:
ret void
}

attributes #0 = { nounwind }

!0 = !{!"csr"}
!1 = !{!"csr", !"wait_for_done_write"}