InlineCost.h revision f72a53db4453a45aca282bd13c1f2dbe40a08466
1//===- InlineCost.cpp - Cost analysis for inliner ---------------*- C++ -*-===//
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 heuristics for inlining decisions.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_INLINECOST_H
15#define LLVM_ANALYSIS_INLINECOST_H
16
17#include <cassert>
18#include <climits>
19#include <vector>
20#include "llvm/ADT/DenseMap.h"
21
22namespace llvm {
23
24  class Value;
25  class Function;
26  class BasicBlock;
27  class CallSite;
28  template<class PtrType, unsigned SmallSize>
29  class SmallPtrSet;
30
31  // CodeMetrics - Calculate size and a few similar metrics for a set of
32  // basic blocks.
33  struct CodeMetrics {
34    /// NeverInline - True if this callee should never be inlined into a
35    /// caller.
36    bool NeverInline;
37
38    /// usesDynamicAlloca - True if this function calls alloca (in the C sense).
39    bool usesDynamicAlloca;
40
41    /// NumInsts, NumBlocks - Keep track of how large each function is, which
42    /// is used to estimate the code size cost of inlining it.
43    unsigned NumInsts, NumBlocks;
44
45    /// NumBBInsts - Keeps track of basic block code size estimates.
46    DenseMap<const BasicBlock *, unsigned> NumBBInsts;
47
48    /// NumCalls - Keep track of the number of calls to 'big' functions.
49    unsigned NumCalls;
50
51    /// NumVectorInsts - Keep track of how many instructions produce vector
52    /// values.  The inliner is being more aggressive with inlining vector
53    /// kernels.
54    unsigned NumVectorInsts;
55
56    /// NumRets - Keep track of how many Ret instructions the block contains.
57    unsigned NumRets;
58
59    CodeMetrics() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
60                    NumBlocks(0), NumCalls(0), NumVectorInsts(0), NumRets(0) {}
61
62    /// analyzeBasicBlock - Add information about the specified basic block
63    /// to the current structure.
64    void analyzeBasicBlock(const BasicBlock *BB);
65
66    /// analyzeFunction - Add information about the specified function
67    /// to the current structure.
68    void analyzeFunction(Function *F);
69  };
70
71  namespace InlineConstants {
72    // Various magic constants used to adjust heuristics.
73    const int InstrCost = 5;
74    const int IndirectCallBonus = 500;
75    const int CallPenalty = 25;
76    const int LastCallToStaticBonus = -15000;
77    const int ColdccPenalty = 2000;
78    const int NoreturnPenalty = 10000;
79  }
80
81  /// InlineCost - Represent the cost of inlining a function. This
82  /// supports special values for functions which should "always" or
83  /// "never" be inlined. Otherwise, the cost represents a unitless
84  /// amount; smaller values increase the likelyhood of the function
85  /// being inlined.
86  class InlineCost {
87    enum Kind {
88      Value,
89      Always,
90      Never
91    };
92
93    // This is a do-it-yourself implementation of
94    //   int Cost : 30;
95    //   unsigned Type : 2;
96    // We used to use bitfields, but they were sometimes miscompiled (PR3822).
97    enum { TYPE_BITS = 2 };
98    enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS };
99    unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS;
100
101    Kind getType() const {
102      return Kind(TypedCost >> COST_BITS);
103    }
104
105    int getCost() const {
106      // Sign-extend the bottom COST_BITS bits.
107      return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS;
108    }
109
110    InlineCost(int C, int T) {
111      TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS);
112      assert(getCost() == C && "Cost exceeds InlineCost precision");
113    }
114  public:
115    static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
116    static InlineCost getAlways() { return InlineCost(0, Always); }
117    static InlineCost getNever() { return InlineCost(0, Never); }
118
119    bool isVariable() const { return getType() == Value; }
120    bool isAlways() const { return getType() == Always; }
121    bool isNever() const { return getType() == Never; }
122
123    /// getValue() - Return a "variable" inline cost's amount. It is
124    /// an error to call this on an "always" or "never" InlineCost.
125    int getValue() const {
126      assert(getType() == Value && "Invalid access of InlineCost");
127      return getCost();
128    }
129  };
130
131  /// InlineCostAnalyzer - Cost analyzer used by inliner.
132  class InlineCostAnalyzer {
133    struct ArgInfo {
134    public:
135      unsigned ConstantWeight;
136      unsigned AllocaWeight;
137
138      ArgInfo(unsigned CWeight, unsigned AWeight)
139        : ConstantWeight(CWeight), AllocaWeight(AWeight) {}
140    };
141
142    struct FunctionInfo {
143      CodeMetrics Metrics;
144
145      /// ArgumentWeights - Each formal argument of the function is inspected to
146      /// see if it is used in any contexts where making it a constant or alloca
147      /// would reduce the code size.  If so, we add some value to the argument
148      /// entry here.
149      std::vector<ArgInfo> ArgumentWeights;
150
151      /// CountCodeReductionForConstant - Figure out an approximation for how
152      /// many instructions will be constant folded if the specified value is
153      /// constant.
154      unsigned CountCodeReductionForConstant(Value *V);
155
156      /// CountCodeReductionForAlloca - Figure out an approximation of how much
157      /// smaller the function will be if it is inlined into a context where an
158      /// argument becomes an alloca.
159      ///
160      unsigned CountCodeReductionForAlloca(Value *V);
161
162      /// analyzeFunction - Add information about the specified function
163      /// to the current structure.
164      void analyzeFunction(Function *F);
165    };
166
167    std::map<const Function *, FunctionInfo> CachedFunctionInfo;
168
169  public:
170
171    /// getInlineCost - The heuristic used to determine if we should inline the
172    /// function call or not.
173    ///
174    InlineCost getInlineCost(CallSite CS,
175                             SmallPtrSet<const Function *, 16> &NeverInline);
176
177    /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
178    /// higher threshold to determine if the function call should be inlined.
179    float getInlineFudgeFactor(CallSite CS);
180
181    /// resetCachedFunctionInfo - erase any cached cost info for this function.
182    void resetCachedCostInfo(Function* Caller) {
183      CachedFunctionInfo[Caller] = FunctionInfo();
184    }
185
186    /// growCachedCostInfo - update the cached cost info for Caller after Callee
187    /// has been inlined. If Callee is NULL it means a dead call has been
188    /// eliminated.
189    void growCachedCostInfo(Function* Caller, Function* Callee);
190  };
191
192  /// callIsSmall - If a call is likely to lower to a single target instruction,
193  /// or is otherwise deemed small return true.
194  bool callIsSmall(const Function *Callee);
195}
196
197#endif
198