InlineSimple.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1//===- InlineSimple.cpp - Code to perform simple function inlining --------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements bottom-up inlining of functions into callees.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Transforms/IPO.h"
15#include "llvm/Analysis/CallGraph.h"
16#include "llvm/Analysis/InlineCost.h"
17#include "llvm/IR/CallSite.h"
18#include "llvm/IR/CallingConv.h"
19#include "llvm/IR/DataLayout.h"
20#include "llvm/IR/Instructions.h"
21#include "llvm/IR/IntrinsicInst.h"
22#include "llvm/IR/Module.h"
23#include "llvm/IR/Type.h"
24#include "llvm/Transforms/IPO/InlinerPass.h"
25
26using namespace llvm;
27
28#define DEBUG_TYPE "inline"
29
30namespace {
31
32/// \brief Actual inliner pass implementation.
33///
34/// The common implementation of the inlining logic is shared between this
35/// inliner pass and the always inliner pass. The two passes use different cost
36/// analyses to determine when to inline.
37class SimpleInliner : public Inliner {
38  InlineCostAnalysis *ICA;
39
40public:
41  SimpleInliner() : Inliner(ID), ICA(nullptr) {
42    initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
43  }
44
45  SimpleInliner(int Threshold)
46      : Inliner(ID, Threshold, /*InsertLifetime*/ true), ICA(nullptr) {
47    initializeSimpleInlinerPass(*PassRegistry::getPassRegistry());
48  }
49
50  static char ID; // Pass identification, replacement for typeid
51
52  InlineCost getInlineCost(CallSite CS) override {
53    return ICA->getInlineCost(CS, getInlineThreshold(CS));
54  }
55
56  bool runOnSCC(CallGraphSCC &SCC) override;
57  void getAnalysisUsage(AnalysisUsage &AU) const override;
58};
59
60static int computeThresholdFromOptLevels(unsigned OptLevel,
61                                         unsigned SizeOptLevel) {
62  if (OptLevel > 2)
63    return 275;
64  if (SizeOptLevel == 1) // -Os
65    return 75;
66  if (SizeOptLevel == 2) // -Oz
67    return 25;
68  return 225;
69}
70
71} // end anonymous namespace
72
73char SimpleInliner::ID = 0;
74INITIALIZE_PASS_BEGIN(SimpleInliner, "inline",
75                "Function Integration/Inlining", false, false)
76INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
77INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis)
78INITIALIZE_PASS_END(SimpleInliner, "inline",
79                "Function Integration/Inlining", false, false)
80
81Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
82
83Pass *llvm::createFunctionInliningPass(int Threshold) {
84  return new SimpleInliner(Threshold);
85}
86
87Pass *llvm::createFunctionInliningPass(unsigned OptLevel,
88                                       unsigned SizeOptLevel) {
89  return new SimpleInliner(
90      computeThresholdFromOptLevels(OptLevel, SizeOptLevel));
91}
92
93bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) {
94  ICA = &getAnalysis<InlineCostAnalysis>();
95  return Inliner::runOnSCC(SCC);
96}
97
98void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const {
99  AU.addRequired<InlineCostAnalysis>();
100  Inliner::getAnalysisUsage(AU);
101}
102