- /// 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);
-
- /// 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;
-
- 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:
-
- /// 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();
- };
+ /// \brief Get the inline cost estimate.
+ /// It is an error to call this on an "always" or "never" InlineCost.
+ int getCost() const {
+ 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(); }
+};
+
+/// \brief Cost analyzer used by inliner.
+class InlineCostAnalysis : public CallGraphSCCPass {
+ const DataLayout *TD;
+ const TargetTransformInfo *TTI;
+
+public:
+ static char ID;
+
+ InlineCostAnalysis();
+ ~InlineCostAnalysis();
+
+ // Pass interface implementation.
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ bool runOnSCC(CallGraphSCC &SCC);
+
+ /// \brief Get an InlineCost object representing the cost of inlining this
+ /// callsite.
+ ///
+ /// Note that threshold is passed into this function. Only costs below the
+ /// threshold are computed with any accuracy. The threshold can be used to
+ /// bound the computation necessary to determine whether the cost is
+ /// sufficiently low to warrant inlining.
+ ///
+ /// Also note that calling this function *dynamically* computes the cost of
+ /// inlining the callsite. It is an expensive, heavyweight call.
+ InlineCost getInlineCost(CallSite CS, int Threshold);
+
+ /// \brief Get an InlineCost with the callee explicitly specified.
+ /// This allows 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);
+
+ /// \brief Minimal filter to detect invalid constructs for inlining.
+ bool isInlineViable(Function &Callee);
+};