LLVM API Documentation

InlineCost.h

Go to the documentation of this file.
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