Skip to content

Commit 675148c

Browse files
[SYCL][NFCI] Unify large-grf splitting with per-aspects split (#7512)
The patch removes standalone splitter we had for `large-grf` and moves `large-grf` handling into per-aspect splitter. The change is intended to be non-functional: at most it may affect the order and names of modules produced by `sycl-post-link`, but not their content.
1 parent 8bc1e87 commit 675148c

File tree

7 files changed

+127
-178
lines changed

7 files changed

+127
-178
lines changed

llvm/test/tools/sycl-post-link/device-code-split/per-aspect-split-2.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
; RUN: FileCheck %s -input-file=%t.table --check-prefix CHECK-TABLE
66
;
77
; RUN: FileCheck %s -input-file=%t_0.sym --check-prefix CHECK-M0-SYMS \
8-
; RUN: --implicit-check-not kernel0 --implicit-check-not kernel1 \
8+
; RUN: --implicit-check-not kernel3 --implicit-check-not kernel1 \
99
; RUN: --implicit-check-not kernel2
1010
;
1111
; RUN: FileCheck %s -input-file=%t_1.sym --check-prefix CHECK-M1-SYMS \
12-
; RUN: --implicit-check-not kernel3 --implicit-check-not kernel1 \
12+
; RUN: --implicit-check-not kernel0 --implicit-check-not kernel1 \
1313
; RUN: --implicit-check-not kernel2
1414
;
1515
; RUN: FileCheck %s -input-file=%t_2.sym --check-prefix CHECK-M2-SYMS \
@@ -21,9 +21,9 @@
2121
; CHECK-TABLE-NEXT: _2.sym
2222
; CHECK-TABLE-EMPTY:
2323

24-
; CHECK-M0-SYMS: kernel3
24+
; CHECK-M0-SYMS: kernel0
2525

26-
; CHECK-M1-SYMS: kernel0
26+
; CHECK-M1-SYMS: kernel3
2727

2828
; CHECK-M2-SYMS: kernel1
2929
; CHECK-M2-SYMS: kernel2

llvm/test/tools/sycl-post-link/device-code-split/per-aspect-split-3.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
; RUN: --implicit-check-not kernel0 --implicit-check-not foo \
1515
; RUN: --implicit-check-not bar
1616
;
17-
; RUN: FileCheck %s -input-file=%t_2.ll --check-prefix CHECK-M2-IR \
17+
; RUN: FileCheck %s -input-file=%t_1.ll --check-prefix CHECK-M1-IR \
1818
; RUN: --implicit-check-not kernel0 --implicit-check-not bar
1919

2020
; We expect to see 3 modules generated:
@@ -49,14 +49,14 @@
4949
; should also present in a separate device image, because it is an entry point
5050
; with unique set of used aspects.
5151
;
52-
; CHECK-M1-SYMS: foo
52+
; CHECK-M1-SYMS: kernel1
5353
;
54-
; CHECK-M2-SYMS: kernel1
54+
; CHECK-M2-SYMS: foo
5555
;
5656
; @kernel1 uses @foo and therefore @foo should be present in the same module as
5757
; @kernel1 as well
58-
; CHECK-M2-IR-DAG: define spir_func void @foo
59-
; CHECK-M2-IR-DAG: define spir_kernel void @kernel1
58+
; CHECK-M1-IR-DAG: define spir_func void @foo
59+
; CHECK-M1-IR-DAG: define spir_kernel void @kernel1
6060

6161

6262
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"

llvm/test/tools/sycl-post-link/sycl-esimd-large-grf.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99

1010
; RUN: sycl-post-link -split=source -symbols -split-esimd -lower-esimd -S %s -o %t.table
1111
; RUN: FileCheck %s -input-file=%t.table
12-
; RUN: FileCheck %s -input-file=%t_esimd_large_grf_0.ll --check-prefixes CHECK-ESIMD-LargeGRF-IR
13-
; RUN: FileCheck %s -input-file=%t_esimd_large_grf_0.prop --check-prefixes CHECK-ESIMD-LargeGRF-PROP
12+
; RUN: FileCheck %s -input-file=%t_esimd_large_grf_1.ll --check-prefixes CHECK-ESIMD-LargeGRF-IR
13+
; RUN: FileCheck %s -input-file=%t_esimd_large_grf_1.prop --check-prefixes CHECK-ESIMD-LargeGRF-PROP
1414
; RUN: FileCheck %s -input-file=%t_0.sym --check-prefixes CHECK-SYCL-SYM
1515
; RUN: FileCheck %s -input-file=%t_esimd_0.sym --check-prefixes CHECK-ESIMD-SYM
16-
; RUN: FileCheck %s -input-file=%t_esimd_large_grf_0.sym --check-prefixes CHECK-ESIMD-LargeGRF-SYM
16+
; RUN: FileCheck %s -input-file=%t_esimd_large_grf_1.sym --check-prefixes CHECK-ESIMD-LargeGRF-SYM
1717

1818
; CHECK: [Code|Properties|Symbols]
19-
; CHECK: {{.*}}esimd_large_grf_0.ll|{{.*}}esimd_large_grf_0.prop|{{.*}}esimd_large_grf_0.sym
2019
; CHECK: {{.*}}_0.ll|{{.*}}_0.prop|{{.*}}_0.sym
2120
; CHECK: {{.*}}esimd_0.ll|{{.*}}esimd_0.prop|{{.*}}esimd_0.sym
21+
; CHECK: {{.*}}esimd_large_grf_1.ll|{{.*}}esimd_large_grf_1.prop|{{.*}}esimd_large_grf_1.sym
2222

2323
; CHECK-ESIMD-LargeGRF-PROP: isEsimdImage=1|1
2424
; CHECK-ESIMD-LargeGRF-PROP: isLargeGRF=1|1

llvm/test/tools/sycl-post-link/sycl-large-grf.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99

1010
; RUN: sycl-post-link -split=source -symbols -split-esimd -lower-esimd -S %s -o %t.table
1111
; RUN: FileCheck %s -input-file=%t.table
12-
; RUN: FileCheck %s -input-file=%t_large_grf_0.ll --check-prefixes CHECK-LARGE-GRF-IR
13-
; RUN: FileCheck %s -input-file=%t_large_grf_0.prop --check-prefixes CHECK-LARGE-GRF-PROP
12+
; RUN: FileCheck %s -input-file=%t_large_grf_1.ll --check-prefixes CHECK-LARGE-GRF-IR
13+
; RUN: FileCheck %s -input-file=%t_large_grf_1.prop --check-prefixes CHECK-LARGE-GRF-PROP
1414
; RUN: FileCheck %s -input-file=%t_0.sym --check-prefixes CHECK-SYCL-SYM
15-
; RUN: FileCheck %s -input-file=%t_large_grf_0.sym --check-prefixes CHECK-LARGE-GRF-SYM
15+
; RUN: FileCheck %s -input-file=%t_large_grf_1.sym --check-prefixes CHECK-LARGE-GRF-SYM
1616

1717
; CHECK: [Code|Properties|Symbols]
18-
; CHECK: {{.*}}_large_grf_0.ll|{{.*}}_large_grf_0.prop|{{.*}}_large_grf_0.sym
1918
; CHECK: {{.*}}_0.ll|{{.*}}_0.prop|{{.*}}_0.sym
19+
; CHECK: {{.*}}_large_grf_1.ll|{{.*}}_large_grf_1.prop|{{.*}}_large_grf_1.sym
2020

2121
; CHECK-LARGE-GRF-PROP: isLargeGRF=1|1
2222

llvm/tools/sycl-post-link/ModuleSplitter.cpp

Lines changed: 26 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -261,42 +261,6 @@ EntryPointGroupVec groupEntryPointsByScope(ModuleDesc &MD,
261261
return EntryPointGroups;
262262
}
263263

264-
template <class EntryPoinGroupFunc>
265-
EntryPointGroupVec
266-
groupEntryPointsByAttribute(ModuleDesc &MD, StringRef AttrName,
267-
bool EmitOnlyKernelsAsEntryPoints,
268-
EntryPoinGroupFunc F) {
269-
EntryPointGroupVec EntryPointGroups{};
270-
std::map<StringRef, EntryPointSet> EntryPointMap;
271-
Module &M = MD.getModule();
272-
273-
// Only process module entry points:
274-
for (auto &F : M.functions()) {
275-
if (!isEntryPoint(F, EmitOnlyKernelsAsEntryPoints) ||
276-
!MD.isEntryPointCandidate(F)) {
277-
continue;
278-
}
279-
if (F.hasFnAttribute(AttrName)) {
280-
EntryPointMap[AttrName].insert(&F);
281-
} else {
282-
EntryPointMap[""].insert(&F);
283-
}
284-
}
285-
if (!EntryPointMap.empty()) {
286-
EntryPointGroups.reserve(EntryPointMap.size());
287-
for (auto &EPG : EntryPointMap) {
288-
EntryPointGroups.emplace_back(EPG.first, std::move(EPG.second),
289-
MD.getEntryPointGroup().Props);
290-
F(EntryPointGroups.back());
291-
}
292-
} else {
293-
// No entry points met, record this.
294-
EntryPointGroups.emplace_back(GLOBAL_SCOPE_NAME, EntryPointSet{});
295-
F(EntryPointGroups.back());
296-
}
297-
return EntryPointGroups;
298-
}
299-
300264
// Represents a call graph between functions in a module. Nodes are functions,
301265
// edges are "calls" relation.
302266
class CallGraph {
@@ -741,33 +705,16 @@ void EntryPointGroup::rebuildFromNames(const std::vector<std::string> &Names,
741705
});
742706
}
743707

