Skip to content

Commit

Permalink
Initial support for SPV_INTEL_maximum_registers extension
Browse files Browse the repository at this point in the history
  • Loading branch information
vmaksimo committed Feb 6, 2024
1 parent a31a0a6 commit ad62ef0
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/LLVMSPIRVExtensions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@ EXT(SPV_INTEL_fpga_argument_interfaces)
EXT(SPV_INTEL_fpga_latency_control)
EXT(SPV_INTEL_fp_max_error)
EXT(SPV_INTEL_cache_controls)
EXT(SPV_INTEL_maximum_registers)
15 changes: 15 additions & 0 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4306,6 +4306,21 @@ bool SPIRVToLLVM::transMetadata() {
F->setMetadata(kSPIR2MD::IntelFPGAIPInterface,
MDNode::get(*Context, InterfaceMDVec));
}
// TODO: Also add support for ExecutionModeMaximumRegistersIdINTEL and
// ExecutionModeNamedMaximumRegistersINTEL
if (auto *EM = BF->getExecutionMode(
internal::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));
}
}
NamedMDNode *MemoryModelMD =
M->getOrInsertNamedMetadata(kSPIRVMD::MemoryModel);
Expand Down
27 changes: 26 additions & 1 deletion lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,8 @@ SPIRVFunction *LLVMToSPIRVBase::transFunctionDecl(Function *F) {

transFPGAFunctionMetadata(BF, F);

transFunctionMetadataAsUserSemanticDecoration(BF, F);
// transFunctionMetadataAsUserSemanticDecoration(BF, F);
transFunctionMetadataAsExecutionMode(BF, F);

transAuxDataInst(BF, F);

Expand Down Expand Up @@ -1118,6 +1119,30 @@ void LLVMToSPIRVBase::transFPGAFunctionMetadata(SPIRVFunction *BF,
transMetadataDecorations(FDecoMD, BF);
}

void LLVMToSPIRVBase::transFunctionMetadataAsExecutionMode(SPIRVFunction *BF,
Function *F) {
if (!BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_maximum_registers))
return;

// TODO: Also add support for ExecutionModeMaximumRegistersIdINTEL
if (auto *RegisterAllocModeMD = F->getMetadata("RegisterAllocMode")) {
auto RegisterAllocMode = RegisterAllocModeMD->getOperand(0).get();
if (isa<MDString>(RegisterAllocMode)) {
StringRef Str = getMDOperandAsString(RegisterAllocModeMD, 0);
if (Str == "AutoINTEL")
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
OpExecutionMode, BF,
internal::ExecutionModeNamedMaximumRegistersINTEL, 0)));
} else {
int64_t RegisterAllocNodeMDOp =
mdconst::dyn_extract<ConstantInt>(RegisterAllocMode)->getZExtValue();
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
OpExecutionMode, BF, internal::ExecutionModeMaximumRegistersINTEL,
RegisterAllocNodeMDOp)));
}
}
}

