blob: c27425443abc6619f53169bc1e87bcf9c05346e7 [file] [log] [blame]
Tom Stellard5cbb53c2014-11-03 19:49:05 +00001//===-- AMDGPUAlwaysInlinePass.cpp - Promote Allocas ----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// This pass marks all internal functions as always_inline and creates
Alfred Huangf9b521f2017-06-15 23:02:55 +000012/// duplicates of all other functions and marks the duplicates as always_inline.
Tom Stellard5cbb53c2014-11-03 19:49:05 +000013//
14//===----------------------------------------------------------------------===//
15
16#include "AMDGPU.h"
17#include "llvm/IR/Module.h"
18#include "llvm/Transforms/Utils/Cloning.h"
19
20using namespace llvm;
21
22namespace {
23
Matt Arsenault1390af22017-09-21 07:00:48 +000024static cl::opt<bool> StressCalls(
25 "amdgpu-stress-function-calls",
26 cl::Hidden,
27 cl::desc("Force all functions to be noinline"),
28 cl::init(false));
29
Tom Stellard5cbb53c2014-11-03 19:49:05 +000030class AMDGPUAlwaysInline : public ModulePass {
Stanislav Mekhanoshin89653df2017-03-30 20:16:02 +000031 bool GlobalOpt;
32
Tom Stellard5cbb53c2014-11-03 19:49:05 +000033public:
Matt Arsenault746e0652017-06-02 18:02:42 +000034 static char ID;
35
36 AMDGPUAlwaysInline(bool GlobalOpt = false) :
37 ModulePass(ID), GlobalOpt(GlobalOpt) { }
Tom Stellard5cbb53c2014-11-03 19:49:05 +000038 bool runOnModule(Module &M) override;
Mehdi Amini117296c2016-10-01 02:56:57 +000039 StringRef getPassName() const override { return "AMDGPU Always Inline Pass"; }
Tom Stellard5cbb53c2014-11-03 19:49:05 +000040};
41
42} // End anonymous namespace
43
Matt Arsenault746e0652017-06-02 18:02:42 +000044INITIALIZE_PASS(AMDGPUAlwaysInline, "amdgpu-always-inline",
45 "AMDGPU Inline All Functions", false, false)
46
Tom Stellard5cbb53c2014-11-03 19:49:05 +000047char AMDGPUAlwaysInline::ID = 0;
48
49bool AMDGPUAlwaysInline::runOnModule(Module &M) {
Nikolay Haustoveba80892016-08-31 11:18:33 +000050 std::vector<GlobalAlias*> AliasesToRemove;
Matt Arsenaultca95d442015-07-13 19:08:36 +000051 std::vector<Function *> FuncsToClone;
Tom Stellard5cbb53c2014-11-03 19:49:05 +000052
Nikolay Haustoveba80892016-08-31 11:18:33 +000053 for (GlobalAlias &A : M.aliases()) {
54 if (Function* F = dyn_cast<Function>(A.getAliasee())) {
55 A.replaceAllUsesWith(F);
56 AliasesToRemove.push_back(&A);
57 }
58 }
59
Stanislav Mekhanoshin89653df2017-03-30 20:16:02 +000060 if (GlobalOpt) {
61 for (GlobalAlias* A : AliasesToRemove) {
62 A->eraseFromParent();
63 }
Nikolay Haustoveba80892016-08-31 11:18:33 +000064 }
65
Matt Arsenault1390af22017-09-21 07:00:48 +000066 auto NewAttr = StressCalls ? Attribute::NoInline : Attribute::AlwaysInline;
67 auto IncompatAttr
68 = StressCalls ? Attribute::AlwaysInline : Attribute::NoInline;
69
Matt Arsenaultca95d442015-07-13 19:08:36 +000070 for (Function &F : M) {
Matt Arsenaultdeaef8e2015-04-22 17:10:44 +000071 if (!F.hasLocalLinkage() && !F.isDeclaration() && !F.use_empty() &&
Matt Arsenault1390af22017-09-21 07:00:48 +000072 !F.hasFnAttribute(IncompatAttr))
Tom Stellard5cbb53c2014-11-03 19:49:05 +000073 FuncsToClone.push_back(&F);
74 }
75
76 for (Function *F : FuncsToClone) {
77 ValueToValueMapTy VMap;
Peter Collingbournedba99562016-05-10 20:23:24 +000078 Function *NewFunc = CloneFunction(F, VMap);
Tom Stellard5cbb53c2014-11-03 19:49:05 +000079 NewFunc->setLinkage(GlobalValue::InternalLinkage);
Tom Stellard5cbb53c2014-11-03 19:49:05 +000080 F->replaceAllUsesWith(NewFunc);
81 }
82
Matt Arsenaultca95d442015-07-13 19:08:36 +000083 for (Function &F : M) {
Matt Arsenault1390af22017-09-21 07:00:48 +000084 if (F.hasLocalLinkage() && !F.hasFnAttribute(IncompatAttr)) {
85 F.addFnAttr(NewAttr);
Tom Stellard5cbb53c2014-11-03 19:49:05 +000086 }
87 }
88 return false;
89}
90
Stanislav Mekhanoshin89653df2017-03-30 20:16:02 +000091ModulePass *llvm::createAMDGPUAlwaysInlinePass(bool GlobalOpt) {
92 return new AMDGPUAlwaysInline(GlobalOpt);
Tom Stellard5cbb53c2014-11-03 19:49:05 +000093}