reduce header #include'age
[oota-llvm.git] / include / llvm / Transforms / Utils / InlineCost.h
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_TRANSFORMS_UTILS_INLINECOST_H
15 #define LLVM_TRANSFORMS_UTILS_INLINECOST_H
16
17 #include <cassert>
18 #include <climits>
19 #include <map>
20 #include <vector>
21
22 namespace llvm {
23
24   class Value;
25   class Function;
26   class CallSite;
27   template<class PtrType, unsigned SmallSize>
28   class SmallPtrSet;
29
30   /// InlineCost - Represent the cost of inlining a function. This
31   /// supports special values for functions which should "always" or
32   /// "never" be inlined. Otherwise, the cost represents a unitless
33   /// amount; smaller values increase the likelyhood of the function
34   /// being inlined.
35   class InlineCost {
36     enum Kind {
37       Value,
38       Always,
39       Never
40     };
41
42     // This is a do-it-yourself implementation of
43     //   int Cost : 30;
44     //   unsigned Type : 2;
45     // We used to use bitfields, but they were sometimes miscompiled (PR3822).
46     enum { TYPE_BITS = 2 };
47     enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS };
48     unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS;
49
50     Kind getType() const {
51       return Kind(TypedCost >> COST_BITS);
52     }
53
54     int getCost() const {
55       // Sign-extend the bottom COST_BITS bits.
56       return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS;
57     }
58
59     InlineCost(int C, int T) {
60       TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS);
61       assert(getCost() == C && "Cost exceeds InlineCost precision");
62     }
63   public:
64     static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
65     static InlineCost getAlways() { return InlineCost(0, Always); }
66     static InlineCost getNever() { return InlineCost(0, Never); }
67
68     bool isVariable() const { return getType() == Value; }
69     bool isAlways() const { return getType() == Always; }
70     bool isNever() const { return getType() == Never; }
71
72     /// getValue() - Return a "variable" inline cost's amount. It is
73     /// an error to call this on an "always" or "never" InlineCost.
74     int getValue() const {
75       assert(getType() == Value && "Invalid access of InlineCost");
76       return getCost();
77     }
78   };
79   
80   /// InlineCostAnalyzer - Cost analyzer used by inliner.
81   class InlineCostAnalyzer {
82     struct ArgInfo {
83     public:
84       unsigned ConstantWeight;
85       unsigned AllocaWeight;
86       
87       ArgInfo(unsigned CWeight, unsigned AWeight)
88         : ConstantWeight(CWeight), AllocaWeight(AWeight) {}
89     };
90     
91     // FunctionInfo - For each function, calculate the size of it in blocks and
92     // instructions.
93     struct FunctionInfo {
94       /// NeverInline - True if this callee should never be inlined into a
95       /// caller.
96       bool NeverInline;
97       
98       /// usesDynamicAlloca - True if this function calls alloca (in the C sense).
99       bool usesDynamicAlloca;
100
101       /// NumInsts, NumBlocks - Keep track of how large each function is, which
102       /// is used to estimate the code size cost of inlining it.
103       unsigned NumInsts, NumBlocks;
104
105       /// NumVectorInsts - Keep track of how many instructions produce vector
106       /// values.  The inliner is being more aggressive with inlining vector
107       /// kernels.
108       unsigned NumVectorInsts;
109       
110       /// ArgumentWeights - Each formal argument of the function is inspected to
111       /// see if it is used in any contexts where making it a constant or alloca
112       /// would reduce the code size.  If so, we add some value to the argument
113       /// entry here.
114       std::vector<ArgInfo> ArgumentWeights;
115       
116       FunctionInfo() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
117                        NumBlocks(0), NumVectorInsts(0) {}
118       
119       /// analyzeFunction - Fill in the current structure with information
120       /// gleaned from the specified function.
121       void analyzeFunction(Function *F);
122
123       /// CountCodeReductionForConstant - Figure out an approximation for how
124       /// many instructions will be constant folded if the specified value is
125       /// constant.
126       unsigned CountCodeReductionForConstant(Value *V);
127       
128       /// CountCodeReductionForAlloca - Figure out an approximation of how much
129       /// smaller the function will be if it is inlined into a context where an
130       /// argument becomes an alloca.
131       ///
132       unsigned CountCodeReductionForAlloca(Value *V);
133     };
134
135     std::map<const Function *, FunctionInfo> CachedFunctionInfo;
136
137   public:
138
139     /// getInlineCost - The heuristic used to determine if we should inline the
140     /// function call or not.
141     ///
142     InlineCost getInlineCost(CallSite CS,
143                              SmallPtrSet<const Function *, 16> &NeverInline);
144
145     /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
146     /// higher threshold to determine if the function call should be inlined.
147     float getInlineFudgeFactor(CallSite CS);
148
149     /// resetCachedFunctionInfo - erase any cached cost info for this function.
150     void resetCachedCostInfo(Function* Caller) {
151       CachedFunctionInfo[Caller].NumBlocks = 0;
152     }
153   };
154 }
155
156 #endif