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