xref: /openbsd-src/gnu/llvm/llvm/lib/Transforms/IPO/InlineSimple.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- InlineSimple.cpp - Code to perform simple function inlining --------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file implements bottom-up inlining of functions into callees.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "llvm/Analysis/AssumptionCache.h"
1409467b48Spatrick #include "llvm/Analysis/InlineCost.h"
15*d415bd75Srobert #include "llvm/Analysis/OptimizationRemarkEmitter.h"
1609467b48Spatrick #include "llvm/Analysis/TargetTransformInfo.h"
1709467b48Spatrick #include "llvm/InitializePasses.h"
1809467b48Spatrick #include "llvm/Transforms/IPO.h"
1909467b48Spatrick #include "llvm/Transforms/IPO/Inliner.h"
2009467b48Spatrick 
2109467b48Spatrick using namespace llvm;
2209467b48Spatrick 
2309467b48Spatrick #define DEBUG_TYPE "inline"
2409467b48Spatrick 
2509467b48Spatrick namespace {
2609467b48Spatrick 
2709467b48Spatrick /// Actual inliner pass implementation.
2809467b48Spatrick ///
2909467b48Spatrick /// The common implementation of the inlining logic is shared between this
3009467b48Spatrick /// inliner pass and the always inliner pass. The two passes use different cost
3109467b48Spatrick /// analyses to determine when to inline.
3209467b48Spatrick class SimpleInliner : public LegacyInlinerBase {
3309467b48Spatrick 
3409467b48Spatrick   InlineParams Params;
3509467b48Spatrick 
3609467b48Spatrick public:
SimpleInliner()3709467b48Spatrick   SimpleInliner() : LegacyInlinerBase(ID), Params(llvm::getInlineParams()) {
3809467b48Spatrick     initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
3909467b48Spatrick   }
4009467b48Spatrick 
SimpleInliner(InlineParams Params)4109467b48Spatrick   explicit SimpleInliner(InlineParams Params)
4209467b48Spatrick       : LegacyInlinerBase(ID), Params(std::move(Params)) {
4309467b48Spatrick     initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
4409467b48Spatrick   }
4509467b48Spatrick 
4609467b48Spatrick   static char ID; // Pass identification, replacement for typeid
4709467b48Spatrick 
getInlineCost(CallBase & CB)48097a140dSpatrick   InlineCost getInlineCost(CallBase &CB) override {
49097a140dSpatrick     Function *Callee = CB.getCalledFunction();
5009467b48Spatrick     TargetTransformInfo &TTI = TTIWP->getTTI(*Callee);
5109467b48Spatrick 
5209467b48Spatrick     bool RemarksEnabled = false;
53*d415bd75Srobert     const auto &BBs = *CB.getCaller();
5409467b48Spatrick     if (!BBs.empty()) {
5509467b48Spatrick       auto DI = OptimizationRemark(DEBUG_TYPE, "", DebugLoc(), &BBs.front());
5609467b48Spatrick       if (DI.isEnabled())
5709467b48Spatrick         RemarksEnabled = true;
5809467b48Spatrick     }
59097a140dSpatrick     OptimizationRemarkEmitter ORE(CB.getCaller());
6009467b48Spatrick 
6109467b48Spatrick     std::function<AssumptionCache &(Function &)> GetAssumptionCache =
6209467b48Spatrick         [&](Function &F) -> AssumptionCache & {
6309467b48Spatrick       return ACT->getAssumptionCache(F);
6409467b48Spatrick     };
65097a140dSpatrick     return llvm::getInlineCost(CB, Params, TTI, GetAssumptionCache, GetTLI,
66097a140dSpatrick                                /*GetBFI=*/nullptr, PSI,
67097a140dSpatrick                                RemarksEnabled ? &ORE : nullptr);
6809467b48Spatrick   }
6909467b48Spatrick 
7009467b48Spatrick   bool runOnSCC(CallGraphSCC &SCC) override;
7109467b48Spatrick   void getAnalysisUsage(AnalysisUsage &AU) const override;
7209467b48Spatrick 
7309467b48Spatrick private:
7409467b48Spatrick   TargetTransformInfoWrapperPass *TTIWP;
7509467b48Spatrick 
7609467b48Spatrick };
7709467b48Spatrick 
7809467b48Spatrick } // end anonymous namespace
7909467b48Spatrick 
8009467b48Spatrick char SimpleInliner::ID = 0;
8109467b48Spatrick INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining",
8209467b48Spatrick                       false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)8309467b48Spatrick INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
8409467b48Spatrick INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
8509467b48Spatrick INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
8609467b48Spatrick INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
8709467b48Spatrick INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
8809467b48Spatrick INITIALIZE_PASS_END(SimpleInliner, "inline", "Function Integration/Inlining",
8909467b48Spatrick                     false, false)
9009467b48Spatrick 
9109467b48Spatrick Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
9209467b48Spatrick 
createFunctionInliningPass(int Threshold)9309467b48Spatrick Pass *llvm::createFunctionInliningPass(int Threshold) {
9409467b48Spatrick   return new SimpleInliner(llvm::getInlineParams(Threshold));
9509467b48Spatrick }
9609467b48Spatrick 
createFunctionInliningPass(unsigned OptLevel,unsigned SizeOptLevel,bool DisableInlineHotCallSite)9709467b48Spatrick Pass *llvm::createFunctionInliningPass(unsigned OptLevel,
9809467b48Spatrick                                        unsigned SizeOptLevel,
9909467b48Spatrick                                        bool DisableInlineHotCallSite) {
10009467b48Spatrick   auto Param = llvm::getInlineParams(OptLevel, SizeOptLevel);
10109467b48Spatrick   if (DisableInlineHotCallSite)
10209467b48Spatrick     Param.HotCallSiteThreshold = 0;
10309467b48Spatrick   return new SimpleInliner(Param);
10409467b48Spatrick }
10509467b48Spatrick 
createFunctionInliningPass(InlineParams & Params)10609467b48Spatrick Pass *llvm::createFunctionInliningPass(InlineParams &Params) {
10709467b48Spatrick   return new SimpleInliner(Params);
10809467b48Spatrick }
10909467b48Spatrick 
runOnSCC(CallGraphSCC & SCC)11009467b48Spatrick bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) {
11109467b48Spatrick   TTIWP = &getAnalysis<TargetTransformInfoWrapperPass>();
11209467b48Spatrick   return LegacyInlinerBase::runOnSCC(SCC);
11309467b48Spatrick }
11409467b48Spatrick 
getAnalysisUsage(AnalysisUsage & AU) const11509467b48Spatrick void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const {
11609467b48Spatrick   AU.addRequired<TargetTransformInfoWrapperPass>();
11709467b48Spatrick   LegacyInlinerBase::getAnalysisUsage(AU);
11809467b48Spatrick }
119