1 //===- InlineSimple.cpp - Code to perform simple function inlining --------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements bottom-up inlining of functions into callees.
11 //===----------------------------------------------------------------------===//
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/Transforms/IPO.h"
25 #include "llvm/Transforms/IPO/Inliner.h"
29 #define DEBUG_TYPE "inline"
33 /// Actual inliner pass implementation.
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.
38 class SimpleInliner
: public LegacyInlinerBase
{
43 SimpleInliner() : LegacyInlinerBase(ID
), Params(llvm::getInlineParams()) {
44 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
47 explicit SimpleInliner(InlineParams Params
)
48 : LegacyInlinerBase(ID
), Params(std::move(Params
)) {
49 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
52 static char ID
; // Pass identification, replacement for typeid
54 InlineCost
getInlineCost(CallSite CS
) override
{
55 Function
*Callee
= CS
.getCalledFunction();
56 TargetTransformInfo
&TTI
= TTIWP
->getTTI(*Callee
);
58 bool RemarksEnabled
= false;
59 const auto &BBs
= CS
.getCaller()->getBasicBlockList();
61 auto DI
= OptimizationRemark(DEBUG_TYPE
, "", DebugLoc(), &BBs
.front());
63 RemarksEnabled
= true;
65 OptimizationRemarkEmitter
ORE(CS
.getCaller());
67 std::function
<AssumptionCache
&(Function
&)> GetAssumptionCache
=
68 [&](Function
&F
) -> AssumptionCache
& {
69 return ACT
->getAssumptionCache(F
);
71 return llvm::getInlineCost(
72 cast
<CallBase
>(*CS
.getInstruction()), Params
, TTI
, GetAssumptionCache
,
73 /*GetBFI=*/None
, PSI
, RemarksEnabled
? &ORE
: nullptr);
76 bool runOnSCC(CallGraphSCC
&SCC
) override
;
77 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
80 TargetTransformInfoWrapperPass
*TTIWP
;
84 } // end anonymous namespace
86 char SimpleInliner::ID
= 0;
87 INITIALIZE_PASS_BEGIN(SimpleInliner
, "inline", "Function Integration/Inlining",
89 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker
)
90 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass
)
91 INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass
)
92 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass
)
93 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass
)
94 INITIALIZE_PASS_END(SimpleInliner
, "inline", "Function Integration/Inlining",
97 Pass
*llvm::createFunctionInliningPass() { return new SimpleInliner(); }
99 Pass
*llvm::createFunctionInliningPass(int Threshold
) {
100 return new SimpleInliner(llvm::getInlineParams(Threshold
));
103 Pass
*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
);
112 Pass
*llvm::createFunctionInliningPass(InlineParams
&Params
) {
113 return new SimpleInliner(Params
);
116 bool SimpleInliner::runOnSCC(CallGraphSCC
&SCC
) {
117 TTIWP
= &getAnalysis
<TargetTransformInfoWrapperPass
>();
118 return LegacyInlinerBase::runOnSCC(SCC
);
121 void SimpleInliner::getAnalysisUsage(AnalysisUsage
&AU
) const {
122 AU
.addRequired
<TargetTransformInfoWrapperPass
>();
123 LegacyInlinerBase::getAnalysisUsage(AU
);