13fb68373c42fe0b8b670f506457d2c45bf12e6a5Devang Patel//===- InlineAlways.cpp - Code to inline always_inline functions ----------===// 222ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// 322ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// The LLVM Compiler Infrastructure 422ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// 522ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// This file is distributed under the University of Illinois Open Source 622ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// License. See LICENSE.TXT for details. 722ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// 822ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel//===----------------------------------------------------------------------===// 922ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// 103fb68373c42fe0b8b670f506457d2c45bf12e6a5Devang Patel// This file implements a custom inliner that handles only functions that 117946e7b8a4058fc2c76f782fa87340738caafaecDevang Patel// are marked as "always inline". 1222ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel// 1322ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel//===----------------------------------------------------------------------===// 1422ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Transforms/IPO.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallPtrSet.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Analysis/CallGraph.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Analysis/InlineCost.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/CallSite.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 2622ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel#include "llvm/Transforms/IPO/InlinerPass.h" 2722ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel 2822ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patelusing namespace llvm; 2922ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "inline" 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3222ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patelnamespace { 3322ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel 340378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth/// \brief Inliner pass which only handles "always inline" functions. 350378e3916a3d568ee161803d4f0107512e595af8Chandler Carruthclass AlwaysInliner : public Inliner { 3686953b5795007eaa98838297360a6987e33e92e7Chandler Carruth InlineCostAnalysis *ICA; 370378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth 380378e3916a3d568ee161803d4f0107512e595af8Chandler Carruthpublic: 390378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth // Use extremely low threshold. 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AlwaysInliner() : Inliner(ID, -2000000000, /*InsertLifetime*/ true), 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ICA(nullptr) { 420378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); 430378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth } 440378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth 450378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth AlwaysInliner(bool InsertLifetime) 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : Inliner(ID, -2000000000, InsertLifetime), ICA(nullptr) { 470378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); 480378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth } 490378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth 500378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth static char ID; // Pass identification, replacement for typeid 510378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InlineCost getInlineCost(CallSite CS) override; 530378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override; 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnSCC(CallGraphSCC &SCC) override; 5686953b5795007eaa98838297360a6987e33e92e7Chandler Carruth 570378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth using llvm::Pass::doFinalization; 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doFinalization(CallGraph &CG) override { 590378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/ true); 600378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth } 610378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth}; 620378e3916a3d568ee161803d4f0107512e595af8Chandler Carruth 6322ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel} 6422ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel 6522ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patelchar AlwaysInliner::ID = 0; 66081c34b725980f995be9080eaec24cd3dfaaf065Owen AndersonINITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", 67081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson "Inliner for always_inline functions", false, false) 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 6986953b5795007eaa98838297360a6987e33e92e7Chandler CarruthINITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) 70081c34b725980f995be9080eaec24cd3dfaaf065Owen AndersonINITIALIZE_PASS_END(AlwaysInliner, "always-inline", 71ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson "Inliner for always_inline functions", false, false) 7222ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel 7322ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang PatelPass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); } 7422ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel 75fa086f1f00a8b75ab2e2208bd7a028e62f9854dbChad RosierPass *llvm::createAlwaysInlinerPass(bool InsertLifetime) { 76fa086f1f00a8b75ab2e2208bd7a028e62f9854dbChad Rosier return new AlwaysInliner(InsertLifetime); 77fa086f1f00a8b75ab2e2208bd7a028e62f9854dbChad Rosier} 78fa086f1f00a8b75ab2e2208bd7a028e62f9854dbChad Rosier 79b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// \brief Get the inline cost for the always-inliner. 80b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// 81b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// The always inliner *only* handles functions which are marked with the 82b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// attribute to force inlining. As such, it is dramatically simpler and avoids 83b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// using the powerful (but expensive) inline cost analysis. Instead it uses 84b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// a very simple and boring direct walk of the instructions looking for 85b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// impossible-to-inline constructs. 86b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// 87b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// Note, it would be possible to go to some lengths to cache the information 88b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// computed here, but as we only expect to do this for relatively few and 89b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// small functions which have the explicit attribute to force inlining, it is 90b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth/// likely not worth it in practice. 91b594a84df501385e4d90bd9531084be62cef0857Chandler CarruthInlineCost AlwaysInliner::getInlineCost(CallSite CS) { 92b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth Function *Callee = CS.getCalledFunction(); 93b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth 9428f872f8a1945635f30763805c1418a90c6b345eBob Wilson // Only inline direct calls to functions with always-inline attributes 9528f872f8a1945635f30763805c1418a90c6b345eBob Wilson // that are viable for inlining. FIXME: We shouldn't even get here for 9628f872f8a1945635f30763805c1418a90c6b345eBob Wilson // declarations. 9728f872f8a1945635f30763805c1418a90c6b345eBob Wilson if (Callee && !Callee->isDeclaration() && 98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CS.hasFnAttr(Attribute::AlwaysInline) && 9986953b5795007eaa98838297360a6987e33e92e7Chandler Carruth ICA->isInlineViable(*Callee)) 10028f872f8a1945635f30763805c1418a90c6b345eBob Wilson return InlineCost::getAlways(); 101b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth 10228f872f8a1945635f30763805c1418a90c6b345eBob Wilson return InlineCost::getNever(); 103b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth} 104b594a84df501385e4d90bd9531084be62cef0857Chandler Carruth 10586953b5795007eaa98838297360a6987e33e92e7Chandler Carruthbool AlwaysInliner::runOnSCC(CallGraphSCC &SCC) { 10686953b5795007eaa98838297360a6987e33e92e7Chandler Carruth ICA = &getAnalysis<InlineCostAnalysis>(); 10786953b5795007eaa98838297360a6987e33e92e7Chandler Carruth return Inliner::runOnSCC(SCC); 10886953b5795007eaa98838297360a6987e33e92e7Chandler Carruth} 10986953b5795007eaa98838297360a6987e33e92e7Chandler Carruth 11086953b5795007eaa98838297360a6987e33e92e7Chandler Carruthvoid AlwaysInliner::getAnalysisUsage(AnalysisUsage &AU) const { 11186953b5795007eaa98838297360a6987e33e92e7Chandler Carruth AU.addRequired<InlineCostAnalysis>(); 11286953b5795007eaa98838297360a6987e33e92e7Chandler Carruth Inliner::getAnalysisUsage(AU); 11322ec199fa0198220a11eb70ee55bb7ea3d1f7c60Devang Patel} 114