Skip to content

Commit 066bd18

Browse files
committed
[SYCL] Add dummy image generation for virtual functions
1 parent 5d5ec9e commit 066bd18

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; RUN: sycl-post-link -split=auto -properties -S < %s -o %t.table
2+
; RUN: FileCheck %s --input-file=%t.table --check-prefix=CHECK-TABLE
3+
; RUN: FileCheck %s --input-file=%t_0.ll --check-prefix=CHECK-FP64-SPLIT
4+
; RUN: FileCheck %s --input-file=%t_1.ll --check-prefix=CHECK-FP64-DUMMY
5+
; RUN: FileCheck %s --input-file=%t_1.prop --check-prefix=CHECK-FP64-DUMMY-PROPS
6+
; RUN: FileCheck %s --input-file=%t_2.ll --check-prefix=CHECK-FP32-SPLIT
7+
8+
; CHECK-TABLE: _0.prop
9+
; CHECK-TABLE-NEXT: _1.prop
10+
; CHECK-TABLE-NEXT: _2.prop
11+
12+
; CHECK-FP64-SPLIT: define spir_func void @bar()
13+
; CHECK-FP32-SPLIT: define spir_func void @foo()
14+
15+
; CHECK-FP64-DUMMY: define spir_func void @bar()
16+
; CHECK-FP64-DUMMY-NEXT: entry:
17+
; CHECK-FP64-DUMMY-NEXT: ret void
18+
19+
; CHECK-FP64-DUMMY-PROPS: dummy=1
20+
21+
define spir_func void @foo() #1 {
22+
%x = alloca float
23+
ret void
24+
}
25+
26+
define spir_func void @bar() #1 !sycl_used_aspects !1 {
27+
%x = alloca double
28+
%d = load double, ptr %x
29+
%res = fadd double %d, %d
30+
ret void
31+
}
32+
33+
attributes #1 = { "sycl-module-id"="v.cpp" "indirectly-callable"="setA" }
34+
35+
!sycl_aspects = !{!0}
36+
!0 = !{!"fp64", i32 6}
37+
!1 = !{i32 6}

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

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ std::string saveModuleIR(Module &M, int I, StringRef Suff) {
306306

307307
std::string saveModuleProperties(module_split::ModuleDesc &MD,
308308
const GlobalBinImageProps &GlobProps, int I,
309-
StringRef Suff, StringRef Target = "") {
309+
StringRef Suff, StringRef Target = "",
310+
bool IsDummy = false) {
310311
auto PropSet =
311312
computeModuleProperties(MD.getModule(), MD.entries(), GlobProps);
312313

@@ -318,6 +319,10 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD,
318319
NewSuff += Target;
319320
}
320321

322+
if (IsDummy) {
323+
PropSet.add(PropSetRegTy::SYCL_VIRTUAL_FUNCTIONS, "dummy", 1);
324+
}
325+
321326
std::error_code EC;
322327
std::string SCFile = makeResultFileName(".prop", I, NewSuff);
323328
raw_fd_ostream SCOut(SCFile, EC);
@@ -416,7 +421,8 @@ void addTableRow(util::SimpleTable &Table,
416421
// IR component saving is skipped, and this file name is recorded as such in
417422
// the result.
418423
void saveModule(std::vector<std::unique_ptr<util::SimpleTable>> &OutTables,
419-
module_split::ModuleDesc &MD, int I, StringRef IRFilename) {
424+
module_split::ModuleDesc &MD, int I, StringRef IRFilename,
425+
bool IsDummy = false) {
420426
IrPropSymFilenameTriple BaseTriple;
421427
StringRef Suffix = getModuleSuffix(MD);
422428
MD.saveSplitInformationAsMetadata();
@@ -440,8 +446,8 @@ void saveModule(std::vector<std::unique_ptr<util::SimpleTable>> &OutTables,
440446
GlobalBinImageProps Props = {EmitKernelParamInfo, EmitProgramMetadata,
441447
EmitExportedSymbols, EmitImportedSymbols,
442448
DeviceGlobals};
443-
CopyTriple.Prop =
444-
saveModuleProperties(MD, Props, I, Suffix, OutputFile.Target);
449+
CopyTriple.Prop = saveModuleProperties(MD, Props, I, Suffix,
450+
OutputFile.Target, IsDummy);
445451
}
446452
addTableRow(*Table, CopyTriple);
447453
}
@@ -741,6 +747,36 @@ bool isTargetCompatibleWithModule(const std::string &Target,
741747
return true;
742748
}
743749

750+
std::optional<module_split::ModuleDesc>
751+
makeDummy(module_split::ModuleDesc &MD) {
752+
bool hasVirtualFunctions = false;
753+
bool hasOptionalKernelFeatures = false;
754+
for (Function &F : MD.getModule().functions()) {
755+
if (F.hasFnAttribute("indirectly-callable"))
756+
hasVirtualFunctions = true;
757+
if (F.getMetadata("sycl_used_aspects"))
758+
hasOptionalKernelFeatures = true;
759+
if (hasVirtualFunctions && hasOptionalKernelFeatures)
760+
break;
761+
}
762+
if (!hasVirtualFunctions || !hasOptionalKernelFeatures)
763+
return {};
764+
765+
auto MDCopy = MD.clone();
766+
767+
for (Function &F : MDCopy.getModule().functions()) {
768+
if (!F.hasFnAttribute("indirectly-callable"))
769+
continue;
770+
771+
F.erase(F.begin(), F.end());
772+
BasicBlock *newBB = BasicBlock::Create(F.getContext(), "entry", &F);
773+
IRBuilder<> builder(newBB);
774+
builder.CreateRetVoid();
775+
}
776+
777+
return MDCopy;
778+
}
779+
744780
std::vector<std::unique_ptr<util::SimpleTable>>
745781
processInputModule(std::unique_ptr<Module> M) {
746782
// Construct the resulting table which will accumulate all the outputs.
@@ -893,6 +929,16 @@ processInputModule(std::unique_ptr<Module> M) {
893929

894930
++ID;
895931
}
932+
933+
bool dummyEmitted = false;
934+
for (module_split::ModuleDesc &IrMD : MMs) {
935+
if (auto Dummy = makeDummy(IrMD)) {
936+
saveModule(Tables, *Dummy, ID, OutIRFileName, /*IsDummy*/ true);
937+
dummyEmitted = true;
938+
}
939+
}
940+
if (dummyEmitted)
941+
++ID;
896942
}
897943
return Tables;
898944
}

0 commit comments

Comments
 (0)