forked from google/clspv
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New pass to inline single call site functions
* Adds a pass that inlines functions with a single call site * Added -no-inline-single option to disable the pass * Due to some unexpected interactions, found some crashes in customer kernels due to another pass. For now, this pass is only enabled if the function has pointer to local arguments * Pass is disabled in many tests to avoid substantial updates * Added new lit tests for the pass * Delete dead functions at the end of the pass
- Loading branch information
1 parent
fc6888e
commit 0dd3fd2
Showing
46 changed files
with
271 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// Copyright 2018 The Clspv Authors. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include <vector> | ||
|
||
#include "llvm/IR/CallingConv.h" | ||
#include "llvm/Pass.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
#include "llvm/Transforms/Utils/Cloning.h" | ||
|
||
#include "ArgKind.h" | ||
#include "clspv/Option.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace { | ||
class InlineFuncWithSingleCallSitePass : public ModulePass { | ||
public: | ||
static char ID; | ||
InlineFuncWithSingleCallSitePass() : ModulePass(ID) {} | ||
|
||
bool runOnModule(Module &M) override; | ||
|
||
private: | ||
bool InlineFunctions(Module &M); | ||
}; | ||
} // namespace | ||
|
||
namespace clspv { | ||
ModulePass *createInlineFuncWithSingleCallSitePass() { | ||
return new InlineFuncWithSingleCallSitePass(); | ||
} | ||
} // namespace clspv | ||
|
||
char InlineFuncWithSingleCallSitePass::ID = 0; | ||
static RegisterPass<InlineFuncWithSingleCallSitePass> | ||
X("InlineFuncWithSingleCallSite", | ||
"Inline functions with a single call site pass"); | ||
|
||
bool InlineFuncWithSingleCallSitePass::runOnModule(Module &M) { | ||
if (!clspv::Option::InlineSingleCallSite()) | ||
return false; | ||
|
||
bool Changed = false; | ||
for (bool local_changed = true; local_changed; Changed |= local_changed) { | ||
local_changed = InlineFunctions(M); | ||
} | ||
|
||
// Clean up dead functions. This done here to avoid ordering requirements on | ||
// inlining. | ||
std::vector<Function *> to_delete; | ||
for (auto &F : M) { | ||
if (F.isDeclaration() || F.getCallingConv() == CallingConv::SPIR_KERNEL) | ||
continue; | ||
|
||
if (F.user_empty()) | ||
to_delete.push_back(&F); | ||
} | ||
for (auto func : to_delete) { | ||
func->eraseFromParent(); | ||
} | ||
|
||
return Changed; | ||
} | ||
|
||
bool InlineFuncWithSingleCallSitePass::InlineFunctions(Module &M) { | ||
bool Changed = false; | ||
std::vector<CallInst *> to_inline; | ||
for (auto &F : M) { | ||
if (F.isDeclaration() || F.getCallingConv() == CallingConv::SPIR_KERNEL) | ||
continue; | ||
|
||
bool has_local_ptr_arg = false; | ||
for (auto &Arg : F.args()) { | ||
if (clspv::IsLocalPtr(Arg.getType())) | ||
has_local_ptr_arg = true; | ||
} | ||
|
||
// Only inline if the function has a local address space parameter. | ||
if (!has_local_ptr_arg) continue; | ||
|
||
if (F.getNumUses() == 1) { | ||
if (auto *call = dyn_cast<CallInst>(*F.user_begin())) | ||
to_inline.push_back(call); | ||
} | ||
} | ||
|
||
for (auto call : to_inline) { | ||
InlineFunctionInfo IFI; | ||
CallSite CS(call); | ||
// Disable generation of lifetime intrinsic. | ||
Changed |= InlineFunction(CS, IFI, nullptr, false); | ||
} | ||
|
||
return Changed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
test/ImageBuiltins/read_only_image2d_passed_to_other_function.cl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
test/ImageBuiltins/read_only_image3d_passed_to_other_function.cl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
test/ImageBuiltins/write_only_image2d_passed_to_other_function.cl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
test/ImageBuiltins/write_only_image3d_passed_to_other_function.cl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// RUN: clspv %s -S -o %t.spvasm | ||
// RUN: FileCheck %s < %t.spvasm | ||
// RUN: clspv %s -o %t.spv | ||
// RUN: spirv-dis -o %t2.spvasm %t.spv | ||
// RUN: FileCheck %s < %t2.spvasm | ||
// RUN: spirv-val --target-env vulkan1.0 %t.spv | ||
|
||
// All functions should be inlined into the kernel. | ||
// CHECK: OpEntryPoint GLCompute [[entry:%[0-9a-zA-Z_]+]] "func_0" | ||
// CHECK-NOT: OpFunctionCall | ||
// CHECK: [[entry]] = OpFunction | ||
// CHECK-NOT: OpFunctionCall | ||
|
||
int func_3(local int *in, int n) { return in[n]; } | ||
int func_2(local int *in, int n) { return func_3(in, n); } | ||
int func_1(local int *in, int n) { return func_2(in, n); } | ||
kernel void func_0(local int *in, global int *out, int n) { | ||
out[n] = func_1(in, n); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// RUN: clspv %s -S -o %t.spvasm | ||
// RUN: FileCheck %s < %t.spvasm | ||
// RUN: clspv %s -o %t.spv | ||
// RUN: spirv-dis -o %t2.spvasm %t.spv | ||
// RUN: FileCheck %s < %t2.spvasm | ||
// RUN: spirv-val --target-env vulkan1.0 %t.spv | ||
|
||
// CHECK: OpEntryPoint GLCompute [[entry:%[0-9a-zA-Z_]+]] "func_0" | ||
// CHECK: [[entry]] = OpFunction | ||
// CHECK: OpFunctionCall | ||
|
||
int func_1(global int *in, int n) { return in[n]; } | ||
kernel void func_0(global int *in, global int *out, int n) { | ||
out[n] = func_1(in, n); | ||
} |
31 changes: 31 additions & 0 deletions
31
test/InlineFuncWithSingleCallSite/two_kernels_partial_chain_inline.cl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// RUN: clspv %s -S -o %t.spvasm | ||
// RUN: FileCheck %s < %t.spvasm | ||
// RUN: clspv %s -o %t.spv | ||
// RUN: spirv-dis -o %t2.spvasm %t.spv | ||
// RUN: FileCheck %s < %t2.spvasm | ||
// RUN: spirv-val --target-env vulkan1.0 %t.spv | ||
|
||
// func_1 is called by both kernel_1 and kernel_2, so it will not be inlined, | ||
// but func_2 and func_3 will both be inlined into func_1. | ||
// CHECK: OpEntryPoint GLCompute [[k1:%[0-9a-zA-Z_]+]] "kernel_1" | ||
// CHECK: OpEntryPoint GLCompute [[k2:%[0-9a-zA-Z_]+]] "kernel_2" | ||
// CHECK: [[func:%[0-9a-zA-Z_]+]] = OpFunction | ||
// CHECK-NOT: OpFunctionCall | ||
// CHECK: OpFunctionEnd | ||
// CHECK: [[k1]] = OpFunction | ||
// CHECK: OpFunctionCall {{%[0-9a-zA-Z_]+}} [[func]] | ||
// CHECK-NOT: OpFunctionCall | ||
// CHECK: [[k2]] = OpFunction | ||
// CHECK: OpFunctionCall {{%[0-9a-zA-Z_]+}} [[func]] | ||
// CHECK-NOT: OpFunctionCall | ||
|
||
int func_3(local int *in, int n) { return in[n]; } | ||
int func_2(local int *in, int n) { return func_3(in, n); } | ||
int func_1(local int *in, int n) { return func_2(in, n); } | ||
kernel void kernel_1(local int *in, global int *out, int n) { | ||
out[n] = func_1(in, n); | ||
} | ||
kernel void kernel_2(local int *in, global int *out, int n) { | ||
out[n] = func_1(in, n); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.