//===- InlineCost.h - Cost analysis for inliner -----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements heuristics for inlining decisions.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_INLINECOST_H
#define LLVM_ANALYSIS_INLINECOST_H

#include <cassert>
#include <climits>
#include <vector>
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Analysis/CodeMetrics.h"

namespace llvm {

  class Value;
  class Function;
  class BasicBlock;
  class CallSite;
  template<class PtrType, unsigned SmallSize>
  class SmallPtrSet;
  class TargetData;

  namespace InlineConstants {
    // Various magic constants used to adjust heuristics.
    const int InstrCost = 5;
    const int IndirectCallBonus = -100;
    const int CallPenalty = 25;
    const int LastCallToStaticBonus = -15000;
    const int ColdccPenalty = 2000;
    const int NoreturnPenalty = 10000;
  }

  /// InlineCost - Represent the cost of inlining a function. This
  /// supports special values for functions which should "always" or
  /// "never" be inlined. Otherwise, the cost represents a unitless
  /// amount; smaller values increase the likelihood of the function
  /// being inlined.
  class InlineCost {
    enum Kind {
      Value,
      Always,
      Never
    };

    // This is a do-it-yourself implementation of
    //   int Cost : 30;
    //   unsigned Type : 2;
    // We used to use bitfields, but they were sometimes miscompiled (PR3822).
    enum { TYPE_BITS = 2 };
    enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS };
    unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS;

    Kind getType() const {
      return Kind(TypedCost >> COST_BITS);
    }

    int getCost() const {
      // Sign-extend the bottom COST_BITS bits.
      return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS;
    }

    InlineCost(int C, int T) {
      TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS);
      assert(getCost() == C && "Cost exceeds InlineCost precision");
    }
  public:
    static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
    static InlineCost getAlways() { return InlineCost(0, Always); }
    static InlineCost getNever() { return InlineCost(0, Never); }

    bool isVariable() const { return getType() == Value; }
    bool isAlways() const { return getType() == Always; }
    bool isNever() const { return getType() == Never; }

    /// getValue() - Return a "variable" inline cost's amount. It is
    /// an error to call this on an "always" or "never" InlineCost.
    int getValue() const {
      assert(getType() == Value && "Invalid access of InlineCost");
      return getCost();
    }
  };

  /// InlineCostAnalyzer - Cost analyzer used by inliner.
  class InlineCostAnalyzer {
    struct ArgInfo {
    public:
      unsigned ConstantWeight;
      unsigned AllocaWeight;

      ArgInfo(unsigned CWeight, unsigned AWeight)
        : ConstantWeight(CWeight), AllocaWeight(AWeight)
          {}
    };

    struct FunctionInfo {
      CodeMetrics Metrics;

      /// ArgumentWeights - Each formal argument of the function is inspected to
      /// see if it is used in any contexts where making it a constant or alloca
      /// would reduce the code size.  If so, we add some value to the argument
      /// entry here.
      std::vector<ArgInfo> ArgumentWeights;

      /// analyzeFunction - Add information about the specified function
      /// to the current structure.
      void analyzeFunction(Function *F, const TargetData *TD);

      /// NeverInline - Returns true if the function should never be
      /// inlined into any caller.
      bool NeverInline();
    };

    // The Function* for a function can be changed (by ArgumentPromotion);
    // the ValueMap will update itself when this happens.
    ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;

    // TargetData if available, or null.
    const TargetData *TD;

    int CountBonusForConstant(Value *V, Constant *C = NULL);
    int ConstantFunctionBonus(CallSite CS, Constant *C);
    int getInlineSize(CallSite CS, Function *Callee);
    int getInlineBonuses(CallSite CS, Function *Callee);
  public:
    InlineCostAnalyzer(): TD(0) {}

    void setTargetData(const TargetData *TData) { TD = TData; }

    /// getInlineCost - The heuristic used to determine if we should inline the
    /// function call or not.
    ///
    InlineCost getInlineCost(CallSite CS,
                             SmallPtrSet<const Function *, 16> &NeverInline);
    /// getCalledFunction - The heuristic used to determine if we should inline
    /// the function call or not.  The callee is explicitly specified, to allow
    /// you to calculate the cost of inlining a function via a pointer.  The
    /// result assumes that the inlined version will always be used.  You should
    /// weight it yourself in cases where this callee will not always be called.
    InlineCost getInlineCost(CallSite CS,
                             Function *Callee,
                             SmallPtrSet<const Function *, 16> &NeverInline);

    /// getSpecializationBonus - The heuristic used to determine the per-call
    /// performance boost for using a specialization of Callee with argument
    /// SpecializedArgNos replaced by a constant.
    int getSpecializationBonus(Function *Callee,
             SmallVectorImpl<unsigned> &SpecializedArgNo);

    /// getSpecializationCost - The heuristic used to determine the code-size
    /// impact of creating a specialized version of Callee with argument
    /// SpecializedArgNo replaced by a constant.
    InlineCost getSpecializationCost(Function *Callee,
               SmallVectorImpl<unsigned> &SpecializedArgNo);

    /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
    /// higher threshold to determine if the function call should be inlined.
    float getInlineFudgeFactor(CallSite CS);

    /// resetCachedFunctionInfo - erase any cached cost info for this function.
    void resetCachedCostInfo(Function* Caller) {
      CachedFunctionInfo[Caller] = FunctionInfo();
    }

    /// growCachedCostInfo - update the cached cost info for Caller after Callee
    /// has been inlined. If Callee is NULL it means a dead call has been
    /// eliminated.
    void growCachedCostInfo(Function* Caller, Function* Callee);

    /// clear - empty the cache of inline costs
    void clear();
  };

  /// callIsSmall - If a call is likely to lower to a single target instruction,
  /// or is otherwise deemed small return true.
  bool callIsSmall(const Function *Callee);
}

#endif
