Skip to content

Commit 3c8ed21

Browse files
[Backport to 16] Support SPV_INTEL_maximum_registers extension (#2344) (#2390)
Spec: KhronosGroup/SPIRV-Registry#235 * Add infrastructure for translating ExecutionModeId (#2297) This functionality was added in SPIR-V 1.2 and allows using an <id> to set the execution modes SubgroupsPerWorkgroupId, LocalSizeId, and LocalSizeHintI, and others. --------- Co-authored-by: Viktoria Maximova <[email protected]>
1 parent 473c348 commit 3c8ed21

14 files changed

+275
-43
lines changed

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ EXT(SPV_INTEL_tensor_float32_rounding)
6464
EXT(SPV_EXT_relaxed_printf_string_address_space)
6565
EXT(SPV_INTEL_fpga_argument_interfaces)
6666
EXT(SPV_INTEL_cache_controls)
67+
EXT(SPV_INTEL_maximum_registers)

lib/SPIRV/SPIRVReader.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4063,6 +4063,48 @@ bool SPIRVToLLVM::transMetadata() {
40634063
F->setMetadata(kSPIR2MD::IntelFPGAIPInterface,
40644064
MDNode::get(*Context, InterfaceMDVec));
40654065
}
4066+
if (auto *EM = BF->getExecutionMode(ExecutionModeMaximumRegistersINTEL)) {
4067+
NamedMDNode *ExecModeMD =
4068+
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);
4069+
4070+
SmallVector<Metadata *, 4> ValueVec;
4071+
ValueVec.push_back(ConstantAsMetadata::get(F));
4072+
ValueVec.push_back(
4073+
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));
4074+
ValueVec.push_back(
4075+
ConstantAsMetadata::get(getUInt32(M, EM->getLiterals()[0])));
4076+
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
4077+
}
4078+
if (auto *EM = BF->getExecutionMode(ExecutionModeMaximumRegistersIdINTEL)) {
4079+
NamedMDNode *ExecModeMD =
4080+
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);
4081+
4082+
SmallVector<Metadata *, 4> ValueVec;
4083+
ValueVec.push_back(ConstantAsMetadata::get(F));
4084+
ValueVec.push_back(
4085+
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));
4086+
4087+
auto *ExecOp = BF->getModule()->getValue(EM->getLiterals()[0]);
4088+
ValueVec.push_back(
4089+
MDNode::get(*Context, ConstantAsMetadata::get(cast<ConstantInt>(
4090+
transValue(ExecOp, nullptr, nullptr)))));
4091+
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
4092+
}
4093+
if (auto *EM =
4094+
BF->getExecutionMode(ExecutionModeNamedMaximumRegistersINTEL)) {
4095+
NamedMDNode *ExecModeMD =
4096+
M->getOrInsertNamedMetadata(kSPIRVMD::ExecutionMode);
4097+
4098+
SmallVector<Metadata *, 4> ValueVec;
4099+
ValueVec.push_back(ConstantAsMetadata::get(F));
4100+
ValueVec.push_back(
4101+
ConstantAsMetadata::get(getUInt32(M, EM->getExecutionMode())));
4102+
4103+
assert(EM->getLiterals()[0] == 0 &&
4104+
"Invalid named maximum number of registers");
4105+
ValueVec.push_back(MDString::get(*Context, "AutoINTEL"));
4106+
ExecModeMD->addOperand(MDNode::get(*Context, ValueVec));
4107+
}
40664108
}
40674109
NamedMDNode *MemoryModelMD =
40684110
M->getOrInsertNamedMetadata(kSPIRVMD::MemoryModel);

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,10 @@ SPIRVFunction *LLVMToSPIRVBase::transFunctionDecl(Function *F) {
901901

902902
transFPGAFunctionMetadata(BF, F);
903903

904-
transFunctionMetadataAsUserSemanticDecoration(BF, F);
904+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_maximum_registers))
905+
transFunctionMetadataAsExecutionMode(BF, F);
906+
else
907+
transFunctionMetadataAsUserSemanticDecoration(BF, F);
905908

906909
transAuxDataInst(BF, F);
907910

@@ -1035,6 +1038,38 @@ void LLVMToSPIRVBase::transFPGAFunctionMetadata(SPIRVFunction *BF,
10351038
transMetadataDecorations(FDecoMD, BF);
10361039
}
10371040

