Skip to content

Commit

Permalink
[Backport to 13] Support SPV_INTEL_maximum_registers extension (Khron…
Browse files Browse the repository at this point in the history
  • Loading branch information
vmaksimo authored and KorovinVlad committed Mar 4, 2024
1 parent 1a23c29 commit 9bb0019
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/LLVMSPIRVExtensions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ EXT(SPV_INTEL_tensor_float32_conversion) // TODO: to remove old extension
EXT(SPV_INTEL_tensor_float32_rounding)
EXT(SPV_INTEL_hw_thread_queries)
EXT(SPV_EXT_relaxed_printf_string_address_space)
EXT(SPV_INTEL_maximum_registers)
42 changes: 42 additions & 0 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3732,6 +3732,48 @@ bool SPIRVToLLVM::transMetadata() {
F->setMetadata(kSPIR2MD::FmaxMhz,
getMDNodeStringIntVec(Context, EM->getLiterals()));
}
if (auto *EM = BF->getExecutionMode(ExecutionModeMaximumRegistersINTEL)) {
NamedMDNode *ExecModeMD =
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);

SmallVector<Metadata *, 4> ValueVec;
ValueVec.push_back(ConstantAsMetadata::get(F));
ValueVec.push_back(
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));
ValueVec.push_back(
ConstantAsMetadata::get(getUInt32(M, EM->getLiterals()[0])));
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
}
if (auto *EM = BF->getExecutionMode(ExecutionModeMaximumRegistersIdINTEL)) {
NamedMDNode *ExecModeMD =
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);

SmallVector<Metadata *, 4> ValueVec;
ValueVec.push_back(ConstantAsMetadata::get(F));
ValueVec.push_back(
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));

auto *ExecOp = BF->getModule()->getValue(EM->getLiterals()[0]);
ValueVec.push_back(
MDNode::get(*Context, ConstantAsMetadata::get(cast<ConstantInt>(
transValue(ExecOp, nullptr, nullptr)))));
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
}
if (auto *EM =
BF->getExecutionMode(ExecutionModeNamedMaximumRegistersINTEL)) {
NamedMDNode *ExecModeMD =
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);

SmallVector<Metadata *, 4> ValueVec;
ValueVec.push_back(ConstantAsMetadata::get(F));
ValueVec.push_back(
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));

assert(EM->getLiterals()[0] == 0 &&
"Invalid named maximum number of registers");
ValueVec.push_back(MDString::get(*Context, "AutoINTEL"));
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
}
}
NamedMDNode *MemoryModelMD =
M->getOrInsertNamedMetadata(kSPIRVMD::MemoryModel);
Expand Down
35 changes: 35 additions & 0 deletions lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,9 @@ SPIRVFunction *LLVMToSPIRVBase::transFunctionDecl(Function *F) {

transFPGAFunctionMetadata(BF, F);

if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_maximum_registers))
transFunctionMetadataAsExecutionMode(BF, F);

SPIRVDBG(dbgs() << "[transFunction] " << *F << " => ";
spvdbgs() << *BF << '\n';)
return BF;
Expand Down Expand Up @@ -854,6 +857,38 @@ void LLVMToSPIRVBase::transFPGAFunctionMetadata(SPIRVFunction *BF,
}
}

