Skip to content

Commit 7ca0143

Browse files
[ESIMD] Aggressively inline every function called by ESIMD kernel
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 4ad9e79 commit 7ca0143

File tree

3 files changed

+61
-32
lines changed

3 files changed

+61
-32
lines changed

llvm/lib/SYCLLowerIR/LowerESIMD.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,11 @@ void SYCLLowerESIMDLegacyPass::collectGenXVolatileType(Module &M) {
12331233
PreservedAnalyses SYCLLowerESIMDPass::run(Function &F,
12341234
FunctionAnalysisManager &FAM,
12351235
SmallPtrSet<Type *, 4> &GVTS) {
1236+
// Add 'alwaysinline' attribute to every function called from ESIMD kernel
1237+
if ((F.getCallingConv() != CallingConv::SPIR_KERNEL) &&
1238+
!F.hasFnAttribute(Attribute::AlwaysInline))
1239+
F.addFnAttr(Attribute::AlwaysInline);
1240+
12361241
SmallVector<CallInst *, 32> ESIMDIntrCalls;
12371242
SmallVector<Instruction *, 8> ESIMDToErases;
12381243

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes
2+
; RUN: opt -LowerESIMD -S < %s | FileCheck %s
3+
4+
; This test checks that LowerESIMD pass sets the 'alwaysinline'
5+
; attribute for all the functions called from ESIMD kernels.
6+
7+
define spir_kernel void @EsimdKernel1() {
8+
; CHECK-LABEL: @EsimdKernel1(
9+
; CHECK-NEXT: call void @foo()
10+
; CHECK-NEXT: call void @bar()
11+
; CHECK-NEXT: ret void
12+
;
13+
call void @foo()
14+
call void @bar()
15+
ret void
16+
}
17+
18+
define spir_kernel void @EsimdKernel2() {
19+
; CHECK-LABEL: @EsimdKernel2(
20+
; CHECK-NEXT: call void @foobar()
21+
; CHECK-NEXT: ret void
22+
;
23+
call void @foobar()
24+
ret void
25+
}
26+
27+
define spir_func void @foo() {
28+
; CHECK: Function Attrs: alwaysinline
29+
; CHECK-LABEL: @foo(
30+
; CHECK-NEXT: ret void
31+
;
32+
ret void
33+
}
34+
35+
define spir_func void @bar() {
36+
; CHECK: Function Attrs: alwaysinline
37+
; CHECK-LABEL: @bar(
38+
; CHECK-NEXT: call void @foobar()
39+
; CHECK-NEXT: ret void
40+
;
41+
call void @foobar()
42+
ret void
43+
}
44+
45+
define spir_func void @foobar() {
46+
; CHECK: Function Attrs: alwaysinline
47+
; CHECK-LABEL: @foobar(
48+
; CHECK-NEXT: ret void
49+
;
50+
ret void
51+
}

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

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/Support/SystemUtils.h"
3737
#include "llvm/Support/WithColor.h"
3838
#include "llvm/Transforms/IPO.h"
39+
#include "llvm/Transforms/IPO/AlwaysInliner.h"
3940
#include "llvm/Transforms/IPO/GlobalDCE.h"
4041
#include "llvm/Transforms/InstCombine/InstCombine.h"
4142
#include "llvm/Transforms/Scalar.h"
@@ -668,40 +669,17 @@ static string_vector saveResultSymbolsLists(string_vector &ResSymbolsLists,
668669
} \
669670
}
670671

671-
// Helper function for creating Inliner pass.
672-
// The approach is taken from opt tool.
673-
static Pass *createFunctionInliningPassHelper() {
674-
if (OptLevelO0)
675-
return createFunctionInliningPass(0, 0, false);
676-
677-
if (OptLevelO1)
678-
return createFunctionInliningPass(1, 0, false);
679-
680-
if (OptLevelO2)
681-
return createFunctionInliningPass(2, 0, false);
682-
683-
if (OptLevelOs)
684-
return createFunctionInliningPass(2, 1, false);
685-
686-
if (OptLevelOz)
687-
return createFunctionInliningPass(2, 2, false);
688-
689-
if (OptLevelO3)
690-
return createFunctionInliningPass(3, 0, false);
691-
692-
return createFunctionInliningPass();
693-
}
694-
695672
// When ESIMD code was separated from the regular SYCL code,
696673
// we can safely process ESIMD part.
697674
// TODO: support options like -debug-pass, -print-[before|after], and others
698675
static void LowerEsimdConstructs(Module &M) {
699676
legacy::PassManager MPM;
700677
MPM.add(createSYCLLowerESIMDPass());
701678
if (!OptLevelO0) {
702-
// Inlining and SROA passes are required to make
703-
// ESIMD/accessor_gather_scatter.cpp test work.
704-
MPM.add(createFunctionInliningPassHelper());
679+
// LowerESIMD pass sets 'alwaysinline' attribute to all the functions
680+
// in the call graph for every ESIMD kernel, which is later consumed
681+
// by AlwaysInliner pass.
682+
MPM.add(createAlwaysInlinerLegacyPass());
705683
MPM.add(createSROAPass());
706684
}
707685
MPM.add(createESIMDLowerVecArgPass());
@@ -711,11 +689,6 @@ static void LowerEsimdConstructs(Module &M) {
711689
MPM.add(createEarlyCSEPass(true));
712690
MPM.add(createInstructionCombiningPass());
713691
MPM.add(createDeadCodeEliminationPass());
714-
MPM.add(createFunctionInliningPassHelper());
715-
MPM.add(createSROAPass());
716-
MPM.add(createEarlyCSEPass(true));
717-
MPM.add(createInstructionCombiningPass());
718-
MPM.add(createDeadCodeEliminationPass());
719692
}
720693
MPM.add(createGenXSPIRVWriterAdaptorPass());
721694
MPM.run(M);

0 commit comments

Comments
 (0)