-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[SPIRV] support for extension SPV_INTEL_maximum_registers #137229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-backend-spir-v Author: VISHAKH PRAKASH (VishMCW) ChangesPatch is 22.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137229.diff 11 Files Affected:
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 4389b86745d7f..1ff17b4345679 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -145,4 +145,8 @@ let TargetPrefix = "spv" in {
// FPMaxErrorDecorationINTEL
def int_spv_assign_fpmaxerror_decoration: Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
+
+ // ExecutionModeMaxRedId
+ def int_spv_max_reg_constant : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
+
}
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
index d009244a92259..3ea39506c38c6 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h
@@ -217,6 +217,11 @@ namespace CooperativeMatrixOperands {
#include "SPIRVGenTables.inc"
} // namespace CooperativeMatrixOperands
+namespace NamedMaximumNumberOfRegisters {
+#define GET_NamedMaximumNumberOfRegisters_DECL
+#include "SPIRVGenTables.inc"
+} // namespace NamedMaximumNumberOfRegisters
+
struct ExtendedBuiltin {
StringRef Name;
InstructionSet::InstructionSet Set;
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
index b486132077e3b..bee11a56b10cf 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::SPIRV;
@@ -147,7 +148,24 @@ void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address,
case SPIRV::OpMemberDecorate:
printRemainingVariableOps(MI, NumFixedOps, OS);
break;
- case SPIRV::OpExecutionMode:
+ case SPIRV::OpExecutionMode: {
+ unsigned NumOperands = MI->getNumOperands();
+ if (NumOperands != NumFixedOps) {
+ const unsigned MaxRegVal =
+ MI->getOperand(FirstVariableIndex).getImm();
+ if (MaxRegVal == 0) {
+
+ OS << ' ';
+ printSymbolicOperand<
+ OperandCategory::NamedMaximumNumberOfRegistersOperand>(
+ MI, FirstVariableIndex, OS);
+ break;
+ }
+ }
+ printRemainingVariableOps(MI, NumFixedOps, OS);
+
+
+ } break;
case SPIRV::OpExecutionModeId:
case SPIRV::OpLoopMerge: {
// Print any literals after the OPERAND_UNKNOWN argument normally.
diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index f17c8a8fac14b..365e5ed3c197a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -76,6 +76,9 @@ class SPIRVAsmPrinter : public AsmPrinter {
void outputExecutionModeFromNumthreadsAttribute(
const MCRegister &Reg, const Attribute &Attr,
SPIRV::ExecutionMode::ExecutionMode EM);
+ void outputExecutionModeFromRegisterAllocMode(const MCRegister &Reg,
+ const MDNode *Node,
+ MachineFunction *MF);
void outputExecutionMode(const Module &M);
void outputAnnotations(const Module &M);
void outputModuleSections();
@@ -492,6 +495,45 @@ void SPIRVAsmPrinter::outputExecutionModeFromNumthreadsAttribute(
outputMCInst(Inst);
}
+// outputs the execution mode for the extension SPV_INTEL_maximum_registers
+void SPIRVAsmPrinter::outputExecutionModeFromRegisterAllocMode(
+ const MCRegister &Reg, const MDNode *Node, MachineFunction *MF) {
+ MCInst Inst;
+ auto *RegisterAllocMode = Node->getOperand(0).get();
+ Inst.setOpcode(SPIRV::OpExecutionMode);
+ Inst.addOperand(MCOperand::createReg(Reg));
+
+ if (auto *MDS = dyn_cast<MDString>(RegisterAllocMode)) {
+ StringRef Str = MDS->getString();
+ if (Str.equals_insensitive("AutoINTEL")) {
+ Inst.addOperand(MCOperand::createImm(static_cast<unsigned>(
+ SPIRV::ExecutionMode::NamedMaximumRegistersINTEL)));
+ Inst.addOperand(MCOperand::createImm(static_cast<unsigned>(
+ SPIRV::NamedMaximumNumberOfRegisters::AutoINTEL)));
+ }
+ } else if (MDNode *NestedNode = dyn_cast<MDNode>(RegisterAllocMode)) {
+ if (auto *CMD = dyn_cast<ConstantAsMetadata>(NestedNode->getOperand(0))) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(CMD->getValue())) {
+ Inst.setOpcode(SPIRV::OpExecutionModeId);
+ Inst.addOperand(MCOperand::createImm(
+ SPIRV::ExecutionMode::MaximumRegistersIdINTEL));
+ auto *GR = ST ->getSPIRVGlobalRegistry();
+ Register MaxOpConstantReg = GR ->getMaxRegConstantExtMap(MF);
+ MCRegister MaxRegister = MAI->getRegisterAlias(MF, MaxOpConstantReg);
+ Inst.addOperand(MCOperand::createReg(MaxRegister));
+ }
+ }
+ } else {
+
+ int64_t RegisterAllocVal =
+ mdconst::dyn_extract<ConstantInt>(RegisterAllocMode)->getZExtValue();
+ Inst.addOperand(
+ MCOperand::createImm(SPIRV::ExecutionMode::MaximumRegistersINTEL));
+ Inst.addOperand(MCOperand::createImm(RegisterAllocVal));
+ }
+ outputMCInst(Inst);
+}
+
void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
NamedMDNode *Node = M.getNamedMetadata("spirv.ExecutionMode");
if (Node) {
@@ -532,6 +574,10 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
Inst.addOperand(MCOperand::createImm(TypeCode));
outputMCInst(Inst);
}
+ if (MDNode *Node = F.getMetadata("RegisterAllocMode")) {
+ MachineFunction *MF = MMI->getMachineFunction(F);
+ outputExecutionModeFromRegisterAllocMode(FReg, Node, MF);
+ }
if (ST->isOpenCLEnv() && !M.getNamedMetadata("spirv.ExecutionMode") &&
!M.getNamedMetadata("opencl.enable.FP_CONTRACT")) {
MCInst Inst;
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 56cbd9414c9ee..bf9058886aa98 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -97,7 +97,9 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::
SPV_INTEL_subgroup_matrix_multiply_accumulate},
{"SPV_INTEL_ternary_bitwise_function",
- SPIRV::Extension::Extension::SPV_INTEL_ternary_bitwise_function}};
+ SPIRV::Extension::Extension::SPV_INTEL_ternary_bitwise_function},
+ {"SPV_INTEL_maximum_registers",
+ SPIRV::Extension::SPV_INTEL_maximum_registers}};
bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
StringRef ArgValue,
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 6205dfedb79fb..4777dbb586b08 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -149,6 +149,7 @@ class SPIRVEmitIntrinsics
unsigned OperandToReplace,
IRBuilder<> &B);
void insertPtrCastOrAssignTypeInstr(Instruction *I, IRBuilder<> &B);
+ void insertMaxRegIdExecModeIntrs(Function *F, IRBuilder<> &B);
bool shouldTryToAddMemAliasingDecoration(Instruction *Inst);
void insertSpirvDecorations(Instruction *I, IRBuilder<> &B);
void processGlobalValue(GlobalVariable &GV, IRBuilder<> &B);
@@ -2206,6 +2207,30 @@ void SPIRVEmitIntrinsics::processParamTypesByFunHeader(Function *F,
}
}
+void SPIRVEmitIntrinsics::insertMaxRegIdExecModeIntrs(Function *F,
+ IRBuilder<> &B) {
+ MDNode *Node = F->getMetadata("RegisterAllocMode");
+
+ if (Node) {
+ Metadata *RegisterAllocMode = Node->getOperand(0).get();
+ // spv_max_reg_constant is added to add the OpConstant instruction which
+ // will be then used as operand for OpExecutionMode MaximumRegistersIdINTEL
+ if (MDNode *NestedNode = dyn_cast<MDNode>(RegisterAllocMode)) {
+ if (auto *CMD = dyn_cast<ConstantAsMetadata>(NestedNode->getOperand(0))) {
+ auto *CI = dyn_cast<ConstantInt>(CMD->getValue());
+ if (!CI)
+ return;
+ int32_t MaxRegNumExt = CI->getSExtValue();
+ B.SetInsertPointPastAllocas(F);
+ Value *MaxRegNumExtVal =
+ ConstantInt::get(Type::getInt32Ty(B.getContext()), MaxRegNumExt);
+ B.CreateIntrinsic(Intrinsic::spv_max_reg_constant, {},
+ {MaxRegNumExtVal});
+ }
+ }
+ }
+}
+
void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) {
B.SetInsertPointPastAllocas(F);
for (unsigned OpIdx = 0; OpIdx < F->arg_size(); ++OpIdx) {
@@ -2381,7 +2406,6 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
}
processParamTypesByFunHeader(CurrF, B);
-
// StoreInst's operand type can be changed during the next transformations,
// so we need to store it in the set. Also store already transformed types.
for (auto &I : instructions(Func)) {
@@ -2415,6 +2439,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
insertAssignTypeIntrs(I, B);
insertPtrCastOrAssignTypeInstr(I, B);
insertSpirvDecorations(I, B);
+ insertMaxRegIdExecModeIntrs(CurrF, B);
// if instruction requires a pointee type set, let's check if we know it
// already, and force it to be i8 if not
if (Postpone && !GR->findAssignPtrTypeInstr(I))
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index b05896fb7174c..f3691ff2f0f46 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -68,6 +68,10 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
// Number of bits pointers and size_t integers require.
const unsigned PointerSize;
+ // Maps each MachineFunction to its associated OpConstant register for the
+ // // SPV_INTEL_maximum_registers extension with ExecutionModeId MaximumRegistersIdINTEL.
+ DenseMap<const MachineFunction *, Register> MaxRegConstantExtMap;
+
// Holds the maximum ID we have in the module.
unsigned Bound;
@@ -114,6 +118,15 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
void setBound(unsigned V) { Bound = V; }
unsigned getBound() { return Bound; }
+ void addMaxRegConstantRegisterExt(const MachineFunction *MF, Register Reg) {
+ MaxRegConstantExtMap[MF] = Reg;
+ }
+
+ Register getMaxRegConstantExtMap(const MachineFunction *MF) {
+ assert(MaxRegConstantExtMap.count(MF) &&
+ "MachineFunction not found in MaxRegConstantExtMap");
+ return MaxRegConstantExtMap[MF];
+ }
void addGlobalObject(const Value *V, const MachineFunction *MF, Register R) {
Reg2GO[std::make_pair(MF, R)] = V;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 79f6b43f3aded..6d8602a158ae1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3185,6 +3185,13 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
case Intrinsic::spv_discard: {
return selectDiscard(ResVReg, ResType, I);
}
+ case Intrinsic::spv_max_reg_constant: {
+ int32_t MaxRegNum = I.getOperand(1).getImm();
+ auto ConstMaxRegId = buildI32Constant(MaxRegNum, I);
+ Register MaxIdRegister = ConstMaxRegId.first;
+ GR.addMaxRegConstantRegisterExt(MF, MaxIdRegister);
+ return ConstMaxRegId.second;
+ } break;
default: {
std::string DiagMsg;
raw_string_ostream OS(DiagMsg);
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index a6482d9df2ccb..740e88e41e9b3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1176,6 +1176,50 @@ static bool isImageTypeWithUnknownFormat(SPIRVType *TypeInst) {
return TypeInst->getOperand(7).getImm() == 0;
}
+static void setExtMaxRegId(const MachineFunction *MF,
+ SPIRV::ModuleAnalysisInfo &MAI,
+ SPIRVGlobalRegistry *GR) {
+ Register VirtualReg = GR->getMaxRegConstantExtMap(MF);
+ MCRegister MaxOpConstantReg = MAI.getNextIDRegister();
+ MAI.setRegisterAlias(MF, VirtualReg, MaxOpConstantReg);
+}
+
+static void transFunctionMetadataAsExecutionMode(const Function &F,
+ const SPIRVSubtarget &ST,
+ SPIRV::ModuleAnalysisInfo &MAI,
+ MachineFunction *MF) {
+ SmallVector<MDNode *, 1> RegisterAllocModeMDs;
+ F.getMetadata("RegisterAllocMode", RegisterAllocModeMDs);
+ if (!RegisterAllocModeMDs.empty()) {
+ MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_maximum_registers);
+ MAI.Reqs.addCapability(SPIRV::Capability::RegisterLimitsINTEL);
+ }
+ for (unsigned I = 0; I < RegisterAllocModeMDs.size(); I++) {
+
+ auto *RegisterAllocMode = RegisterAllocModeMDs[I]->getOperand(0).get();
+ if (auto *MDS = dyn_cast<MDString>(RegisterAllocMode)) {
+ MAI.Reqs.getAndAddRequirements(
+ SPIRV::OperandCategory::ExecutionModeOperand,
+ SPIRV::ExecutionMode::NamedMaximumRegistersINTEL, ST);
+ } else if (isa<MDNode>(RegisterAllocMode)) {
+ MDNode *NestedNode = dyn_cast<MDNode>(RegisterAllocMode);
+ if (auto *CMD = dyn_cast<ConstantAsMetadata>(NestedNode->getOperand(0))) {
+ auto *CI = dyn_cast<ConstantInt>(CMD->getValue());
+ if (!CI)
+ break;
+ MAI.Reqs.getAndAddRequirements(
+ SPIRV::OperandCategory::ExecutionModeOperand,
+ SPIRV::ExecutionMode::MaximumRegistersIdINTEL, ST);
+ setExtMaxRegId(MF, MAI, ST.getSPIRVGlobalRegistry());
+ }
+ } else {
+ MAI.Reqs.getAndAddRequirements(
+ SPIRV::OperandCategory::ExecutionModeOperand,
+ SPIRV::ExecutionMode::MaximumRegistersINTEL, ST);
+ }
+ }
+}
+
static void AddDotProductRequirements(const MachineInstr &MI,
SPIRV::RequirementHandler &Reqs,
const SPIRVSubtarget &ST) {
@@ -1921,7 +1965,10 @@ static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
MAI.Reqs.getAndAddRequirements(
SPIRV::OperandCategory::ExecutionModeOperand,
SPIRV::ExecutionMode::VecTypeHint, ST);
-
+ if (F.getMetadata("RegisterAllocMode")) {
+ MachineFunction *MF = MMI->getMachineFunction(F);
+ transFunctionMetadataAsExecutionMode(F, ST, MAI, MF);
+ }
if (F.hasOptNone()) {
if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_optnone);
@@ -2061,7 +2108,6 @@ bool SPIRVModuleAnalysis::runOnModule(Module &M) {
// Process type/const/global var/func decl instructions, number their
// destination registers from 0 to N, collect Extensions and Capabilities.
- collectReqs(M, MAI, MMI, *ST);
collectDeclarations(M);
// Number rest of registers from N+1 onwards.
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index afd3a5206926c..1f10a0fa94a9c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -172,6 +172,8 @@ def KernelProfilingInfoOperand : OperandCategory;
def OpcodeOperand : OperandCategory;
def CooperativeMatrixLayoutOperand : OperandCategory;
def CooperativeMatrixOperandsOperand : OperandCategory;
+def NamedMaximumNumberOfRegistersOperand: OperandCategory;
+
//===----------------------------------------------------------------------===//
// Multiclass used to define Extesions enum values and at the same time
@@ -315,6 +317,7 @@ defm SPV_INTEL_memory_access_aliasing : ExtensionOperand<118>;
defm SPV_INTEL_fp_max_error : ExtensionOperand<119>;
defm SPV_INTEL_ternary_bitwise_function : ExtensionOperand<120>;
defm SPV_INTEL_subgroup_matrix_multiply_accumulate : ExtensionOperand<121>;
+defm SPV_INTEL_maximum_registers : ExtensionOperand<122>;
//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
@@ -517,6 +520,7 @@ defm MemoryAccessAliasingINTEL : CapabilityOperand<5910, 0, 0, [SPV_INTEL_memory
defm FPMaxErrorINTEL : CapabilityOperand<6169, 0, 0, [SPV_INTEL_fp_max_error], []>;
defm TernaryBitwiseFunctionINTEL : CapabilityOperand<6241, 0, 0, [SPV_INTEL_ternary_bitwise_function], []>;
defm SubgroupMatrixMultiplyAccumulateINTEL : CapabilityOperand<6236, 0, 0, [SPV_INTEL_subgroup_matrix_multiply_accumulate], []>;
+defm RegisterLimitsINTEL : CapabilityOperand<6460 , 0, 0, [SPV_INTEL_maximum_registers], []>;
//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
@@ -714,6 +718,9 @@ defm RoundingModeRTPINTEL : ExecutionModeOperand<5620, [RoundToInfinityINTEL]>;
defm RoundingModeRTNINTEL : ExecutionModeOperand<5621, [RoundToInfinityINTEL]>;
defm FloatingPointModeALTINTEL : ExecutionModeOperand<5622, [FloatingPointModeINTEL]>;
defm FloatingPointModeIEEEINTEL : ExecutionModeOperand<5623, [FloatingPointModeINTEL]>;
+defm MaximumRegistersINTEL : ExecutionModeOperand<6461, [RegisterLimitsINTEL]>;
+defm MaximumRegistersIdINTEL : ExecutionModeOperand<6462, [RegisterLimitsINTEL]>;
+defm NamedMaximumRegistersINTEL : ExecutionModeOperand<6463, [RegisterLimitsINTEL]>;
//===----------------------------------------------------------------------===//
// Multiclass used to define StorageClass enum values and at the same time
@@ -1745,3 +1752,28 @@ defm MatrixAAndBTF32ComponentsINTEL : CooperativeMatrixOperandsOperand<0x20, [SP
defm MatrixAAndBBFloat16ComponentsINTEL : CooperativeMatrixOperandsOperand<0x40, [SPV_INTEL_joint_matrix], [CooperativeMatrixBFloat16ComponentTypeINTEL]>;
defm MatrixCBFloat16ComponentsINTEL : CooperativeMatrixOperandsOperand<0x80, [SPV_INTEL_joint_matrix], [CooperativeMatrixBFloat16ComponentTypeINTEL]>;
defm MatrixResultBFloat16ComponentsINTEL : CooperativeMatrixOperandsOperand<0x100, [SPV_INTEL_joint_matrix], [CooperativeMatrixBFloat16ComponentTypeINTEL]>;
+
+//===----------------------------------------------------------------------===//
+// Multiclass used to define Named Max Number of Reg Operands enum values and at the
+// same time SymbolicOperand entries with string mnemonics, extensions and
+// capabilities.
+//===----------------------------------------------------------------------===//
+
+def NamedMaximumNumberOfRegisters : GenericEnum, Operand<i32> {
+ let FilterClass = "NamedMaximumNumberOfRegisters";
+ let NameField = "Name";
+ let ValueField = "Value";
+ let PrintMethod = !strconcat("printSymbolicOperand<OperandCategory::", FilterClass, "Operand>");
+}
+
+class NamedMaximumNumberOfRegisters<string name, bits<32> value> {
+ string Name = name;
+ bits<32> Value = value;
+}
+
+multiclass NamedMaximumNumberOfRegistersOperand<bits<32> value, list<Extension> reqExtensions, list<Capability> reqCapabilities> {
+ def : NamedMaximumNumberOfRegisters<NAME, value>;
+ defm : SymbolicOperandWithRequirements<NamedMaximumNumberOfRegistersOperand, value, NAME, 0, 0, reqExtensions, reqCapabilities>;
+}
+
+defm AutoINTEL : NamedMaximumNumberOfRegistersOperand<0x0, [SPV_INTEL_maximum_registers], [RegisterLimitsINTEL]>;
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_maximum_registers/registerallocmode_maxreg_extension.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_maximum_registers/registerallocmode_maxreg_extension.ll
new file mode 100644
index 0000000000000..b30abf65aaaa1
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_maximum_registers/registerallocmode_maxreg_extension.ll
@@ -0,0 +1,77 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s --spirv-ext=+SPV_INTEL_maximum_registers -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s --spirv-ext=+SP...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! Please fix the formatting issues.
Buildkite CI failed due to a Git lock (.lock file) — looks unrelated to this patch. Could someone please retry the build? @michalpaszkowski |
@@ -532,6 +574,10 @@ void SPIRVAsmPrinter::outputExecutionMode(const Module &M) { | |||
Inst.addOperand(MCOperand::createImm(TypeCode)); | |||
outputMCInst(Inst); | |||
} | |||
if (MDNode *Node = F.getMetadata("RegisterAllocMode")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest not to rely on internal to internal https://github.com/intel/llvm metadata. Instead lets use !spirv.ExecutionMode metadata, see https://github.com/KhronosGroup/SPIRV-LLVM-Translator/blob/main/docs/SPIRVRepresentationInLLVM.rst as 'SPIR-V friendly LLVM IR' is also used in SPIR-V backend.
No description provided.