void LLVMToSPIRVBase::transFunctionMetadataAsExecutionMode(SPIRVFunction *BF,
Function *F) {
SmallVector<MDNode *, 1> RegisterAllocModeMDs;
F->getMetadata("RegisterAllocMode", RegisterAllocModeMDs);

for (unsigned I = 0; I < RegisterAllocModeMDs.size(); I++) {
auto *RegisterAllocMode = RegisterAllocModeMDs[I]->getOperand(0).get();
if (isa<MDString>(RegisterAllocMode)) {
const StringRef Str = getMDOperandAsString(RegisterAllocModeMDs[I], 0);
const NamedMaximumNumberOfRegisters NamedValue =
SPIRVNamedMaximumNumberOfRegistersNameMap::rmap(Str.str());
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
OpExecutionMode, BF, ExecutionModeNamedMaximumRegistersINTEL,
NamedValue)));
} else if (isa<MDNode>(RegisterAllocMode)) {
auto *RegisterAllocNodeMDOp =
getMDOperandAsMDNode(RegisterAllocModeMDs[I], 0);
const int Num = getMDOperandAsInt(RegisterAllocNodeMDOp, 0);
auto *Const =
BM->addConstant(transType(Type::getInt32Ty(F->getContext())), Num);
BF->addExecutionMode(BM->add(new SPIRVExecutionModeId(
BF, ExecutionModeMaximumRegistersIdINTEL, Const->getId())));
} else {
const int64_t RegisterAllocVal =
mdconst::dyn_extract<ConstantInt>(RegisterAllocMode)->getZExtValue();
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
OpExecutionMode, BF, ExecutionModeMaximumRegistersINTEL,
RegisterAllocVal)));
}
}
}

