Skip to content

Commit 37b339e

Browse files
authored
[SYCL] Update aspect propagation for virtual functions (#15703)
Spec & design: #10540
1 parent f77c81f commit 37b339e

File tree

5 files changed

+171
-1
lines changed

5 files changed

+171
-1
lines changed

llvm/lib/SYCLLowerIR/SYCLPropagateAspectsUsage.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,38 @@ void setSyclFixedTargetsMD(const std::vector<Function *> &EntryPoints,
647647
F->setMetadata("sycl_fixed_targets", MDN);
648648
}
649649

650+
void collectVirtualFunctionSetInfo(
651+
Function &F, StringMap<SmallVector<Function *, 4>> &VirtualFunctionSets) {
652+
if (!F.hasFnAttribute("indirectly-callable"))
653+
return;
654+
Attribute IndirectlyCallableAttr = F.getFnAttribute("indirectly-callable");
655+
StringRef SetName = IndirectlyCallableAttr.getValueAsString();
656+
VirtualFunctionSets[SetName].push_back(&F);
657+
}
658+
659+
// For each set S of virtual functions that F declares,
660+
// propagate S through the CG and then add the aspects
661+
// used by S to F.
662+
void processDeclaredVirtualFunctionSets(
663+
Function *F, CallGraphTy &CG, FunctionToAspectsMapTy &AspectsMap,
664+
SmallPtrSet<const Function *, 16> &Visited,
665+
StringMap<SmallVector<Function *, 4>> &VirtualFunctionSets) {
666+
if (!F->hasFnAttribute("calls-indirectly"))
667+
return;
668+
Attribute CallsIndirectlyAttr = F->getFnAttribute("calls-indirectly");
669+
SmallVector<StringRef, 4> DeclaredVirtualFunctionSetNames;
670+
CallsIndirectlyAttr.getValueAsString().split(DeclaredVirtualFunctionSetNames,
671+
",");
672+
auto &AspectsF = AspectsMap[F];
673+
for (auto Name : DeclaredVirtualFunctionSetNames) {
674+
for (auto VFn : VirtualFunctionSets[Name]) {
675+
propagateAspectsThroughCG(VFn, CG, AspectsMap, Visited);
676+
for (auto Aspect : AspectsMap[VFn])
677+
AspectsF.insert(Aspect);
678+
}
679+
}
680+
}
681+
650682
/// Returns a map of functions with corresponding used aspects.
651683
std::pair<FunctionToAspectsMapTy, FunctionToAspectsMapTy>
652684
buildFunctionsToAspectsMap(Module &M, TypeToAspectsMapTy &TypesWithAspects,
@@ -655,16 +687,21 @@ buildFunctionsToAspectsMap(Module &M, TypeToAspectsMapTy &TypesWithAspects,
655687
bool ValidateAspects, bool FP64ConvEmu) {
656688
FunctionToAspectsMapTy FunctionToUsedAspects;
657689
FunctionToAspectsMapTy FunctionToDeclaredAspects;
690+
StringMap<SmallVector<Function *, 4>> VirtualFunctionSets;
658691
CallGraphTy CG;
659692

660693
for (Function &F : M.functions()) {
661694
processFunction(F, FunctionToUsedAspects, FunctionToDeclaredAspects,
662695
TypesWithAspects, CG, AspectValues, FP64ConvEmu);
696+
collectVirtualFunctionSetInfo(F, VirtualFunctionSets);
663697
}
664698

665699
SmallPtrSet<const Function *, 16> Visited;
666-
for (Function *F : EntryPoints)
700+
for (Function *F : EntryPoints) {
667701
propagateAspectsThroughCG(F, CG, FunctionToUsedAspects, Visited);
702+
processDeclaredVirtualFunctionSets(F, CG, FunctionToUsedAspects, Visited,
703+
VirtualFunctionSets);
704+
}
668705

669706
if (ValidateAspects)
670707
validateUsedAspectsForFunctions(FunctionToUsedAspects, AspectValues,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: opt -passes=sycl-propagate-aspects-usage < %s -S | FileCheck %s
2+
3+
; CHECK: @vfn() #0 !sycl_used_aspects ![[#aspects:]]
4+
define spir_func void @vfn() #0 {
5+
%tmp = alloca double
6+
ret void
7+
}
8+
9+
; CHECK: @foo() #1 !sycl_used_aspects ![[#aspects]]
10+
define spir_kernel void @foo() #1 {
11+
ret void
12+
}
13+
14+
; CHECK: ![[#aspects]] = !{i32 6}
15+
16+
attributes #0 = { "indirectly-callable"="_ZTSv" }
17+
attributes #1 = { "calls-indirectly"="_ZTSv" }
18+
19+
!sycl_aspects = !{!0}
20+
!0 = !{!"fp64", i32 6}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: opt -passes=sycl-propagate-aspects-usage < %s -S | FileCheck %s
2+
3+
%Foo = type { i32 }
4+
%Bar = type { i32 }
5+
6+
; CHECK: @vfnFoo() #0 !sycl_used_aspects ![[#aspectsFoo:]]
7+
define spir_func void @vfnFoo() #0 {
8+
%tmp = alloca %Foo
9+
ret void
10+
}
11+
12+
; CHECK: @vfnBar() #1 !sycl_used_aspects ![[#aspectsBar:]]
13+
define spir_func void @vfnBar() #1 {
14+
%tmp = alloca %Bar
15+
ret void
16+
}
17+
18+
; CHECK: @kernel() #2 !sycl_used_aspects ![[#aspectsKernel:]]
19+
define spir_kernel void @kernel() #2 {
20+
ret void
21+
}
22+
23+
; CHECK: ![[#aspectsFoo]] = !{i32 1}
24+
; CHECK: ![[#aspectsBar]] = !{i32 2}
25+
; CHECK: ![[#aspectsKernel]] = !{i32 1, i32 2}
26+
27+
attributes #0 = { "indirectly-callable"="setFoo" }
28+
attributes #1 = { "indirectly-callable"="setBar" }
29+
attributes #2 = { "calls-indirectly"="setFoo,setBar" }
30+
31+
!sycl_aspects = !{!0}
32+
!0 = !{!"fp64", i32 6}
33+
34+
!sycl_types_that_use_aspects = !{!1, !2}
35+
!1 = !{!"Foo", i32 1}
36+
!2 = !{!"Bar", i32 2}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
; RUN: opt -passes=sycl-propagate-aspects-usage < %s -S | FileCheck %s
2+
3+
%Foo = type { i32 }
4+
%Bar = type { i32 }
5+
6+
; CHECK: @vfnFoo() #0 !sycl_used_aspects ![[#aspectsFoo:]]
7+
define spir_func void @vfnFoo() #0 {
8+
call void @subFoo()
9+
ret void
10+
}
11+
12+
define spir_func void @subFoo() {
13+
%tmp = alloca %Foo
14+
ret void
15+
}
16+
17+
; CHECK: @vfnBar() #1 !sycl_used_aspects ![[#aspectsBar:]]
18+
define spir_func void @vfnBar() #1 {
19+
call void @subBar()
20+
ret void
21+
}
22+
23+
define spir_func void @subBar() {
24+
%tmp = alloca %Bar
25+
ret void
26+
}
27+
28+
; CHECK: @kernelA() #2 !sycl_used_aspects ![[#aspectsFoo]]
29+
define spir_kernel void @kernelA() #2 {
30+
ret void
31+
}
32+
33+
; CHECK: @kernelB() #3 !sycl_used_aspects ![[#aspectsBar]]
34+
define spir_kernel void @kernelB() #3 {
35+
ret void
36+
}
37+
38+
; CHECK: ![[#aspectsFoo]] = !{i32 1}
39+
; CHECK: ![[#aspectsBar]] = !{i32 2}
40+
41+
attributes #0 = { "indirectly-callable"="setFoo" }
42+
attributes #1 = { "indirectly-callable"="setBar" }
43+
attributes #2 = { "calls-indirectly"="setFoo" }
44+
attributes #3 = { "calls-indirectly"="setBar" }
45+
46+
!sycl_aspects = !{!0}
47+
!0 = !{!"fp64", i32 6}
48+
49+
!sycl_types_that_use_aspects = !{!1, !2}
50+
!1 = !{!"Foo", i32 1}
51+
!2 = !{!"Bar", i32 2}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: opt -passes=sycl-propagate-aspects-usage < %s -S | FileCheck %s
2+
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-G1"
3+
target triple = "spir64-unknown-unknown"
4+
5+
@vtable = linkonce_odr dso_local unnamed_addr addrspace(1) constant { [3 x ptr addrspace(4)] } { [3 x ptr addrspace(4)] [ptr addrspace(4) null, ptr addrspace(4) null, ptr addrspace(4) addrspacecast (ptr @foo to ptr addrspace(4))] }, align 8
6+
7+
; CHECK: @foo() #0 !sycl_used_aspects ![[#aspects:]]
8+
define linkonce_odr spir_func void @foo() #0 {
9+
entry:
10+
%tmp = alloca double
11+
ret void
12+
}
13+
14+
; CHECK-NOT: @construct({{.*}}){{.*}}!sycl_used_aspects
15+
define weak_odr dso_local spir_kernel void @construct(ptr addrspace(1) noundef align 8 %_arg_StorageAcc) {
16+
entry:
17+
store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) (i8, ptr addrspace(1) @vtable, i64 16), ptr addrspace(1) %_arg_StorageAcc, align 8
18+
ret void
19+
}
20+
21+
; CHECK: ![[#aspects]] = !{i32 6}
22+
23+
attributes #0 = { "indirectly-callable"="set-foo" }
24+
25+
!sycl_aspects = !{!0}
26+
!0 = !{!"fp64", i32 6}

0 commit comments

Comments
 (0)