Home | History | Annotate | Download | only in Analysis
      1 //===- InlineCost.h - 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 <vector>
     20 #include "llvm/ADT/DenseMap.h"
     21 #include "llvm/ADT/ValueMap.h"
     22 #include "llvm/Analysis/CodeMetrics.h"
     23 
     24 namespace llvm {
     25 
     26   class Value;
     27   class Function;
     28   class BasicBlock;
     29   class CallSite;
     30   template<class PtrType, unsigned SmallSize>
     31   class SmallPtrSet;
     32 
     33   namespace InlineConstants {
     34     // Various magic constants used to adjust heuristics.
     35     const int InstrCost = 5;
     36     const int IndirectCallBonus = -100;
     37     const int CallPenalty = 25;
     38     const int LastCallToStaticBonus = -15000;
     39     const int ColdccPenalty = 2000;
     40     const int NoreturnPenalty = 10000;
     41   }
     42 
     43   /// InlineCost - Represent the cost of inlining a function. This
     44   /// supports special values for functions which should "always" or
     45   /// "never" be inlined. Otherwise, the cost represents a unitless
     46   /// amount; smaller values increase the likelihood of the function
     47   /// being inlined.
     48   class InlineCost {
     49     enum Kind {
     50       Value,
     51       Always,
     52       Never
     53     };
     54 
     55     // This is a do-it-yourself implementation of
     56     //   int Cost : 30;
     57     //   unsigned Type : 2;
     58     // We used to use bitfields, but they were sometimes miscompiled (PR3822).
     59     enum { TYPE_BITS = 2 };
     60     enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS };
     61     unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS;
     62 
     63     Kind getType() const {
     64       return Kind(TypedCost >> COST_BITS);
     65     }
     66 
     67     int getCost() const {
     68       // Sign-extend the bottom COST_BITS bits.
     69       return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS;
     70     }
     71 
     72     InlineCost(int C, int T) {
     73       TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS);
     74       assert(getCost() == C && "Cost exceeds InlineCost precision");
     75     }
     76   public:
     77     static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
     78     static InlineCost getAlways() { return InlineCost(0, Always); }
     79     static InlineCost getNever() { return InlineCost(0, Never); }
     80 
     81     bool isVariable() const { return getType() == Value; }
     82     bool isAlways() const { return getType() == Always; }
     83     bool isNever() const { return getType() == Never; }
     84 
     85     /// getValue() - Return a "variable" inline cost's amount. It is
     86     /// an error to call this on an "always" or "never" InlineCost.
     87     int getValue() const {
     88       assert(getType() == Value && "Invalid access of InlineCost");
     89       return getCost();
     90     }
     91   };
     92 
     93   /// InlineCostAnalyzer - Cost analyzer used by inliner.
     94   class InlineCostAnalyzer {
     95     struct ArgInfo {
     96     public:
     97       unsigned ConstantWeight;
     98       unsigned AllocaWeight;
     99 
    100       ArgInfo(unsigned CWeight, unsigned AWeight)
    101         : ConstantWeight(CWeight), AllocaWeight(AWeight)
    102           {}
    103     };
    104 
    105     struct FunctionInfo {
    106       CodeMetrics Metrics;
    107 
    108       /// ArgumentWeights - Each formal argument of the function is inspected to
    109       /// see if it is used in any contexts where making it a constant or alloca
    110       /// would reduce the code size.  If so, we add some value to the argument
    111       /// entry here.
    112       std::vector<ArgInfo> ArgumentWeights;
    113 
    114       /// analyzeFunction - Add information about the specified function
    115       /// to the current structure.
    116       void analyzeFunction(Function *F);
    117 
    118       /// NeverInline - Returns true if the function should never be
    119       /// inlined into any caller.
    120       bool NeverInline();
    121     };
    122 
    123     // The Function* for a function can be changed (by ArgumentPromotion);
    124     // the ValueMap will update itself when this happens.
    125     ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;
    126 
    127     int CountBonusForConstant(Value *V, Constant *C = NULL);
    128     int ConstantFunctionBonus(CallSite CS, Constant *C);
    129     int getInlineSize(CallSite CS, Function *Callee);
    130     int getInlineBonuses(CallSite CS, Function *Callee);
    131   public:
    132 
    133     /// getInlineCost - The heuristic used to determine if we should inline the
    134     /// function call or not.
    135     ///
    136     InlineCost getInlineCost(CallSite CS,
    137                              SmallPtrSet<const Function *, 16> &NeverInline);
    138     /// getCalledFunction - The heuristic used to determine if we should inline
    139     /// the function call or not.  The callee is explicitly specified, to allow
    140     /// you to calculate the cost of inlining a function via a pointer.  The
    141     /// result assumes that the inlined version will always be used.  You should
    142     /// weight it yourself in cases where this callee will not always be called.
    143     InlineCost getInlineCost(CallSite CS,
    144                              Function *Callee,
    145                              SmallPtrSet<const Function *, 16> &NeverInline);
    146 
    147     /// getSpecializationBonus - The heuristic used to determine the per-call
    148     /// performance boost for using a specialization of Callee with argument
    149     /// SpecializedArgNos replaced by a constant.
    150     int getSpecializationBonus(Function *Callee,
    151              SmallVectorImpl<unsigned> &SpecializedArgNo);
    152 
    153     /// getSpecializationCost - The heuristic used to determine the code-size
    154     /// impact of creating a specialized version of Callee with argument
    155     /// SpecializedArgNo replaced by a constant.
    156     InlineCost getSpecializationCost(Function *Callee,
    157                SmallVectorImpl<unsigned> &SpecializedArgNo);
    158 
    159     /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
    160     /// higher threshold to determine if the function call should be inlined.
    161     float getInlineFudgeFactor(CallSite CS);
    162 
    163     /// resetCachedFunctionInfo - erase any cached cost info for this function.
    164     void resetCachedCostInfo(Function* Caller) {
    165       CachedFunctionInfo[Caller] = FunctionInfo();
    166     }
    167 
    168     /// growCachedCostInfo - update the cached cost info for Caller after Callee
    169     /// has been inlined. If Callee is NULL it means a dead call has been
    170     /// eliminated.
    171     void growCachedCostInfo(Function* Caller, Function* Callee);
    172 
    173     /// clear - empty the cache of inline costs
    174     void clear();
    175   };
    176 
    177   /// callIsSmall - If a call is likely to lower to a single target instruction,
    178   /// or is otherwise deemed small return true.
    179   bool callIsSmall(const Function *Callee);
    180 }
    181 
    182 #endif
    183