Skip to content

Commit

Permalink
[SYCL] [ESIMD] Aggressively inline every function called by ESIMD ker…
Browse files Browse the repository at this point in the history
…nel (#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.
  • Loading branch information
DenisBakhvalov authored Mar 4, 2021
1 parent 59ceaf4 commit 65b459d
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 28 deletions.
8 changes: 8 additions & 0 deletions llvm/lib/SYCLLowerIR/LowerESIMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,14 @@ PreservedAnalyses SYCLLowerESIMDPass::run(Module &M,

size_t SYCLLowerESIMDPass::runOnFunction(Function &F,
SmallPtrSet<Type *, 4> &GVTS) {
// There is a current limitation of GPU vector backend that requires kernel
// functions to be inlined into the kernel itself. To overcome this
// limitation, mark every function called from ESIMD kernel with
// 'alwaysinline' attribute.
if ((F.getCallingConv() != CallingConv::SPIR_KERNEL) &&
!F.hasFnAttribute(Attribute::AlwaysInline))
F.addFnAttr(Attribute::AlwaysInline);

SmallVector<CallInst *, 32> ESIMDIntrCalls;
SmallVector<Instruction *, 8> ESIMDToErases;

Expand Down
39 changes: 39 additions & 0 deletions llvm/test/SYCLLowerIR/esimd_lower_inline_hint.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
; RUN: opt -LowerESIMD -S < %s | FileCheck %s

; This test checks that LowerESIMD pass sets the 'alwaysinline'
; attribute for all non-kernel functions.

define spir_kernel void @EsimdKernel1() {
; CHECK: @EsimdKernel1(
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @bar()
call void @foo()
call void @bar()
ret void
}

define spir_kernel void @EsimdKernel2() {
; CHECK: @EsimdKernel2(
; CHECK-NEXT: call void @foobar()
call void @foobar()
ret void
}

define spir_func void @foo() {
; CHECK: @foo() #[[ATTR:[0-9]+]]
ret void
}

define spir_func void @bar() {
; CHECK: @bar() #[[ATTR]]
; CHECK-NEXT: call void @foobar
call void @foobar()
ret void
}

define spir_func void @foobar() {
; CHECK: @foobar() #[[ATTR]]
ret void
}

; CHECK: attributes #[[ATTR]] = { alwaysinline }
32 changes: 4 additions & 28 deletions llvm/tools/sycl-post-link/sycl-post-link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Scalar.h"
Expand Down Expand Up @@ -489,40 +490,15 @@ static string_vector saveResultSymbolsLists(string_vector &ResSymbolsLists,
} \
}

// Helper function for creating Inliner pass.
// The approach is taken from opt tool.
static Pass *createFunctionInliningPassHelper() {
if (OptLevelO0)
return createFunctionInliningPass(0, 0, false);

if (OptLevelO1)
return createFunctionInliningPass(1, 0, false);

if (OptLevelO2)
return createFunctionInliningPass(2, 0, false);

if (OptLevelOs)
return createFunctionInliningPass(2, 1, false);

if (OptLevelOz)
return createFunctionInliningPass(2, 2, false);

if (OptLevelO3)
return createFunctionInliningPass(3, 0, false);

return createFunctionInliningPass();
}

// When ESIMD code was separated from the regular SYCL code,
// we can safely process ESIMD part.
// TODO: support options like -debug-pass, -print-[before|after], and others
static void LowerEsimdConstructs(Module &M) {
legacy::PassManager MPM;
MPM.add(createSYCLLowerESIMDPass());
if (!OptLevelO0) {
// Inlining and SROA passes are required to make
// ESIMD/accessor_gather_scatter.cpp test work.
MPM.add(createFunctionInliningPassHelper());
// Force-inline all functions marked 'alwaysinline' by the LowerESIMD pass.
MPM.add(createAlwaysInlinerLegacyPass());
MPM.add(createSROAPass());
}
MPM.add(createESIMDLowerVecArgPass());
Expand All @@ -532,7 +508,7 @@ static void LowerEsimdConstructs(Module &M) {
MPM.add(createEarlyCSEPass(true));
MPM.add(createInstructionCombiningPass());
MPM.add(createDeadCodeEliminationPass());
MPM.add(createFunctionInliningPassHelper());
// TODO: maybe remove some passes below that don't affect code quality
MPM.add(createSROAPass());
MPM.add(createEarlyCSEPass(true));
MPM.add(createInstructionCombiningPass());
Expand Down

0 comments on commit 65b459d

Please sign in to comment.