SPIRVValue *LLVMToSPIRVBase::transConstant(Value *V) {
if (auto CPNull = dyn_cast<ConstantPointerNull>(V))
return BM->addNullConstant(
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class LLVMToSPIRVBase {
SPIRVFunction *transFunctionDecl(Function *F);
void transVectorComputeMetadata(Function *F);
void transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F);
void transFunctionMetadataAsExecutionMode(SPIRVFunction *BF, Function *F);
bool transGlobalVariables();

Op transBoolOpCode(SPIRVValue *Opn, Op OC);
Expand Down
3 changes: 3 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,9 @@ void SPIRVExecutionMode::decode(std::istream &I) {
case ExecutionModeMaxWorkDimINTEL:
case ExecutionModeNumSIMDWorkitemsINTEL:
case ExecutionModeSchedulerTargetFmaxMhzINTEL:
case ExecutionModeMaximumRegistersINTEL:
case ExecutionModeMaximumRegistersIdINTEL:
case ExecutionModeNamedMaximumRegistersINTEL:
WordLiterals.resize(1);
break;
default:
Expand Down
19 changes: 18 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRVEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,17 @@ class SPIRVExecutionMode : public SPIRVAnnotation {
}
}

llvm::Optional<ExtensionID> getRequiredExtension() const override {
switch (static_cast<unsigned>(ExecMode)) {
case ExecutionModeMaximumRegistersINTEL:
case ExecutionModeMaximumRegistersIdINTEL:
case ExecutionModeNamedMaximumRegistersINTEL:
return ExtensionID::SPV_INTEL_maximum_registers;
default:
return {};
}
}

protected:
_SPIRV_DCL_ENCDEC
SPIRVExecutionModeKind ExecMode;
Expand Down Expand Up @@ -747,6 +758,11 @@ class SPIRVComponentExecutionModes {
return IsDenorm(EMK) || IsRoundingMode(EMK) || IsFPMode(EMK) ||
IsOtherFP(EMK);
};
auto IsMaxRegisters = [&](auto EMK) {
return EMK == ExecutionModeMaximumRegistersINTEL ||
EMK == ExecutionModeMaximumRegistersIdINTEL ||
EMK == ExecutionModeNamedMaximumRegistersINTEL;
};
auto IsCompatible = [&](SPIRVExecutionMode *EM0, SPIRVExecutionMode *EM1) {
if (EM0->getTargetId() != EM1->getTargetId())
return true;
Expand All @@ -760,7 +776,8 @@ class SPIRVComponentExecutionModes {
return true;
return !(IsDenorm(EMK0) && IsDenorm(EMK1)) &&
!(IsRoundingMode(EMK0) && IsRoundingMode(EMK1)) &&
!(IsFPMode(EMK0) && IsFPMode(EMK1));
!(IsFPMode(EMK0) && IsFPMode(EMK1)) &&
!(IsMaxRegisters(EMK0) && IsMaxRegisters(EMK1));
};
for (auto I = ExecModes.begin(); I != ExecModes.end(); ++I) {
assert(IsCompatible(ExecMode, (*I).second) &&
Expand Down
6 changes: 6 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ template <> inline void SPIRVMap<SPIRVExecutionModeKind, SPIRVCapVec>::init() {
{internal::CapabilityFastCompositeINTEL});
ADD_VEC_INIT(ExecutionModeNamedBarrierCountINTEL,
{CapabilityVectorComputeINTEL});
ADD_VEC_INIT(ExecutionModeMaximumRegistersINTEL,
{CapabilityRegisterLimitsINTEL});
ADD_VEC_INIT(ExecutionModeMaximumRegistersIdINTEL,
{CapabilityRegisterLimitsINTEL});
ADD_VEC_INIT(ExecutionModeNamedMaximumRegistersINTEL,
{CapabilityRegisterLimitsINTEL});
}

template <> inline void SPIRVMap<SPIRVMemoryModelKind, SPIRVCapVec>::init() {
Expand Down
3 changes: 3 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ inline bool isValid(spv::ExecutionModel V) {
case ExecutionModelClosestHitKHR:
case ExecutionModelMissKHR:
case ExecutionModelCallableKHR:
case ExecutionModeMaximumRegistersINTEL:
case ExecutionModeMaximumRegistersIdINTEL:
case ExecutionModeNamedMaximumRegistersINTEL:
return true;
default:
return false;
Expand Down
9 changes: 8 additions & 1 deletion lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
add(CapabilityLongCompositesINTEL, "LongCompositesINTEL");
add(CapabilityAtomicFloat16AddEXT, "AtomicFloat16AddEXT");
add(CapabilityDebugInfoModuleINTEL, "DebugInfoModuleINTEL");

add(CapabilityRegisterLimitsINTEL, "RegisterLimitsINTEL");
// From spirv_internal.hpp
add(internal::CapabilityFPGADSPControlINTEL, "FPGADSPControlINTEL");
add(internal::CapabilityFastCompositeINTEL, "FastCompositeINTEL");
Expand All @@ -590,6 +590,13 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
}
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)

template <>
inline void SPIRVMap<NamedMaximumNumberOfRegisters, std::string>::init() {
add(NamedMaximumNumberOfRegistersAutoINTEL, "AutoINTEL");
}
SPIRV_DEF_NAMEMAP(NamedMaximumNumberOfRegisters,
SPIRVNamedMaximumNumberOfRegistersNameMap);

} /* namespace SPIRV */

#endif // SPIRV_LIBSPIRV_SPIRVNAMEMAPENUM_H
1 change: 1 addition & 0 deletions lib/SPIRV/libSPIRV/SPIRVStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ SPIRV_DEF_ENCDEC(Capability)
SPIRV_DEF_ENCDEC(Decoration)
SPIRV_DEF_ENCDEC(OCLExtOpKind)
SPIRV_DEF_ENCDEC(SPIRVDebugExtOpKind)
SPIRV_DEF_ENCDEC(NamedMaximumNumberOfRegisters)
SPIRV_DEF_ENCDEC(LinkageType)

// Read a string with padded 0's at the end so that they form a stream of
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/libSPIRV/SPIRVStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ SPIRV_DEC_ENCDEC(Capability)
SPIRV_DEC_ENCDEC(Decoration)
SPIRV_DEC_ENCDEC(OCLExtOpKind)
SPIRV_DEC_ENCDEC(SPIRVDebugExtOpKind)
SPIRV_DEC_ENCDEC(NamedMaximumNumberOfRegisters)
SPIRV_DEC_ENCDEC(LinkageType)

const SPIRVEncoder &operator<<(const SPIRVEncoder &O, const std::string &Str);
Expand Down
2 changes: 1 addition & 1 deletion spirv-headers-tag.conf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1c6bb2743599e6eb6f37b2969acc0aef812e32e3
b73e168ca5e123dcf3dea8a34b19a5130f421ae1
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv -spirv-text --spirv-ext=+SPV_INTEL_maximum_registers %t.bc
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_maximum_registers -o %t.spv
; RUN: llvm-spirv -r %t.spv -spirv-target-env=SPV-IR -o - | llvm-dis -o %t.rev.ll
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM

; CHECK-SPIRV: EntryPoint [[#]] [[#FUNC0:]] "main_l3"
; CHECK-SPIRV: EntryPoint [[#]] [[#FUNC1:]] "main_l6"
; CHECK-SPIRV: EntryPoint [[#]] [[#FUNC2:]] "main_l9"
; CHECK-SPIRV: EntryPoint [[#]] [[#FUNC3:]] "main_l13"
; CHECK-SPIRV: EntryPoint [[#]] [[#FUNC4:]] "main_l19"

; CHECK-SPIRV: ExecutionMode [[#FUNC0]] 6461 2
; CHECK-SPIRV: ExecutionMode [[#FUNC1]] 6461 1
; CHECK-SPIRV: ExecutionMode [[#FUNC2]] 6463 0
; CHECK-SPIRV: ExecutionModeId [[#FUNC3]] 6462 [[#Const3:]]
; CHECK-SPIRV: TypeInt [[#TypeInt:]] 32 0
; CHECK-SPIRV: Constant [[#TypeInt]] [[#Const3]] 3

; CHECK-SPIRV-NOT: ExecutionMode [[#FUNC4]]

; CHECK-LLVM: !spirv.ExecutionMode = !{![[#FLAG0:]], ![[#FLAG1:]], ![[#FLAG2:]], ![[#FLAG3:]]}
; CHECK-LLVM: ![[#FLAG0]] = !{void ()* @main_l3, i32 6461, i32 2}
; CHECK-LLVM: ![[#FLAG1]] = !{void ()* @main_l6, i32 6461, i32 1}
; CHECK-LLVM: ![[#FLAG2]] = !{void ()* @main_l9, i32 6463, !"AutoINTEL"}
; CHECK-LLVM: ![[#FLAG3]] = !{void ()* @main_l13, i32 6462, ![[#VAL:]]}
; CHECK-LLVM: ![[#VAL]] = !{i32 3}

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
target triple = "spir64"

; Function Attrs: noinline nounwind optnone
define weak dso_local spir_kernel void @main_l3() #0 !RegisterAllocMode !10 {
newFuncRoot:
ret void
}

; Function Attrs: noinline nounwind optnone
define weak dso_local spir_kernel void @main_l6() #0 !RegisterAllocMode !11 {
newFuncRoot:
ret void
}

; Function Attrs: noinline nounwind optnone
define weak dso_local spir_kernel void @main_l9() #0 !RegisterAllocMode !12 {
newFuncRoot:
ret void
}

; Function Attrs: noinline nounwind optnone
define weak dso_local spir_kernel void @main_l13() #0 !RegisterAllocMode !13 {
newFuncRoot:
ret void
}

; Function Attrs: noinline nounwind optnone
define weak dso_local spir_kernel void @main_l19() #0 {
newFuncRoot:
ret void
}

attributes #0 = { noinline nounwind optnone }


!opencl.compiler.options = !{!0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0}
!spirv.Source = !{!2, !3, !3, !3, !3, !3, !2, !3, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2}
!llvm.module.flags = !{!4, !5, !6, !7, !8}
!spirv.MemoryModel = !{!9, !9, !9, !9, !9, !9}
!spirv.ExecutionMode = !{}

!0 = !{}
!2 = !{i32 4, i32 200000}
!3 = !{i32 3, i32 200000}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 7, !"openmp", i32 50}
!6 = !{i32 7, !"openmp-device", i32 50}
!7 = !{i32 1, !"PIC Level", i32 2}
!8 = !{i32 7, !"frame-pointer", i32 2}
!9 = !{i32 2, i32 2}
!10 = !{i32 2}
!11 = !{i32 1}
!12 = !{!"AutoINTEL"}
!13 = !{!14}
!14 = !{i32 3}

0 comments on commit 9bb0019

Please sign in to comment.