1 //===-- AMDGPUAlwaysInlinePass.cpp - Promote Allocas ----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This pass marks all internal functions as always_inline and creates
12 /// duplicates of all other functions and marks the duplicates as always_inline.
14 //===----------------------------------------------------------------------===//
17 #include "llvm/IR/Module.h"
18 #include "llvm/Transforms/Utils/Cloning.h"
24 static cl::opt<bool> StressCalls(
25 "amdgpu-stress-function-calls",
27 cl::desc("Force all functions to be noinline"),
30 class AMDGPUAlwaysInline : public ModulePass {
36 AMDGPUAlwaysInline(bool GlobalOpt = false) :
37 ModulePass(ID), GlobalOpt(GlobalOpt) { }
38 bool runOnModule(Module &M) override;
39 StringRef getPassName() const override { return "AMDGPU Always Inline Pass"; }
42 } // End anonymous namespace
44 INITIALIZE_PASS(AMDGPUAlwaysInline, "amdgpu-always-inline",
45 "AMDGPU Inline All Functions", false, false)
47 char AMDGPUAlwaysInline::ID = 0;
49 bool AMDGPUAlwaysInline::runOnModule(Module &M) {
50 std::vector<GlobalAlias*> AliasesToRemove;
51 std::vector<Function *> FuncsToClone;
53 for (GlobalAlias &A : M.aliases()) {
54 if (Function* F = dyn_cast<Function>(A.getAliasee())) {
55 A.replaceAllUsesWith(F);
56 AliasesToRemove.push_back(&A);
61 for (GlobalAlias* A : AliasesToRemove) {
66 auto NewAttr = StressCalls ? Attribute::NoInline : Attribute::AlwaysInline;
68 = StressCalls ? Attribute::AlwaysInline : Attribute::NoInline;
70 for (Function &F : M) {
71 if (!F.hasLocalLinkage() && !F.isDeclaration() && !F.use_empty() &&
72 !F.hasFnAttribute(IncompatAttr))
73 FuncsToClone.push_back(&F);
76 for (Function *F : FuncsToClone) {
77 ValueToValueMapTy VMap;
78 Function *NewFunc = CloneFunction(F, VMap);
79 NewFunc->setLinkage(GlobalValue::InternalLinkage);
80 F->replaceAllUsesWith(NewFunc);
83 for (Function &F : M) {
84 if (F.hasLocalLinkage() && !F.hasFnAttribute(IncompatAttr)) {
91 ModulePass *llvm::createAMDGPUAlwaysInlinePass(bool GlobalOpt) {
92 return new AMDGPUAlwaysInline(GlobalOpt);