1041+
void LLVMToSPIRVBase::transFunctionMetadataAsExecutionMode(SPIRVFunction *BF,
1042+
Function *F) {
1043+
SmallVector<MDNode *, 1> RegisterAllocModeMDs;
1044+
F->getMetadata("RegisterAllocMode", RegisterAllocModeMDs);
1045+
1046+
for (unsigned I = 0; I < RegisterAllocModeMDs.size(); I++) {
1047+
auto *RegisterAllocMode = RegisterAllocModeMDs[I]->getOperand(0).get();
1048+
if (isa<MDString>(RegisterAllocMode)) {
1049+
StringRef Str = getMDOperandAsString(RegisterAllocModeMDs[I], 0);
1050+
NamedMaximumNumberOfRegisters NamedValue =
1051+
SPIRVNamedMaximumNumberOfRegistersNameMap::rmap(Str.str());
1052+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
1053+
OpExecutionMode, BF, ExecutionModeNamedMaximumRegistersINTEL,
1054+
NamedValue)));
1055+
} else if (isa<MDNode>(RegisterAllocMode)) {
1056+
auto *RegisterAllocNodeMDOp =
1057+
getMDOperandAsMDNode(RegisterAllocModeMDs[I], 0);
1058+
int Num = getMDOperandAsInt(RegisterAllocNodeMDOp, 0);
1059+
auto *Const =
1060+
BM->addConstant(transType(Type::getInt32Ty(F->getContext())), Num);
1061+
BF->addExecutionMode(BM->add(new SPIRVExecutionModeId(
1062+
BF, ExecutionModeMaximumRegistersIdINTEL, Const->getId())));
1063+
} else {
1064+
int64_t RegisterAllocVal =
1065+
mdconst::dyn_extract<ConstantInt>(RegisterAllocMode)->getZExtValue();
1066+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
1067+
OpExecutionMode, BF, ExecutionModeMaximumRegistersINTEL,
1068+
RegisterAllocVal)));
1069+
}
1070+
}
1071+
}
1072+
10381073
void LLVMToSPIRVBase::transFunctionMetadataAsUserSemanticDecoration(
10391074
SPIRVFunction *BF, Function *F) {
10401075
if (auto *RegisterAllocModeMD = F->getMetadata("RegisterAllocMode")) {
@@ -4996,19 +5031,20 @@ bool LLVMToSPIRVBase::transExecutionMode() {
49965031
auto AddSingleArgExecutionMode = [&](ExecutionMode EMode) {
49975032
uint32_t Arg = ~0u;
49985033
N.get(Arg);
4999-
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(BF, EMode, Arg)));
5034+
BF->addExecutionMode(
5035+
BM->add(new SPIRVExecutionMode(OpExecutionMode, BF, EMode, Arg)));
50005036
};
50015037

50025038
switch (EMode) {
50035039
case spv::ExecutionModeContractionOff:
5004-
BF->addExecutionMode(BM->add(
5005-
new SPIRVExecutionMode(BF, static_cast<ExecutionMode>(EMode))));
5040+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
5041+
OpExecutionMode, BF, static_cast<ExecutionMode>(EMode))));
50065042
break;
50075043
case spv::ExecutionModeInitializer:
50085044
case spv::ExecutionModeFinalizer:
50095045
if (BM->isAllowedToUseVersion(VersionNumber::SPIRV_1_1)) {
5010-
BF->addExecutionMode(BM->add(
5011-
new SPIRVExecutionMode(BF, static_cast<ExecutionMode>(EMode))));
5046+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
5047+
OpExecutionMode, BF, static_cast<ExecutionMode>(EMode))));
50125048
} else {
50135049
getErrorLog().checkError(false, SPIRVEC_Requires1_1,
50145050
"Initializer/Finalizer Execution Mode");
@@ -5020,15 +5056,16 @@ bool LLVMToSPIRVBase::transExecutionMode() {
50205056
unsigned X = 0, Y = 0, Z = 0;
50215057
N.get(X).get(Y).get(Z);
50225058
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
5023-
BF, static_cast<ExecutionMode>(EMode), X, Y, Z)));
5059+
OpExecutionMode, BF, static_cast<ExecutionMode>(EMode), X, Y, Z)));
50245060
} break;
50255061
case spv::ExecutionModeMaxWorkgroupSizeINTEL: {
50265062
if (BM->isAllowedToUseExtension(
50275063
ExtensionID::SPV_INTEL_kernel_attributes)) {
50285064
unsigned X = 0, Y = 0, Z = 0;
50295065
N.get(X).get(Y).get(Z);
50305066
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
5031-
BF, static_cast<ExecutionMode>(EMode), X, Y, Z)));
5067+
OpExecutionMode, BF, static_cast<ExecutionMode>(EMode), X, Y,
5068+
Z)));
50325069
BM->addExtension(ExtensionID::SPV_INTEL_kernel_attributes);
50335070
BM->addCapability(CapabilityKernelAttributesINTEL);
50345071
}
@@ -5037,8 +5074,8 @@ bool LLVMToSPIRVBase::transExecutionMode() {
50375074
if (!BM->isAllowedToUseExtension(
50385075
ExtensionID::SPV_INTEL_kernel_attributes))
50395076
break;
5040-
BF->addExecutionMode(BM->add(
5041-
new SPIRVExecutionMode(BF, static_cast<ExecutionMode>(EMode))));
5077+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
5078+
OpExecutionMode, BF, static_cast<ExecutionMode>(EMode))));
50425079
BM->addExtension(ExtensionID::SPV_INTEL_kernel_attributes);
50435080
BM->addCapability(CapabilityKernelAttributesINTEL);
50445081
} break;
@@ -5068,8 +5105,9 @@ bool LLVMToSPIRVBase::transExecutionMode() {
50685105
break;
50695106
unsigned NBarrierCnt = 0;
50705107
N.get(NBarrierCnt);
5071-
BF->addExecutionMode(new SPIRVExecutionMode(
5072-
BF, static_cast<ExecutionMode>(EMode), NBarrierCnt));
5108+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
5109+
OpExecutionMode, BF, static_cast<ExecutionMode>(EMode),
5110+
NBarrierCnt)));
50735111
BM->addExtension(ExtensionID::SPV_INTEL_vector_compute);
50745112
BM->addCapability(CapabilityVectorComputeINTEL);
50755113
} break;
@@ -5099,8 +5137,8 @@ bool LLVMToSPIRVBase::transExecutionMode() {
50995137
} break;
51005138
case spv::internal::ExecutionModeFastCompositeKernelINTEL: {
51015139
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_fast_composite))
5102-
BF->addExecutionMode(BM->add(
5103-
new SPIRVExecutionMode(BF, static_cast<ExecutionMode>(EMode))));
5140+
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
5141+
OpExecutionMode, BF, static_cast<ExecutionMode>(EMode))));
51045142
} break;
51055143
default:
51065144
llvm_unreachable("invalid execution mode");
@@ -5145,8 +5183,8 @@ void LLVMToSPIRVBase::transFPContract() {
51455183
}
51465184

