Skip to content

Commit 65b459d

Browse files
[SYCL] [ESIMD] Aggressively inline every function called by ESIMD kernel (#3261)
This patch is created to overcome a current limitation of Intel GPU vector backend that requires kernel functions to be inlined into the kernel itself. I removed later inlining passes since AlwaysInline pass is supposed to inline everything that's possible.
1 parent 59ceaf4 commit 65b459d

File tree

3 files changed

+51
-28
lines changed

3 files changed

+51
-28
lines changed

llvm/lib/SYCLLowerIR/LowerESIMD.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,14 @@ PreservedAnalyses SYCLLowerESIMDPass::run(Module &M,
12441244

12451245
size_t SYCLLowerESIMDPass::runOnFunction(Function &F,
12461246
SmallPtrSet<Type *, 4> &GVTS) {
1247+
// There is a current limitation of GPU vector backend that requires kernel
1248+
// functions to be inlined into the kernel itself. To overcome this
1249+
// limitation, mark every function called from ESIMD kernel with
1250+
// 'alwaysinline' attribute.
1251+
if ((F.getCallingConv() != CallingConv::SPIR_KERNEL) &&
1252+
!F.hasFnAttribute(Attribute::AlwaysInline))
1253+
F.addFnAttr(Attribute::AlwaysInline);
1254+
12471255
SmallVector<CallInst *, 32> ESIMDIntrCalls;
12481256
SmallVector<Instruction *, 8> ESIMDToErases;
12491257

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; RUN: opt -LowerESIMD -S < %s | FileCheck %s
2+
3+
; This test checks that LowerESIMD pass sets the 'alwaysinline'
4+
; attribute for all non-kernel functions.
5+
6+
define spir_kernel void @EsimdKernel1() {
7+
; CHECK: @EsimdKernel1(
8+
; CHECK-NEXT: call void @foo()
9+
; CHECK-NEXT: call void @bar()
10+
call void @foo()
11+
call void @bar()
12+
ret void
13+
}
14+
15+
define spir_kernel void @EsimdKernel2() {
16+
; CHECK: @EsimdKernel2(
17+
; CHECK-NEXT: call void @foobar()
18+
call void @foobar()
19+
ret void
20+
}
21+
22+
define spir_func void @foo() {
23+
; CHECK: @foo() #[[ATTR:[0-9]+]]
24+
ret void
25+
}
26+
27+
define spir_func void @bar() {
28+
; CHECK: @bar() #[[ATTR]]
29+
; CHECK-NEXT: call void @foobar
30+
call void @foobar()
31+
ret void
32+
}
33+
34+
define spir_func void @foobar() {
35+
; CHECK: @foobar() #[[ATTR]]
36+
ret void
37+
}
38+
39+
; CHECK: attributes #[[ATTR]] = { alwaysinline }

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

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/Support/SystemUtils.h"
3838
#include "llvm/Support/WithColor.h"
3939
#include "llvm/Transforms/IPO.h"
40+
#include "llvm/Transforms/IPO/AlwaysInliner.h"
4041
#include "llvm/Transforms/IPO/GlobalDCE.h"
4142
#include "llvm/Transforms/InstCombine/InstCombine.h"
4243
#include "llvm/Transforms/Scalar.h"
@@ -489,40 +490,15 @@ static string_vector saveResultSymbolsLists(string_vector &ResSymbolsLists,
489490
} \
490491
}
491492

492-
// Helper function for creating Inliner pass.
493-
// The approach is taken from opt tool.
494-
static Pass *createFunctionInliningPassHelper() {
495-
if (OptLevelO0)
496-
return createFunctionInliningPass(0, 0, false);
497-
498-
if (OptLevelO1)
499-
return createFunctionInliningPass(1, 0, false);
500-
501-
if (OptLevelO2)
502-
return createFunctionInliningPass(2, 0, false);
503-
504-
if (OptLevelOs)
505-
return createFunctionInliningPass(2, 1, false);
506-
507-
if (OptLevelOz)
508-
return createFunctionInliningPass(2, 2, false);
509-
510-
if (OptLevelO3)
511-
return createFunctionInliningPass(3, 0, false);
512-
513-
return createFunctionInliningPass();
514-
}
515-
516493
// When ESIMD code was separated from the regular SYCL code,
517494
// we can safely process ESIMD part.
518495
// TODO: support options like -debug-pass, -print-[before|after], and others
519496
static void LowerEsimdConstructs(Module &M) {
520497
legacy::PassManager MPM;
521498
MPM.add(createSYCLLowerESIMDPass());
522499
if (!OptLevelO0) {
523-
// Inlining and SROA passes are required to make
524-
// ESIMD/accessor_gather_scatter.cpp test work.
525-
MPM.add(createFunctionInliningPassHelper());
500+
// Force-inline all functions marked 'alwaysinline' by the LowerESIMD pass.
501+
MPM.add(createAlwaysInlinerLegacyPass());
526502
MPM.add(createSROAPass());
527503
}
528504
MPM.add(createESIMDLowerVecArgPass());
@@ -532,7 +508,7 @@ static void LowerEsimdConstructs(Module &M) {
532508
MPM.add(createEarlyCSEPass(true));
533509
MPM.add(createInstructionCombiningPass());
534510
MPM.add(createDeadCodeEliminationPass());
535-
MPM.add(createFunctionInliningPassHelper());
511+
// TODO: maybe remove some passes below that don't affect code quality
536512
MPM.add(createSROAPass());
537513
MPM.add(createEarlyCSEPass(true));
538514
MPM.add(createInstructionCombiningPass());

0 commit comments

Comments
 (0)