145bb48eaSTom Stellard //===-- AMDGPUAlwaysInlinePass.cpp - Promote Allocas ----------------------===//
245bb48eaSTom Stellard //
345bb48eaSTom Stellard //                     The LLVM Compiler Infrastructure
445bb48eaSTom Stellard //
545bb48eaSTom Stellard // This file is distributed under the University of Illinois Open Source
645bb48eaSTom Stellard // License. See LICENSE.TXT for details.
745bb48eaSTom Stellard //
845bb48eaSTom Stellard //===----------------------------------------------------------------------===//
945bb48eaSTom Stellard //
1045bb48eaSTom Stellard /// \file
1145bb48eaSTom Stellard /// This pass marks all internal functions as always_inline and creates
1245bb48eaSTom Stellard /// duplicates of all other functions a marks the duplicates as always_inline.
1345bb48eaSTom Stellard //
1445bb48eaSTom Stellard //===----------------------------------------------------------------------===//
1545bb48eaSTom Stellard 
1645bb48eaSTom Stellard #include "AMDGPU.h"
1745bb48eaSTom Stellard #include "llvm/IR/Module.h"
1845bb48eaSTom Stellard #include "llvm/Transforms/Utils/Cloning.h"
1945bb48eaSTom Stellard 
2045bb48eaSTom Stellard using namespace llvm;
2145bb48eaSTom Stellard 
2245bb48eaSTom Stellard namespace {
2345bb48eaSTom Stellard 
2445bb48eaSTom Stellard class AMDGPUAlwaysInline : public ModulePass {
2545bb48eaSTom Stellard   static char ID;
2645bb48eaSTom Stellard 
27*89653dfdSStanislav Mekhanoshin   bool GlobalOpt;
28*89653dfdSStanislav Mekhanoshin 
2945bb48eaSTom Stellard public:
30*89653dfdSStanislav Mekhanoshin   AMDGPUAlwaysInline(bool GlobalOpt) : ModulePass(ID), GlobalOpt(GlobalOpt) { }
3145bb48eaSTom Stellard   bool runOnModule(Module &M) override;
32117296c0SMehdi Amini   StringRef getPassName() const override { return "AMDGPU Always Inline Pass"; }
3345bb48eaSTom Stellard };
3445bb48eaSTom Stellard 
3545bb48eaSTom Stellard } // End anonymous namespace
3645bb48eaSTom Stellard 
3745bb48eaSTom Stellard char AMDGPUAlwaysInline::ID = 0;
3845bb48eaSTom Stellard 
3945bb48eaSTom Stellard bool AMDGPUAlwaysInline::runOnModule(Module &M) {
40eba80895SNikolay Haustov   std::vector<GlobalAlias*> AliasesToRemove;
4145bb48eaSTom Stellard   std::vector<Function *> FuncsToClone;
42ca95d441SMatt Arsenault 
43eba80895SNikolay Haustov   for (GlobalAlias &A : M.aliases()) {
44eba80895SNikolay Haustov     if (Function* F = dyn_cast<Function>(A.getAliasee())) {
45eba80895SNikolay Haustov       A.replaceAllUsesWith(F);
46eba80895SNikolay Haustov       AliasesToRemove.push_back(&A);
47eba80895SNikolay Haustov     }
48eba80895SNikolay Haustov   }
49eba80895SNikolay Haustov 
50*89653dfdSStanislav Mekhanoshin   if (GlobalOpt) {
51eba80895SNikolay Haustov     for (GlobalAlias* A : AliasesToRemove) {
52eba80895SNikolay Haustov       A->eraseFromParent();
53eba80895SNikolay Haustov     }
54*89653dfdSStanislav Mekhanoshin   }
55eba80895SNikolay Haustov 
56ca95d441SMatt Arsenault   for (Function &F : M) {
5745bb48eaSTom Stellard     if (!F.hasLocalLinkage() && !F.isDeclaration() && !F.use_empty() &&
5845bb48eaSTom Stellard         !F.hasFnAttribute(Attribute::NoInline))
5945bb48eaSTom Stellard       FuncsToClone.push_back(&F);
6045bb48eaSTom Stellard   }
6145bb48eaSTom Stellard 
6245bb48eaSTom Stellard   for (Function *F : FuncsToClone) {
6345bb48eaSTom Stellard     ValueToValueMapTy VMap;
64dba99560SPeter Collingbourne     Function *NewFunc = CloneFunction(F, VMap);
6545bb48eaSTom Stellard     NewFunc->setLinkage(GlobalValue::InternalLinkage);
6645bb48eaSTom Stellard     F->replaceAllUsesWith(NewFunc);
6745bb48eaSTom Stellard   }
6845bb48eaSTom Stellard 
69ca95d441SMatt Arsenault   for (Function &F : M) {
7045bb48eaSTom Stellard     if (F.hasLocalLinkage() && !F.hasFnAttribute(Attribute::NoInline)) {
7145bb48eaSTom Stellard       F.addFnAttr(Attribute::AlwaysInline);
7245bb48eaSTom Stellard     }
7345bb48eaSTom Stellard   }
7445bb48eaSTom Stellard   return false;
7545bb48eaSTom Stellard }
7645bb48eaSTom Stellard 
77*89653dfdSStanislav Mekhanoshin ModulePass *llvm::createAMDGPUAlwaysInlinePass(bool GlobalOpt) {
78*89653dfdSStanislav Mekhanoshin   return new AMDGPUAlwaysInline(GlobalOpt);
7945bb48eaSTom Stellard }
80