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