InlineCost.h revision 43cda021d9425f53443b3d56bcf81afe99353ee9
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 <map>
20#include <vector>
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    /// NumVectorInsts - Keep track of how many instructions produce vector
46    /// values.  The inliner is being more aggressive with inlining vector
47    /// kernels.
48    unsigned NumVectorInsts;
49
50    /// NumRets - Keep track of how many Ret instructions the block contains.
51    unsigned NumRets;
52
53    CodeMetrics() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
54                    NumBlocks(0), NumVectorInsts(0), NumRets(0) {}
55
56    /// analyzeBasicBlock - Add information about the specified basic block
57    /// to the current structure.
58    void analyzeBasicBlock(const BasicBlock *BB);
59
60    /// analyzeFunction - Add information about the specified function
61    /// to the current structure.
62    void analyzeFunction(Function *F);
63  };
64
65  namespace InlineConstants {
66    // Various magic constants used to adjust heuristics.
67    const int InstrCost = 5;
68    const int IndirectCallBonus = 500;
69    const int CallPenalty = 5;  // In instrs, so multiply by InstrCost.
70    const int LastCallToStaticBonus = -15000;
71    const int ColdccPenalty = 2000;
72    const int NoreturnPenalty = 10000;
73  }
74
75  /// InlineCost - Represent the cost of inlining a function. This
76  /// supports special values for functions which should "always" or
77  /// "never" be inlined. Otherwise, the cost represents a unitless
78  /// amount; smaller values increase the likelyhood of the function
79  /// being inlined.
80  class InlineCost {
81    enum Kind {
82      Value,
83      Always,
84      Never
85    };
86
87    // This is a do-it-yourself implementation of
88    //   int Cost : 30;
89    //   unsigned Type : 2;
90    // We used to use bitfields, but they were sometimes miscompiled (PR3822).
91    enum { TYPE_BITS = 2 };
92    enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS };
93    unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS;
94
95    Kind getType() const {
96      return Kind(TypedCost >> COST_BITS);
97    }
98
99    int getCost() const {
100      // Sign-extend the bottom COST_BITS bits.
101      return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS;
102    }
103
104    InlineCost(int C, int T) {
105      TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS);
106      assert(getCost() == C && "Cost exceeds InlineCost precision");
107    }
108  public:
109    static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
110    static InlineCost getAlways() { return InlineCost(0, Always); }
111    static InlineCost getNever() { return InlineCost(0, Never); }
112
113    bool isVariable() const { return getType() == Value; }
114    bool isAlways() const { return getType() == Always; }
115    bool isNever() const { return getType() == Never; }
116
117    /// getValue() - Return a "variable" inline cost's amount. It is
118    /// an error to call this on an "always" or "never" InlineCost.
119    int getValue() const {
120      assert(getType() == Value && "Invalid access of InlineCost");
121      return getCost();
122    }
123  };
124
125  /// InlineCostAnalyzer - Cost analyzer used by inliner.
126  class InlineCostAnalyzer {
127    struct ArgInfo {
128    public:
129      unsigned ConstantWeight;
130      unsigned AllocaWeight;
131
132      ArgInfo(unsigned CWeight, unsigned AWeight)
133        : ConstantWeight(CWeight), AllocaWeight(AWeight) {}
134    };
135
136    struct FunctionInfo {
137      CodeMetrics Metrics;
138
139      /// ArgumentWeights - Each formal argument of the function is inspected to
140      /// see if it is used in any contexts where making it a constant or alloca
141      /// would reduce the code size.  If so, we add some value to the argument
142      /// entry here.
143      std::vector<ArgInfo> ArgumentWeights;
144
145      /// CountCodeReductionForConstant - Figure out an approximation for how
146      /// many instructions will be constant folded if the specified value is
147      /// constant.
148      unsigned CountCodeReductionForConstant(Value *V);
149
150      /// CountCodeReductionForAlloca - Figure out an approximation of how much
151      /// smaller the function will be if it is inlined into a context where an
152      /// argument becomes an alloca.
153      ///
154      unsigned CountCodeReductionForAlloca(Value *V);
155
156      /// analyzeFunction - Add information about the specified function
157      /// to the current structure.
158      void analyzeFunction(Function *F);
159    };
160
161    std::map<const Function *, FunctionInfo> CachedFunctionInfo;
162
163  public:
164
165    /// getInlineCost - The heuristic used to determine if we should inline the
166    /// function call or not.
167    ///
168    InlineCost getInlineCost(CallSite CS,
169                             SmallPtrSet<const Function *, 16> &NeverInline);
170
171    /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
172    /// higher threshold to determine if the function call should be inlined.
173    float getInlineFudgeFactor(CallSite CS);
174
175    /// resetCachedFunctionInfo - erase any cached cost info for this function.
176    void resetCachedCostInfo(Function* Caller) {
177      CachedFunctionInfo[Caller] = FunctionInfo();
178    }
179  };
180}
181
182#endif
183