LLVM API Documentation
00001 //===- InlineCost.cpp - Cost analysis for inliner ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements heuristics for inlining decisions. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_TRANSFORMS_UTILS_INLINECOST_H 00015 #define LLVM_TRANSFORMS_UTILS_INLINECOST_H 00016 00017 #include "llvm/ADT/SmallPtrSet.h" 00018 #include <cassert> 00019 #include <map> 00020 #include <vector> 00021 00022 namespace llvm { 00023 00024 class Value; 00025 class Function; 00026 class CallSite; 00027 00028 /// InlineCost - Represent the cost of inlining a function. This 00029 /// supports special values for functions which should "always" or 00030 /// "never" be inlined. Otherwise, the cost represents a unitless 00031 /// amount; smaller values increase the likelyhood of the function 00032 /// being inlined. 00033 class InlineCost { 00034 enum Kind { 00035 Value, 00036 Always, 00037 Never 00038 }; 00039 00040 int Cost : 30; 00041 unsigned Type : 2; 00042 00043 InlineCost(int C, int T) : Cost(C), Type(T) { 00044 assert(Cost == C && "Cost exceeds InlineCost precision"); 00045 } 00046 public: 00047 static InlineCost get(int Cost) { return InlineCost(Cost, Value); } 00048 static InlineCost getAlways() { return InlineCost(0, Always); } 00049 static InlineCost getNever() { return InlineCost(0, Never); } 00050 00051 bool isVariable() const { return Type == Value; } 00052 bool isAlways() const { return Type == Always; } 00053 bool isNever() const { return Type == Never; } 00054 00055 /// getValue() - Return a "variable" inline cost's amount. It is 00056 /// an error to call this on an "always" or "never" InlineCost. 00057 int getValue() const { 00058 assert(Type == Value && "Invalid access of InlineCost"); 00059 return Cost; 00060 } 00061 }; 00062 00063 /// InlineCostAnalyzer - Cost analyzer used by inliner. 00064 class InlineCostAnalyzer { 00065 struct ArgInfo { 00066 public: 00067 unsigned ConstantWeight; 00068 unsigned AllocaWeight; 00069 00070 ArgInfo(unsigned CWeight, unsigned AWeight) 00071 : ConstantWeight(CWeight), AllocaWeight(AWeight) {} 00072 }; 00073 00074 // FunctionInfo - For each function, calculate the size of it in blocks and 00075 // instructions. 00076 struct FunctionInfo { 00077 /// NeverInline - True if this callee should never be inlined into a 00078 /// caller. 00079 bool NeverInline; 00080 00081 /// usesDynamicAlloca - True if this function calls alloca (in the C sense). 00082 bool usesDynamicAlloca; 00083 00084 /// NumInsts, NumBlocks - Keep track of how large each function is, which 00085 /// is used to estimate the code size cost of inlining it. 00086 unsigned NumInsts, NumBlocks; 00087 00088 /// NumVectorInsts - Keep track of how many instructions produce vector 00089 /// values. The inliner is being more aggressive with inlining vector 00090 /// kernels. 00091 unsigned NumVectorInsts; 00092 00093 /// ArgumentWeights - Each formal argument of the function is inspected to 00094 /// see if it is used in any contexts where making it a constant or alloca 00095 /// would reduce the code size. If so, we add some value to the argument 00096 /// entry here. 00097 std::vector<ArgInfo> ArgumentWeights; 00098 00099 FunctionInfo() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0), 00100 NumBlocks(0), NumVectorInsts(0) {} 00101 00102 /// analyzeFunction - Fill in the current structure with information 00103 /// gleaned from the specified function. 00104 void analyzeFunction(Function *F); 00105 00106 /// CountCodeReductionForConstant - Figure out an approximation for how 00107 /// many instructions will be constant folded if the specified value is 00108 /// constant. 00109 unsigned CountCodeReductionForConstant(Value *V); 00110 00111 /// CountCodeReductionForAlloca - Figure out an approximation of how much 00112 /// smaller the function will be if it is inlined into a context where an 00113 /// argument becomes an alloca. 00114 /// 00115 unsigned CountCodeReductionForAlloca(Value *V); 00116 }; 00117 00118 std::map<const Function *, FunctionInfo> CachedFunctionInfo; 00119 00120 public: 00121 00122 /// getInlineCost - The heuristic used to determine if we should inline the 00123 /// function call or not. 00124 /// 00125 InlineCost getInlineCost(CallSite CS, 00126 SmallPtrSet<const Function *, 16> &NeverInline); 00127 00128 /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a 00129 /// higher threshold to determine if the function call should be inlined. 00130 float getInlineFudgeFactor(CallSite CS); 00131 00132 /// resetCachedFunctionInfo - erase any cached cost info for this function. 00133 void resetCachedCostInfo(Function* Caller) { 00134 CachedFunctionInfo[Caller].NumBlocks = 0; 00135 } 00136 }; 00137 } 00138 00139 #endif