Fix inline cost predictions with SCIENCE.
[oota-llvm.git] / include / llvm / Analysis / 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_ANALYSIS_INLINECOST_H
15 #define LLVM_ANALYSIS_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 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