diff --git a/llvm/include/llvm/Analysis/InlineCost.h b/llvm/include/llvm/Analysis/InlineCost.h --- a/llvm/include/llvm/Analysis/InlineCost.h +++ b/llvm/include/llvm/Analysis/InlineCost.h @@ -95,6 +95,9 @@ /// The adjusted threshold against which this cost was computed. int Threshold = 0; + /// The amount of StaticBonus that has been applied. + int StaticBonusApplied = 0; + /// Must be set for Always and Never instances. const char *Reason = nullptr; @@ -102,27 +105,29 @@ Optional CostBenefit = None; // Trivial constructor, interesting logic in the factory functions below. - InlineCost(int Cost, int Threshold, const char *Reason = nullptr, + InlineCost(int Cost, int Threshold, int StaticBonusApplied, + const char *Reason = nullptr, Optional CostBenefit = None) - : Cost(Cost), Threshold(Threshold), Reason(Reason), + : Cost(Cost), Threshold(Threshold), + StaticBonusApplied(StaticBonusApplied), Reason(Reason), CostBenefit(CostBenefit) { assert((isVariable() || Reason) && "Reason must be provided for Never or Always"); } public: - static InlineCost get(int Cost, int Threshold) { + static InlineCost get(int Cost, int Threshold, int StaticBonus = 0) { assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value"); assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); - return InlineCost(Cost, Threshold); + return InlineCost(Cost, Threshold, StaticBonus); } static InlineCost getAlways(const char *Reason, Optional CostBenefit = None) { - return InlineCost(AlwaysInlineCost, 0, Reason, CostBenefit); + return InlineCost(AlwaysInlineCost, 0, 0, Reason, CostBenefit); } static InlineCost getNever(const char *Reason, Optional CostBenefit = None) { - return InlineCost(NeverInlineCost, 0, Reason, CostBenefit); + return InlineCost(NeverInlineCost, 0, 0, Reason, CostBenefit); } /// Test whether the inline cost is low enough for inlining. @@ -145,6 +150,12 @@ return Threshold; } + /// Get the amount of StaticBonus applied. + int getStaticBonusApplied() const { + assert(isVariable() && "Invalid access of InlineCost"); + return StaticBonusApplied; + } + /// Get the cost-benefit pair which was computed by cost-benefit analysis Optional getCostBenefit() const { return CostBenefit; } diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -549,6 +549,9 @@ /// for speculative "expected profit" of the inlining decision. int Threshold = 0; + /// The amount of StaticBonus applied. + int StaticBonusApplied = 0; + /// Attempt to evaluate indirect calls to boost its inline cost. const bool BoostIndirectCalls; @@ -1058,6 +1061,7 @@ virtual ~InlineCostCallAnalyzer() = default; int getThreshold() const { return Threshold; } int getCost() const { return Cost; } + int getStaticBonusApplied() const { return StaticBonusApplied; } Optional getCostBenefitPair() { return CostBenefit; } bool wasDecidedByCostBenefit() const { return DecidedByCostBenefit; } bool wasDecidedByCostThreshold() const { return DecidedByCostThreshold; } @@ -1922,8 +1926,10 @@ // If there is only one call of the function, and it has internal linkage, // the cost of inlining it drops dramatically. It may seem odd to update // Cost in updateThreshold, but the bonus depends on the logic in this method. - if (isSoleCallToLocalFunction(Call, F)) + if (isSoleCallToLocalFunction(Call, F)) { Cost -= LastCallToStaticBonus; + StaticBonusApplied = LastCallToStaticBonus; + } } bool CallAnalyzer::visitCmpInst(CmpInst &I) { @@ -2970,7 +2976,8 @@ } if (CA.wasDecidedByCostThreshold()) - return InlineCost::get(CA.getCost(), CA.getThreshold()); + return InlineCost::get(CA.getCost(), CA.getThreshold(), + CA.getStaticBonusApplied()); // No details on how the decision was made, simply return always or never. return ShouldInline.isSuccess()