1//===- InlineSimple.cpp - Code to perform simple function inlining --------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file implements bottom-up inlining of functions into callees. 10// 11//===----------------------------------------------------------------------===// 12 13#include "llvm/Analysis/AssumptionCache.h" 14#include "llvm/Analysis/InlineCost.h" 15#include "llvm/Analysis/ProfileSummaryInfo.h" 16#include "llvm/Analysis/TargetLibraryInfo.h" 17#include "llvm/Analysis/TargetTransformInfo.h" 18#include "llvm/IR/CallSite.h" 19#include "llvm/IR/CallingConv.h" 20#include "llvm/IR/DataLayout.h" 21#include "llvm/IR/Instructions.h" 22#include "llvm/IR/Module.h" 23#include "llvm/IR/Type.h" 24#include "llvm/InitializePasses.h" 25#include "llvm/Transforms/IPO.h" 26#include "llvm/Transforms/IPO/Inliner.h" 27 28using namespace llvm; 29 30#define DEBUG_TYPE "inline" 31 32namespace { 33 34/// Actual inliner pass implementation. 35/// 36/// The common implementation of the inlining logic is shared between this 37/// inliner pass and the always inliner pass. The two passes use different cost 38/// analyses to determine when to inline. 39class SimpleInliner : public LegacyInlinerBase { 40 41 InlineParams Params; 42 43public: 44 SimpleInliner() : LegacyInlinerBase(ID), Params(llvm::getInlineParams()) { 45 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 46 } 47 48 explicit SimpleInliner(InlineParams Params) 49 : LegacyInlinerBase(ID), Params(std::move(Params)) { 50 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 51 } 52 53 static char ID; // Pass identification, replacement for typeid 54 55 InlineCost getInlineCost(CallSite CS) override { 56 Function *Callee = CS.getCalledFunction(); 57 TargetTransformInfo &TTI = TTIWP->getTTI(*Callee); 58 59 bool RemarksEnabled = false; 60 const auto &BBs = CS.getCaller()->getBasicBlockList(); 61 if (!BBs.empty()) { 62 auto DI = OptimizationRemark(DEBUG_TYPE, "", DebugLoc(), &BBs.front()); 63 if (DI.isEnabled()) 64 RemarksEnabled = true; 65 } 66 OptimizationRemarkEmitter ORE(CS.getCaller()); 67 68 std::function<AssumptionCache &(Function &)> GetAssumptionCache = 69 [&](Function &F) -> AssumptionCache & { 70 return ACT->getAssumptionCache(F); 71 }; 72 return llvm::getInlineCost( 73 cast<CallBase>(*CS.getInstruction()), Params, TTI, GetAssumptionCache, 74 /*GetBFI=*/None, PSI, RemarksEnabled ? &ORE : nullptr); 75 } 76 77 bool runOnSCC(CallGraphSCC &SCC) override; 78 void getAnalysisUsage(AnalysisUsage &AU) const override; 79 80private: 81 TargetTransformInfoWrapperPass *TTIWP; 82 83}; 84 85} // end anonymous namespace 86 87char SimpleInliner::ID = 0; 88INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining", 89 false, false) 90INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) 91INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 92INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) 93INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) 94INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 95INITIALIZE_PASS_END(SimpleInliner, "inline", "Function Integration/Inlining", 96 false, false) 97 98Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); } 99 100Pass *llvm::createFunctionInliningPass(int Threshold) { 101 return new SimpleInliner(llvm::getInlineParams(Threshold)); 102} 103 104Pass *llvm::createFunctionInliningPass(unsigned OptLevel, 105 unsigned SizeOptLevel, 106 bool DisableInlineHotCallSite) { 107 auto Param = llvm::getInlineParams(OptLevel, SizeOptLevel); 108 if (DisableInlineHotCallSite) 109 Param.HotCallSiteThreshold = 0; 110 return new SimpleInliner(Param); 111} 112 113Pass *llvm::createFunctionInliningPass(InlineParams &Params) { 114 return new SimpleInliner(Params); 115} 116 117bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) { 118 TTIWP = &getAnalysis<TargetTransformInfoWrapperPass>(); 119 return LegacyInlinerBase::runOnSCC(SCC); 120} 121 122void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const { 123 AU.addRequired<TargetTransformInfoWrapperPass>(); 124 LegacyInlinerBase::getAnalysisUsage(AU); 125} 126