void LLVMToSPIRVBase::transFunctionMetadataAsUserSemanticDecoration(
SPIRVFunction *BF, Function *F) {
if (auto *RegisterAllocModeMD = F->getMetadata("RegisterAllocMode")) {
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class LLVMToSPIRVBase : protected BuiltinCallHelper {
SPIRVFunction *transFunctionDecl(Function *F);
void transVectorComputeMetadata(Function *F);
void transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F);
void transFunctionMetadataAsExecutionMode(SPIRVFunction *BF, Function *F);
void transFunctionMetadataAsUserSemanticDecoration(SPIRVFunction *BF,
Function *F);
void transAuxDataInst(SPIRVFunction *BF, Function *F);
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 @@ -660,6 +660,9 @@ void SPIRVExecutionMode::decode(std::istream &I) {
case ExecutionModeSchedulerTargetFmaxMhzINTEL:
case ExecutionModeRegisterMapInterfaceINTEL:
case ExecutionModeStreamingInterfaceINTEL:
case internal::ExecutionModeMaximumRegistersINTEL:
case internal::ExecutionModeMaximumRegistersIdINTEL:
case internal::ExecutionModeNamedMaximumRegistersINTEL:
WordLiterals.resize(1);
break;
default:
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 @@ -291,6 +291,12 @@ template <> inline void SPIRVMap<SPIRVExecutionModeKind, SPIRVCapVec>::init() {
{CapabilityFPGAKernelAttributesINTEL});
ADD_VEC_INIT(ExecutionModeNamedBarrierCountINTEL,
{CapabilityVectorComputeINTEL});
ADD_VEC_INIT(internal::ExecutionModeMaximumRegistersINTEL,
{internal::CapabilityRegisterLimitsINTEL});
ADD_VEC_INIT(internal::ExecutionModeMaximumRegistersIdINTEL,
{internal::CapabilityRegisterLimitsINTEL});
ADD_VEC_INIT(internal::ExecutionModeNamedMaximumRegistersINTEL,
{internal::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 @@ -73,6 +73,9 @@ inline bool isValid(spv::ExecutionModel V) {
case ExecutionModelCallableKHR:
case ExecutionModeRegisterMapInterfaceINTEL:
case ExecutionModeStreamingInterfaceINTEL:
case internal::ExecutionModeMaximumRegistersINTEL:
case internal::ExecutionModeMaximumRegistersIdINTEL:
case internal::ExecutionModeNamedMaximumRegistersINTEL:
return true;
default:
return false;
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 @@ -668,6 +668,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
"CooperativeMatrixInvocationInstructionsINTEL");
add(internal::CapabilityCooperativeMatrixCheckedInstructionsINTEL,
"CooperativeMatrixCheckedInstructionsINTEL");
add(internal::CapabilityRegisterLimitsINTEL, "RegisterLimitsINTEL");
}
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)

Expand Down
14 changes: 13 additions & 1 deletion lib/SPIRV/libSPIRV/spirv_internal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,17 @@ enum InternalCapability {
ICapabilityJointMatrixBF16ComponentTypeINTEL = 6437,
ICapabilityJointMatrixPackedInt2ComponentTypeINTEL = 6438,
ICapabilityJointMatrixPackedInt4ComponentTypeINTEL = 6439,
ICapabilityCacheControlsINTEL = 6441
ICapabilityCacheControlsINTEL = 6441,
ICapRegisterLimitsINTEL = 6460
};

enum InternalFunctionControlMask { IFunctionControlOptNoneINTELMask = 0x10000 };

enum InternalExecutionMode {
IExecModeFastCompositeKernelINTEL = 6088,
IExecModeMaximumRegistersINTEL = 6461,
IExecModeMaximumRegistersIdINTEL = 6462,
IExecModeNamedMaximumRegistersINTEL = 6463
};

constexpr LinkageType LinkageTypeInternal =
Expand Down Expand Up @@ -289,12 +293,20 @@ constexpr Capability CapabilityBfloat16ConversionINTEL =
static_cast<Capability>(ICapBfloat16ConversionINTEL);
constexpr Capability CapabilityGlobalVariableDecorationsINTEL =
static_cast<Capability>(ICapGlobalVariableDecorationsINTEL);
constexpr Capability CapabilityRegisterLimitsINTEL =
static_cast<Capability>(ICapRegisterLimitsINTEL);

constexpr FunctionControlMask FunctionControlOptNoneINTELMask =
static_cast<FunctionControlMask>(IFunctionControlOptNoneINTELMask);

constexpr ExecutionMode ExecutionModeFastCompositeKernelINTEL =
static_cast<ExecutionMode>(IExecModeFastCompositeKernelINTEL);
constexpr ExecutionMode ExecutionModeMaximumRegistersINTEL =
static_cast<ExecutionMode>(IExecModeMaximumRegistersINTEL);
constexpr ExecutionMode ExecutionModeMaximumRegistersIdINTEL =
static_cast<ExecutionMode>(IExecModeMaximumRegistersIdINTEL);
constexpr ExecutionMode ExecutionModeNamedMaximumRegistersINTEL =
static_cast<ExecutionMode>(IExecModeNamedMaximumRegistersINTEL);

} // namespace internal
} // namespace spv
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
; 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]] 6461 0
; CHECK-SPIRV: ExecutionMode [[#FUNC3]] 6461 3

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

; CHECK-LLVM: !spirv.ExecutionMode = !{![[#FLAG0:]], ![[#FLAG1:]], ![[#FLAG2:]], ![[#FLAG3:]]}
; CHECK-LLVM: ![[#FLAG0]] = !{ptr @main_l3, i32 6461, i32 2}
; CHECK-LLVM: ![[#FLAG1]] = !{ptr @main_l6, i32 6461, i32 1}
; CHECK-LLVM: ![[#FLAG2]] = !{ptr @main_l9, i32 6461, i32 0}
; CHECK-LLVM: ![[#FLAG3]] = !{ptr @main_l13, i32 6461, 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 8, !"PIC Level", i32 2}
!8 = !{i32 7, !"frame-pointer", i32 2}
!9 = !{i32 2, i32 2}
!10 = !{i32 2}
!11 = !{i32 1}
!12 = !{i32 0}
!13 = !{i32 3}
3 changes: 3 additions & 0 deletions test/transcoding/registerallocmode.ll
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
; This test is saved just as a copy of the legacy feature test.
; XFAIL: *

; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv -spirv-text %t.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv %t.bc -o %t.spv
Expand Down

0 comments on commit ad62ef0

Please sign in to comment.