51475185
if (DisableContraction) {
5148-
BF->addExecutionMode(BF->getModule()->add(
5149-
new SPIRVExecutionMode(BF, spv::ExecutionModeContractionOff)));
5186+
BF->addExecutionMode(BF->getModule()->add(new SPIRVExecutionMode(
5187+
OpExecutionMode, BF, spv::ExecutionModeContractionOff)));
51505188
}
51515189
}
51525190
}

lib/SPIRV/SPIRVWriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class LLVMToSPIRVBase : protected BuiltinCallHelper {
123123
void transVectorComputeMetadata(Function *F);
124124
void transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F);
125125
void transAuxDataInst(SPIRVFunction *BF, Function *F);
126+
void transFunctionMetadataAsExecutionMode(SPIRVFunction *BF, Function *F);
126127
void transFunctionMetadataAsUserSemanticDecoration(SPIRVFunction *BF,
127128
Function *F);
128129
bool transGlobalVariables();

lib/SPIRV/libSPIRV/SPIRVEntry.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ SPIRVEntryPoint::SPIRVEntryPoint(SPIRVModule *TheModule,
568568
SPIRVExecutionModelKind TheExecModel,
569569
SPIRVId TheId, const std::string &TheName,
570570
std::vector<SPIRVId> Variables)
571-
: SPIRVAnnotation(TheModule->get<SPIRVFunction>(TheId),
571+
: SPIRVAnnotation(OpEntryPoint, TheModule->get<SPIRVFunction>(TheId),
572572
getSizeInWords(TheName) + Variables.size() + 3),
573573
ExecModel(TheExecModel), Name(TheName), Variables(Variables) {}
574574

@@ -615,6 +615,9 @@ void SPIRVExecutionMode::decode(std::istream &I) {
615615
case ExecutionModeNumSIMDWorkitemsINTEL:
616616
case ExecutionModeSchedulerTargetFmaxMhzINTEL:
617617
case ExecutionModeStreamingInterfaceINTEL:
618+
case ExecutionModeMaximumRegistersINTEL:
619+
case ExecutionModeMaximumRegistersIdINTEL:
620+
case ExecutionModeNamedMaximumRegistersINTEL:
618621
WordLiterals.resize(1);
619622
break;
620623
default:
@@ -636,7 +639,8 @@ SPIRVForward *SPIRVAnnotationGeneric::getOrCreateTarget() const {
636639
}
637640

638641
SPIRVName::SPIRVName(const SPIRVEntry *TheTarget, const std::string &TheStr)
639-
: SPIRVAnnotation(TheTarget, getSizeInWords(TheStr) + 2), Str(TheStr) {}
642+
: SPIRVAnnotation(OpName, TheTarget, getSizeInWords(TheStr) + 2),
643+
Str(TheStr) {}
640644

641645
void SPIRVName::encode(spv_ostream &O) const { getEncoder(O) << Target << Str; }
642646

0 commit comments

Comments
 (0)