Use the attribute builder to add attributes to call/invoke instruction. No functional...
[oota-llvm.git] / include / llvm / Analysis / InlineCost.h
index c523890472a0bca640d936a35102997aede07c6c..a075db33427df8cc536643142464c2ff5b7a6360 100644 (file)
@@ -26,7 +26,7 @@
 namespace llvm {
 
   class CallSite;
-  class TargetData;
+  class DataLayout;
 
   namespace InlineConstants {
     // Various magic constants used to adjust heuristics.
@@ -36,6 +36,9 @@ namespace llvm {
     const int LastCallToStaticBonus = -15000;
     const int ColdccPenalty = 2000;
     const int NoreturnPenalty = 10000;
+    /// Do not inline functions which allocate this many bytes on the stack
+    /// when the caller is recursive.
+    const unsigned TotalAllocaSizeRecursiveCaller = 1024;
   }
 
   /// \brief Represents the cost of inlining a function.
@@ -49,70 +52,65 @@ namespace llvm {
   /// directly tested to determine if inlining should occur given the cost and
   /// threshold for this cost metric.
   class InlineCost {
-    enum CostKind {
-      CK_Variable,
-      CK_Always,
-      CK_Never
+    enum SentinelValues {
+      AlwaysInlineCost = INT_MIN,
+      NeverInlineCost = INT_MAX
     };
 
-    const int      Cost : 30; // The inlining cost if neither always nor never.
-    const unsigned Kind : 2;  // The type of cost, one of CostKind above.
+    /// \brief The estimated cost of inlining this callsite.
+    const int Cost;
 
-    /// \brief The adjusted threshold against which this cost should be tested.
+    /// \brief The adjusted threshold against which this cost was computed.
     const int Threshold;
 
     // Trivial constructor, interesting logic in the factory functions below.
-    InlineCost(int Cost, CostKind Kind, int Threshold)
-      : Cost(Cost), Kind(Kind), Threshold(Threshold) {}
+    InlineCost(int Cost, int Threshold)
+      : Cost(Cost), Threshold(Threshold) {}
 
   public:
     static InlineCost get(int Cost, int Threshold) {
-      InlineCost Result(Cost, CK_Variable, Threshold);
-      assert(Result.Cost == Cost && "Cost exceeds InlineCost precision");
-      return Result;
+      assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
+      assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
+      return InlineCost(Cost, Threshold);
     }
     static InlineCost getAlways() {
-      return InlineCost(0, CK_Always, 0);
+      return InlineCost(AlwaysInlineCost, 0);
     }
     static InlineCost getNever() {
-      return InlineCost(0, CK_Never, 0);
+      return InlineCost(NeverInlineCost, 0);
     }
 
     /// \brief Test whether the inline cost is low enough for inlining.
     operator bool() const {
-      if (isAlways()) return true;
-      if (isNever()) return false;
       return Cost < Threshold;
     }
 
-    bool isVariable() const { return Kind == CK_Variable; }
-    bool isAlways() const   { return Kind == CK_Always; }
-    bool isNever() const    { return Kind == CK_Never; }
+    bool isAlways() const   { return Cost == AlwaysInlineCost; }
+    bool isNever() const    { return Cost == NeverInlineCost; }
+    bool isVariable() const { return !isAlways() && !isNever(); }
 
-    /// getCost() - Return a "variable" inline cost's amount. It is
-    /// an error to call this on an "always" or "never" InlineCost.
+    /// \brief Get the inline cost estimate.
+    /// It is an error to call this on an "always" or "never" InlineCost.
     int getCost() const {
-      assert(Kind == CK_Variable && "Invalid access of InlineCost");
+      assert(isVariable() && "Invalid access of InlineCost");
       return Cost;
     }
 
     /// \brief Get the cost delta from the threshold for inlining.
     /// Only valid if the cost is of the variable kind. Returns a negative
     /// value if the cost is too high to inline.
-    int getCostDelta() const {
-      return Threshold - getCost();
-    }
+    int getCostDelta() const { return Threshold - getCost(); }
   };
 
   /// InlineCostAnalyzer - Cost analyzer used by inliner.
   class InlineCostAnalyzer {
-    // TargetData if available, or null.
-    const TargetData *TD;
+    // DataLayout if available, or null.
+    const DataLayout *TD;
 
   public:
     InlineCostAnalyzer(): TD(0) {}
 
-    void setTargetData(const TargetData *TData) { TD = TData; }
+    void setDataLayout(const DataLayout *TData) { TD = TData; }
 
     /// \brief Get an InlineCost object representing the cost of inlining this
     /// callsite.
@@ -122,23 +120,16 @@ namespace llvm {
     /// bound the computation necessary to determine whether the cost is
     /// sufficiently low to warrant inlining.
     InlineCost getInlineCost(CallSite CS, int Threshold);
-
-    /// resetCachedFunctionInfo - erase any cached cost info for this function.
-    void resetCachedCostInfo(Function* Caller) {
-    }
-
-    /// 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();
+    /// 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.  This
+    /// behaves exactly as the version with no explicit callee parameter in all
+    /// other respects.
+    //
+    //  Note: This is used by out-of-tree passes, please do not remove without
+    //  adding a replacement API.
+    InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
   };
-
-  /// 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