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