744-
std::unique_ptr<ModuleSplitterBase>
745-
getLargeGRFSplitter(ModuleDesc &&MD, bool EmitOnlyKernelsAsEntryPoints) {
746-
EntryPointGroupVec Groups = groupEntryPointsByAttribute(
747-
MD, sycl::kernel_props::ATTR_LARGE_GRF, EmitOnlyKernelsAsEntryPoints,
748-
[](EntryPointGroup &G) {
749-
if (G.GroupId == sycl::kernel_props::ATTR_LARGE_GRF) {
750-
G.Props.UsesLargeGRF = true;
751-
}
752-
});
753-
assert(!Groups.empty() && "At least one group is expected");
754-
assert(Groups.size() <= 2 && "At most 2 groups are expected");
755-
756-
if (Groups.size() > 1)
757-
return std::make_unique<ModuleSplitter>(std::move(MD), std::move(Groups));
758-
else
759-
return std::make_unique<ModuleCopier>(std::move(MD), std::move(Groups));
760-
}
761-
762708
namespace {
763709
// Data structure, which represent a combination of all possible optional
764710
// features used in a function.
765711
//
766712
// It has extra methods to be useable as a key in llvm::DenseMap.
767713
struct UsedOptionalFeatures {
768714
SmallVector<int, 4> Aspects;
769-
// TODO: extend this further with reqd-sub-group-size, reqd-work-group-size,
770-
// large-grf and other properties
715+
bool UsesLargeGRF = false;
716+
// TODO: extend this further with reqd-sub-group-size, reqd-work-group-size
717+
// and other properties
771718

772719
UsedOptionalFeatures() = default;
773720

@@ -785,19 +732,27 @@ struct UsedOptionalFeatures {
785732
llvm::sort(Aspects);
786733
}
787734

735+
if (F->hasFnAttribute(sycl::kernel_props::ATTR_LARGE_GRF))
736+
UsesLargeGRF = true;
737+
788738
llvm::hash_code AspectsHash =
789739
llvm::hash_combine_range(Aspects.begin(), Aspects.end());
790-
Hash = static_cast<unsigned>(llvm::hash_combine(AspectsHash));
740+
llvm::hash_code LargeGRFHash = llvm::hash_value(UsesLargeGRF);
741+
Hash = static_cast<unsigned>(llvm::hash_combine(AspectsHash, LargeGRFHash));
791742
}
792743

793-
std::string getName(StringRef BaseName) const {
744+
std::string generateModuleName(StringRef BaseName) const {
794745
if (Aspects.empty())
795746
return BaseName.str() + "-no-aspects";
796747

797748
std::string Ret = BaseName.str() + "-aspects";
798749
for (int A : Aspects) {
799750
Ret += "-" + std::to_string(A);
800751
}
752+
753+
if (UsesLargeGRF)
754+
Ret += "-large-grf";
755+
801756
return Ret;
802757
}
803758

@@ -833,7 +788,7 @@ struct UsedOptionalFeatures {
833788
return false;
834789
}
835790

836-
return IsEmpty == Other.IsEmpty;
791+
return IsEmpty == Other.IsEmpty && UsesLargeGRF == Other.UsesLargeGRF;
837792
}
838793

839794
unsigned hash() const { return static_cast<unsigned>(Hash); }
@@ -885,9 +840,18 @@ getSplitterByOptionalFeatures(ModuleDesc &&MD,
885840
Groups.emplace_back(GLOBAL_SCOPE_NAME, EntryPointSet{});
886841
} else {
887842
Groups.reserve(PropertiesToFunctionsMap.size());
888-
for (auto &EPG : PropertiesToFunctionsMap) {
889-
Groups.emplace_back(EPG.first.getName(MD.getEntryPointGroup().GroupId),
890-
std::move(EPG.second), MD.getEntryPointGroup().Props);
843+
for (auto &It : PropertiesToFunctionsMap) {
844+
const UsedOptionalFeatures &Features = It.first;
845+
EntryPointSet &EntryPoints = It.second;
846+
847+
// Start with properties of a source module
848+
EntryPointGroup::Properties MDProps = MD.getEntryPointGroup().Props;
849+
// Propagate LargeGRF flag to entry points group
850+
if (Features.UsesLargeGRF)
851+
MDProps.UsesLargeGRF = true;
852+
Groups.emplace_back(
853+
Features.generateModuleName(MD.getEntryPointGroup().GroupId),
854+
std::move(EntryPoints), MDProps);
891855
}
892856
}
893857

llvm/tools/sycl-post-link/ModuleSplitter.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,6 @@ getSplitterByMode(ModuleDesc &&MD, IRSplitMode Mode,
252252
bool AutoSplitIsGlobalScope,
253253
bool EmitOnlyKernelsAsEntryPoints);
254254

255-
std::unique_ptr<ModuleSplitterBase>
256-
getLargeGRFSplitter(ModuleDesc &&MD, bool EmitOnlyKernelsAsEntryPoints);
257-
258255
std::unique_ptr<ModuleSplitterBase>
259256
getSplitterByOptionalFeatures(ModuleDesc &&MD,
260257
bool EmitOnlyKernelsAsEntryPoints);

0 commit comments

Comments
 (0)