Skip to content

Commit 69efb32

Browse files
KorovinVladigcbot
authored andcommitted
Support SPV_INTEL_maximum_registers extension
.
1 parent b0eac28 commit 69efb32

File tree

7 files changed

+205
-13
lines changed

7 files changed

+205
-13
lines changed

IGC/VectorCompiler/include/vc/Utils/GenX/KernelInfo.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SPDX-License-Identifier: MIT
2626
#include "llvm/GenXIntrinsics/GenXMetadata.h"
2727

2828
#include <cstdint>
29+
#include <optional>
2930
#include <type_traits>
3031
#include <unordered_map>
3132

@@ -116,6 +117,14 @@ template <typename Ty = llvm::Value> Ty *getValueAsMetadata(llvm::Metadata *M) {
116117
return nullptr;
117118
}
118119

120+
template <typename Ty = llvm::Value>
121+
Ty *getValueAsMetadata(const llvm::Metadata *M) {
122+
if (auto *VM = llvm::dyn_cast<llvm::ValueAsMetadata>(M))
123+
if (auto *V = llvm::dyn_cast<Ty>(VM->getValue()))
124+
return V;
125+
return nullptr;
126+
}
127+
119128
// Number of barriers can only be 0, 1, 2, 4, 8, 16, 24, 32.
120129
// Alignment here means choosing nearest overlapping legal number of barriers.
121130
static unsigned alignBarrierCnt(unsigned BarrierCnt) {
@@ -178,6 +187,13 @@ class KernelMetadata {
178187
Fixed = 4,
179188
};
180189

190+
// TODO: Use SPIR-V headers.
191+
enum class ExecutionMode {
192+
MaximumRegistersINTEL = 6461,
193+
MaximumRegistersIdINTEL = 6462,
194+
NamedMaximumRegistersINTEL = 6463
195+
};
196+
181197
private:
182198
const llvm::Function *F = nullptr;
183199
llvm::MDNode *ExternalNode = nullptr;
@@ -195,6 +211,9 @@ class KernelMetadata {
195211
std::vector<int> BTIs;
196212
ArgToImplicitLinearization Linearization;
197213

214+
// Optional SPIR-V execution mode.
215+
std::optional<unsigned> GRFSize;
216+
198217
public:
199218
// default constructor
200219
KernelMetadata() {}
@@ -221,6 +240,8 @@ class KernelMetadata {
221240
void updateBTIndicesMD(std::vector<int> &&BTIs);
222241
void updateSLMSizeMD(unsigned Size);
223242

243+
void parseExecutionMode(llvm::MDNode *SpirvExecutionMode);
244+
224245
bool hasArgLinearization(llvm::Argument *Arg) const {
225246
return Linearization.count(Arg);
226247
}
@@ -269,6 +290,8 @@ class KernelMetadata {
269290
return ArgTypeDescs[Idx];
270291
}
271292

293+
std::optional<unsigned> getGRFSize() const { return GRFSize; }
294+
272295
enum { AK_NORMAL, AK_SAMPLER, AK_SURFACE };
273296
RegCategory getArgCategory(unsigned Idx) const {
274297
switch (getArgKind(Idx) & 7) {

IGC/VectorCompiler/lib/GenXCodeGen/GenXCisaBuilder.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -907,10 +907,11 @@ static bool isExtOperandBaled(Use &U, const GenXBaling *Baling) {
907907

908908
// Args:
909909
// HasBarrier - whether kernel has barrier or sbarrier
910-
void addKernelAttrsFromMetadata(VISAKernel &Kernel,
911-
const vc::KernelMetadata &KM,
912-
const GenXSubtarget *Subtarget,
913-
bool HasBarrier) {
910+
static void addKernelAttrsFromMetadata(VISAKernel &Kernel,
911+
const vc::KernelMetadata &KM,
912+
const GenXSubtarget *Subtarget,
913+
const GenXBackendConfig *BC,
914+
bool HasBarrier) {
914915
unsigned SLMSizeInKb = divideCeil(KM.getSLMSize(), 1024);
915916
if (SLMSizeInKb > Subtarget->getMaxSlmSize())
916917
report_fatal_error("SLM size exceeds target limits");
@@ -943,6 +944,21 @@ void addKernelAttrsFromMetadata(VISAKernel &Kernel,
943944
static_cast<uint8_t>(KM.getAlignedBarrierCnt(HasBarrier));
944945
Kernel.AddKernelAttribute("NBarrierCnt", sizeof(BarrierCnt), &BarrierCnt);
945946
}
947+
948+
// Default number of registers.
949+
unsigned NumGRF = 128;
950+
// Set by compile option.
951+
if (BC->isAutoLargeGRFMode())
952+
NumGRF = 0;
953+
if (BC->getGRFSize())
954+
NumGRF = BC->getGRFSize();
955+
// Set by kernel metadata.
956+
if (KM.getGRFSize()) {
957+
unsigned NumGRFPerKernel = *KM.getGRFSize();
958+
if (NumGRFPerKernel == 0 || Subtarget->isValidGRFSize(NumGRFPerKernel))
959+
NumGRF = NumGRFPerKernel;
960+
}
961+
Kernel.AddKernelAttribute("NumGRF", sizeof(NumGRF), &NumGRF);
946962
}
947963

948964
// Legalize name for using as filename or in visa asm
@@ -1001,7 +1017,8 @@ void GenXKernelBuilder::runOnKernel() {
10011017
IGC_ASSERT_MESSAGE(Kernel, "Kernel initialization failed!");
10021018
LLVM_DEBUG(dbgs() << "=== PROCESS KERNEL(" << KernelName << ") ===\n");
10031019

1004-
addKernelAttrsFromMetadata(*Kernel, TheKernelMetadata, Subtarget, HasBarrier);
1020+
addKernelAttrsFromMetadata(*Kernel, TheKernelMetadata, Subtarget,
1021+
BackendConfig, HasBarrier);
10051022

10061023
// Set CM target for all functions produced by VC.
10071024
// See visa spec for CMTarget value (section 4, Kernel).
@@ -5818,13 +5835,6 @@ collectFinalizerArgs(StringSaver &Saver, const GenXSubtarget &ST,
58185835
if (ST.needsWANoMaskFusedEU() && !DisableNoMaskWA)
58195836
addArgument("-noMaskWA");
58205837

5821-
unsigned GRFSize = BC.getGRFSize();
5822-
if (GRFSize > 0) {
5823-
addArgument("-TotalGRFNum");
5824-
addArgument(to_string(GRFSize));
5825-
} else if (BC.isAutoLargeGRFMode())
5826-
addArgument("-autoGRFSelection");
5827-
58285838
if (ST.hasFusedEU()) {
58295839
addArgument("-fusedCallWA");
58305840
addArgument("1");

IGC/VectorCompiler/lib/GenXCodeGen/GenXSubtarget.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ SPDX-License-Identifier: MIT
2727
#include "Probe/Assertion.h"
2828
#include "common/StringMacros.hpp"
2929

30+
#include <unordered_set>
31+
3032
using namespace llvm;
3133

3234
#define DEBUG_TYPE "subtarget"
@@ -274,3 +276,18 @@ bool GenXSubtarget::isInternalIntrinsicSupported(unsigned ID) const {
274276

275277
return true;
276278
}
279+
280+
bool GenXSubtarget::isValidGRFSize(unsigned Size) const {
281+
switch (TargetId) {
282+
case GenXSubtarget::XeHP:
283+
case GenXSubtarget::XeHPG:
284+
case GenXSubtarget::XeLPG:
285+
case GenXSubtarget::XeLPGPlus:
286+
case GenXSubtarget::XeHPC:
287+
case GenXSubtarget::XeHPCVG:
288+
case GenXSubtarget::Xe2:
289+
return Size == 128 || Size == 256;
290+
default:
291+
return Size == 128; // platforms <= TGL
292+
}
293+
}

IGC/VectorCompiler/lib/GenXCodeGen/GenXSubtarget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ class GenXSubtarget final : public GenXGenSubtargetInfo {
457457
PreDefined_Surface stackSurface() const { return StackSurf; }
458458

459459
bool isIntrinsicSupported(unsigned ID) const;
460+
bool isValidGRFSize(unsigned Size) const;
460461
};
461462

462463
} // namespace llvm

IGC/VectorCompiler/lib/Utils/GenX/KernelInfo.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*========================== begin_copyright_notice ============================
22
3-
Copyright (C) 2021-2022 Intel Corporation
3+
Copyright (C) 2021-2024 Intel Corporation
44
55
SPDX-License-Identifier: MIT
66
@@ -47,6 +47,12 @@ static MDNode *findExternalNode(const Function &F) {
4747
genx::KernelMDOp::ArgTypeDescs);
4848
}
4949

50+
static MDNode *findSpirvExecutionModeNode(const Function &F) {
51+
constexpr unsigned FunctionRef = 0;
52+
constexpr unsigned MinNumOps = 3;
53+
return findNode(F, "spirv.ExecutionMode", FunctionRef, MinNumOps);
54+
};
55+
5056
void vc::internal::createInternalMD(Function &F) {
5157
IGC_ASSERT_MESSAGE(!findInternalNode(F),
5258
"Internal node has already been created!");
@@ -104,6 +110,13 @@ static RetTy extractConstantIntMD(const MDOperand &Op) {
104110
return static_cast<RetTy>(V->getZExtValue());
105111
}
106112

113+
template <typename RetTy = unsigned>
114+
static RetTy extractConstantIntMD(const Metadata &Op) {
115+
const auto *V = getValueAsMetadata<ConstantInt>(&Op);
116+
IGC_ASSERT_MESSAGE(V, "Unexpected null value in metadata");
117+
return static_cast<RetTy>(V->getZExtValue());
118+
}
119+
107120
template <typename Cont>
108121
static void extractConstantsFromMDNode(const MDNode *N, Cont &C) {
109122
if (!N)
@@ -247,6 +260,11 @@ vc::KernelMetadata::KernelMetadata(const Function *F) {
247260
}
248261
if (LinearizationNode)
249262
Linearization = extractLinearizationMD(*F, LinearizationNode);
263+
264+
MDNode *SpirvExecutionMode = findSpirvExecutionModeNode(*F);
265+
if (!SpirvExecutionMode)
266+
return;
267+
parseExecutionMode(SpirvExecutionMode);
250268
}
251269

252270
static MDNode *createArgLinearizationMD(const ImplicitLinearizationInfo &Info) {
@@ -339,6 +357,32 @@ void vc::KernelMetadata::updateSLMSizeMD(unsigned Size) {
339357
ValueAsMetadata::get(C));
340358
}
341359

360+
void vc::KernelMetadata::parseExecutionMode(MDNode *SpirvExecutionMode) {
361+
IGC_ASSERT(SpirvExecutionMode->getNumOperands() >= 3);
362+
363+
auto &EMode = SpirvExecutionMode->getOperand(1);
364+
auto &EModeVal = SpirvExecutionMode->getOperand(2);
365+
auto EModeId = static_cast<ExecutionMode>(extractConstantIntMD(EMode));
366+
switch (EModeId) {
367+
case ExecutionMode::MaximumRegistersINTEL:
368+
GRFSize = extractConstantIntMD(*(EModeVal.get()));
369+
return;
370+
case ExecutionMode::MaximumRegistersIdINTEL: {
371+
auto *GRFSizeNode = cast<MDNode>(EModeVal.get());
372+
GRFSize = extractConstantIntMD(*(GRFSizeNode->getOperand(0)));
373+
return;
374+
}
375+
case ExecutionMode::NamedMaximumRegistersINTEL: {
376+
auto *NamedExecMode = cast<MDString>(EModeVal.get());
377+
IGC_ASSERT_EXIT_MESSAGE(!NamedExecMode->getString().compare("AutoINTEL"),
378+
"Unhandled NamedMaximumRegisters value");
379+
GRFSize = 0;
380+
return;
381+
}
382+
}
383+
IGC_ASSERT_EXIT_MESSAGE(0, "Unhandled execution mode!");
384+
}
385+
342386
bool vc::hasKernel(const Module &M) {
343387
NamedMDNode *KernelsMD = M.getNamedMetadata(genx::FunctionMD::GenXKernels);
344388
if (!KernelsMD)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2024 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; COM: This test verifies that spirv.ExecutionMode metadata is not corrupted
10+
; COM: somewhere in VC pipeline.
11+
12+
; RUN: llc %s -march=genx64 -mcpu=Xe2 -vc-skip-ocl-runtime-info -finalizer-opts='-dumpvisa -dumpcommonisa -isaasmToConsole' -o /dev/null | \
13+
; RUN: FileCheck %s
14+
15+
; CHECK: .kernel_attr NumGRF=256
16+
define dllexport spir_kernel void @kernel(i32 %arg) local_unnamed_addr #0 {
17+
ret void
18+
}
19+
20+
attributes #0 = { noinline nounwind "CMGenxMain" }
21+
22+
!genx.kernels = !{!2}
23+
!genx.kernel.internal = !{!3}
24+
!spirv.ExecutionMode = !{!4}
25+
26+
!0 = !{i32 24}
27+
!1 = !{}
28+
!2 = !{void (i32)* @kernel, !"kernel", !0, i32 0, !0, !1, !1, i32 0}
29+
!3 = !{void (i32)* @kernel, null, null, null, null}
30+
!4 = !{void (i32)* @kernel, i32 6461, i32 256}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2024 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; COM: ;;;;;;;;;; RUNNERS ;;;;;;;;;;
10+
11+
; RUN: %opt %use_old_pass_manager% -march=genx64 -mtriple=spir64-unknown-unknown -mcpu=XeHPC \
12+
; RUN: -GenXModule -GenXNumberingWrapper -GenXLiveRangesWrapper -GenXCisaBuilderPass -GenXFinalizer \
13+
; RUN: -disable-verify -finalizer-opts="-dumpcommonisa -isaasmToConsole" < %s | FileCheck %s
14+
15+
; CHECK: .kernel_attr NumGRF=256
16+
define dllexport spir_kernel void @test_256_uint(i32 %arg) #0 {
17+
ret void
18+
}
19+
20+
; CHECK: .kernel_attr NumGRF=256
21+
define dllexport spir_kernel void @test_256_node(i32 %arg) #0 {
22+
ret void
23+
}
24+
25+
; CHECK: .kernel_attr NumGRF=0
26+
define dllexport spir_kernel void @test_auto(i32 %arg) #0 {
27+
ret void
28+
}
29+
30+
; CHECK: .kernel_attr NumGRF=128
31+
define dllexport spir_kernel void @test_default(i32 %arg) #0 {
32+
ret void
33+
}
34+
35+
; CHECK: .kernel_attr NumGRF=128
36+
define dllexport spir_kernel void @test_invalid(i32 %arg) #0 {
37+
ret void
38+
}
39+
40+
attributes #0 = { "CMGenxMain" "VC.Stack.Amount"="0" "target-cpu"="XeHPC" }
41+
42+
!genx.kernels = !{!2, !5, !9, !12, !14}
43+
!genx.kernel.internal = !{!3, !6, !10, !13, !15}
44+
!spirv.ExecutionMode = !{!4, !7, !11, !16}
45+
46+
!0 = !{i32 24}
47+
!1 = !{}
48+
49+
!2 = !{void (i32)* @test_256_uint, !"test_256_uint", !0, i32 0, !0, !1, !1, i32 0}
50+
!3 = !{void (i32)* @test_256_uint, null, null, null, null}
51+
!4 = !{void (i32)* @test_256_uint, i32 6461, i32 256}
52+
53+
!5 = !{void (i32)* @test_256_node, !"test_256_node", !0, i32 0, !0, !1, !1, i32 0}
54+
!6 = !{void (i32)* @test_256_node, null, null, null, null}
55+
!7 = !{void (i32)* @test_256_node, i32 6462, !8}
56+
!8 = !{i32 256}
57+
58+
!9 = !{void (i32)* @test_auto, !"test_auto", !0, i32 0, !0, !1, !1, i32 0}
59+
!10 = !{void (i32)* @test_auto, null, null, null, null}
60+
!11 = !{void (i32)* @test_auto, i32 6463, !"AutoINTEL"}
61+
62+
!12 = !{void (i32)* @test_default, !"test_default", !0, i32 0, !0, !1, !1, i32 0}
63+
!13 = !{void (i32)* @test_default, null, null, null, null}
64+
65+
!14 = !{void (i32)* @test_invalid, !"test_invalid", !0, i32 0, !0, !1, !1, i32 0}
66+
!15 = !{void (i32)* @test_invalid, null, null, null, null}
67+
!16 = !{void (i32)* @test_invalid, i32 6461, i32 200}

0 commit comments

Comments
 (0)