Skip to content

Commit 92ea64b

Browse files
authored
Support SPV_INTEL_maximum_registers extension (#2344)
Spec: KhronosGroup/SPIRV-Registry#235
1 parent 6b3ec41 commit 92ea64b

File tree

13 files changed

+226
-4
lines changed

13 files changed

+226
-4
lines changed

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ EXT(SPV_INTEL_fp_max_error)
7171
EXT(SPV_INTEL_cache_controls)
7272
EXT(SPV_INTEL_subgroup_requirements)
7373
EXT(SPV_INTEL_task_sequence)
74+
EXT(SPV_INTEL_maximum_registers)

lib/SPIRV/SPIRVReader.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4259,6 +4259,50 @@ bool SPIRVToLLVM::transMetadata() {
42594259
F->setMetadata(kSPIR2MD::IntelFPGAIPInterface,
42604260
MDNode::get(*Context, InterfaceMDVec));
42614261
}
4262+
if (auto *EM = BF->getExecutionMode(
4263+
internal::ExecutionModeMaximumRegistersINTEL)) {
4264+
NamedMDNode *ExecModeMD =
4265+
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);
4266+
4267+
SmallVector<Metadata *, 4> ValueVec;
4268+
ValueVec.push_back(ConstantAsMetadata::get(F));
4269+
ValueVec.push_back(
4270+
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));
4271+
ValueVec.push_back(
4272+
ConstantAsMetadata::get(getUInt32(M, EM->getLiterals()[0])));
4273+
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
4274+
}
4275+
if (auto *EM = BF->getExecutionMode(
4276+
internal::ExecutionModeMaximumRegistersIdINTEL)) {
4277+
NamedMDNode *ExecModeMD =
4278+
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);
4279+
4280+
SmallVector<Metadata *, 4> ValueVec;
4281+
ValueVec.push_back(ConstantAsMetadata::get(F));
4282+
ValueVec.push_back(
4283+
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));
4284+
4285+
auto *ExecOp = BF->getModule()->getValue(EM->getLiterals()[0]);
4286+
ValueVec.push_back(
4287+
MDNode::get(*Context, ConstantAsMetadata::get(cast<ConstantInt>(
4288+
transValue(ExecOp, nullptr, nullptr)))));
4289+
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
4290+
}
4291+
if (auto *EM = BF->getExecutionMode(
4292+
internal::ExecutionModeNamedMaximumRegistersINTEL)) {
4293+
NamedMDNode *ExecModeMD =
4294+
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);
4295+
4296+
SmallVector<Metadata *, 4> ValueVec;
4297+
ValueVec.push_back(ConstantAsMetadata::get(F));
4298+
ValueVec.push_back(
4299+
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));
4300+
4301+
assert(EM->getLiterals()[0] == 0 &&
4302+
"Invalid named maximum number of registers");
4303+
ValueVec.push_back(MDString::get(*Context, "AutoINTEL"));
4304+
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
4305+
}
42624306
}
42634307
NamedMDNode *MemoryModelMD =
42644308
M->getOrInsertNamedMetadata(kSPIRVMD::MemoryModel);

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,10 @@ SPIRVFunction *LLVMToSPIRVBase::transFunctionDecl(Function *F) {
979979

980980
transFPGAFunctionMetadata(BF, F);
981981

982-
transFunctionMetadataAsUserSemanticDecoration(BF, F);
982+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_maximum_registers))
983+
transFunctionMetadataAsExecutionMode(BF, F);
984+
else
985+
transFunctionMetadataAsUserSemanticDecoration(BF, F);
983986

984987
transAuxDataInst(BF, F);
985988

@@ -1120,6 +1123,38 @@ void LLVMToSPIRVBase::transFPGAFunctionMetadata(SPIRVFunction *BF,
11201123
transMetadataDecorations(FDecoMD, BF);
11211124
}
11221125

1126+
void LLVMToSPIRVBase::transFunctionMetadataAsExecutionMode(SPIRVFunction *BF,
1127+
Function *F) {
1128+
SmallVector<MDNode *, 1> RegisterAllocModeMDs;
1129+
F->getMetadata("RegisterAllocMode", RegisterAllocModeMDs);
1130+
1131+
for (unsigned I = 0; I < RegisterAllocModeMDs.size(); I++) {
1132+
auto *RegisterAllocMode = RegisterAllocModeMDs[I]->getOperand(0).get();
1133+
if (isa<MDString>(RegisterAllocMode)) {
1134+
StringRef Str = getMDOperandAsString(RegisterAllocModeMDs[I], 0);
1135+
internal::InternalNamedMaximumNumberOfRegisters NamedValue =
1136+
SPIRVNamedMaximumNumberOfRegistersNameMap::rmap(Str.str());
1137+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
1138+
OpExecutionMode, BF,
1139+
internal::ExecutionModeNamedMaximumRegistersINTEL, NamedValue)));
1140+
} else if (isa<MDNode>(RegisterAllocMode)) {
1141+
auto *RegisterAllocNodeMDOp =
1142+
getMDOperandAsMDNode(RegisterAllocModeMDs[I], 0);
1143+
int Num = getMDOperandAsInt(RegisterAllocNodeMDOp, 0);
1144+
auto *Const =
1145+
BM->addConstant(transType(Type::getInt32Ty(F->getContext())), Num);
1146+
BF->addExecutionMode(BM->add(new SPIRVExecutionModeId(
1147+
BF, internal::ExecutionModeMaximumRegistersIdINTEL, Const->getId())));
1148+
} else {
1149+
int64_t RegisterAllocVal =
1150+
mdconst::dyn_extract<ConstantInt>(RegisterAllocMode)->getZExtValue();
1151+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
1152+
OpExecutionMode, BF, internal::ExecutionModeMaximumRegistersINTEL,
1153+
RegisterAllocVal)));
1154+
}
1155+
}
1156+
}
1157+
11231158
void LLVMToSPIRVBase::transFunctionMetadataAsUserSemanticDecoration(
11241159
SPIRVFunction *BF, Function *F) {
11251160
if (auto *RegisterAllocModeMD = F->getMetadata("RegisterAllocMode")) {

lib/SPIRV/SPIRVWriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class LLVMToSPIRVBase : protected BuiltinCallHelper {
131131
SPIRVFunction *transFunctionDecl(Function *F);
132132
void transVectorComputeMetadata(Function *F);
133133
void transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F);
134+
void transFunctionMetadataAsExecutionMode(SPIRVFunction *BF, Function *F);
134135
void transFunctionMetadataAsUserSemanticDecoration(SPIRVFunction *BF,
135136
Function *F);
136137
void transAuxDataInst(SPIRVFunction *BF, Function *F);

lib/SPIRV/libSPIRV/SPIRVEntry.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,9 @@ void SPIRVExecutionMode::decode(std::istream &I) {
661661
case ExecutionModeRegisterMapInterfaceINTEL:
662662
case ExecutionModeStreamingInterfaceINTEL:
663663
case spv::internal::ExecutionModeNamedSubgroupSizeINTEL:
664+
case internal::ExecutionModeMaximumRegistersINTEL:
665+
case internal::ExecutionModeMaximumRegistersIdINTEL:
666+
case internal::ExecutionModeNamedMaximumRegistersINTEL:
664667
WordLiterals.resize(1);
665668
break;
666669
default:

lib/SPIRV/libSPIRV/SPIRVEntry.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,17 @@ class SPIRVExecutionMode : public SPIRVAnnotation {
696696
}
697697
}
698698

699+
std::optional<ExtensionID> getRequiredExtension() const override {
700+
switch (static_cast<unsigned>(ExecMode)) {
701+
case internal::ExecutionModeMaximumRegistersINTEL:
702+
case internal::ExecutionModeMaximumRegistersIdINTEL:
703+
case internal::ExecutionModeNamedMaximumRegistersINTEL:
704+
return ExtensionID::SPV_INTEL_maximum_registers;
705+
default:
706+
return {};
707+
}
708+
}
709+
699710
protected:
700711
_SPIRV_DCL_ENCDEC
701712
SPIRVExecutionModeKind ExecMode;
@@ -757,6 +768,11 @@ class SPIRVComponentExecutionModes {
757768
return IsDenorm(EMK) || IsRoundingMode(EMK) || IsFPMode(EMK) ||
758769
IsOtherFP(EMK);
759770
};
771+
auto IsMaxRegisters = [&](auto EMK) {
772+
return EMK == internal::ExecutionModeMaximumRegistersINTEL ||
773+
EMK == internal::ExecutionModeMaximumRegistersIdINTEL ||
774+
EMK == internal::ExecutionModeNamedMaximumRegistersINTEL;
775+
};
760776
auto IsCompatible = [&](SPIRVExecutionMode *EM0, SPIRVExecutionMode *EM1) {
761777
if (EM0->getTargetId() != EM1->getTargetId())
762778
return true;
@@ -770,7 +786,8 @@ class SPIRVComponentExecutionModes {
770786
return true;
771787
return !(IsDenorm(EMK0) && IsDenorm(EMK1)) &&
772788
!(IsRoundingMode(EMK0) && IsRoundingMode(EMK1)) &&
773-
!(IsFPMode(EMK0) && IsFPMode(EMK1));
789+
!(IsFPMode(EMK0) && IsFPMode(EMK1)) &&
790+
!(IsMaxRegisters(EMK0) && IsMaxRegisters(EMK1));
774791
};
775792
for (auto I = ExecModes.begin(); I != ExecModes.end(); ++I) {
776793
assert(IsCompatible(ExecMode, (*I).second) &&

lib/SPIRV/libSPIRV/SPIRVEnum.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ template <> inline void SPIRVMap<SPIRVExecutionModeKind, SPIRVCapVec>::init() {
293293
{CapabilityVectorComputeINTEL});
294294
ADD_VEC_INIT(internal::ExecutionModeNamedSubgroupSizeINTEL,
295295
{internal::CapabilitySubgroupRequirementsINTEL});
296+
ADD_VEC_INIT(internal::ExecutionModeMaximumRegistersINTEL,
297+
{internal::CapabilityRegisterLimitsINTEL});
298+
ADD_VEC_INIT(internal::ExecutionModeMaximumRegistersIdINTEL,
299+
{internal::CapabilityRegisterLimitsINTEL});
300+
ADD_VEC_INIT(internal::ExecutionModeNamedMaximumRegistersINTEL,
301+
{internal::CapabilityRegisterLimitsINTEL});
296302
}
297303

298304
template <> inline void SPIRVMap<SPIRVMemoryModelKind, SPIRVCapVec>::init() {

lib/SPIRV/libSPIRV/SPIRVIsValidEnum.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ inline bool isValid(spv::ExecutionModel V) {
7373
case ExecutionModelCallableKHR:
7474
case ExecutionModeRegisterMapInterfaceINTEL:
7575
case ExecutionModeStreamingInterfaceINTEL:
76+
case internal::ExecutionModeMaximumRegistersINTEL:
77+
case internal::ExecutionModeMaximumRegistersIdINTEL:
78+
case internal::ExecutionModeNamedMaximumRegistersINTEL:
7679
return true;
7780
default:
7881
return false;

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
672672
add(internal::CapabilitySubgroupRequirementsINTEL,
673673
"SubgroupRequirementsINTEL");
674674
add(internal::CapabilityTaskSequenceINTEL, "TaskSequenceINTEL");
675+
add(internal::CapabilityRegisterLimitsINTEL, "RegisterLimitsINTEL");
675676
}
676677
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
677678

@@ -695,6 +696,14 @@ template <> inline void SPIRVMap<HostAccessQualifier, std::string>::init() {
695696
}
696697
SPIRV_DEF_NAMEMAP(HostAccessQualifier, SPIRVHostAccessQualifierNameMap)
697698

699+
template <>
700+
inline void
701+
SPIRVMap<internal::InternalNamedMaximumNumberOfRegisters, std::string>::init() {
702+
add(internal::NamedMaximumNumberOfRegistersAutoINTEL, "AutoINTEL");
703+
}
704+
SPIRV_DEF_NAMEMAP(internal::InternalNamedMaximumNumberOfRegisters,
705+
SPIRVNamedMaximumNumberOfRegistersNameMap);
706+
698707
} /* namespace SPIRV */
699708

700709
#endif // SPIRV_LIBSPIRV_SPIRVNAMEMAPENUM_H

lib/SPIRV/libSPIRV/SPIRVStream.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ SPIRV_DEF_ENCDEC(SPIRVDebugExtOpKind)
147147
SPIRV_DEF_ENCDEC(NonSemanticAuxDataOpKind)
148148
SPIRV_DEF_ENCDEC(InitializationModeQualifier)
149149
SPIRV_DEF_ENCDEC(HostAccessQualifier)
150+
SPIRV_DEF_ENCDEC(internal::InternalNamedMaximumNumberOfRegisters)
150151
SPIRV_DEF_ENCDEC(LinkageType)
151152

152153
// Read a string with padded 0's at the end so that they form a stream of

0 commit comments

Comments
 (0)