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 @@ -270,6 +270,16 @@ ProfileSummaryInfo *PSI = nullptr, OptimizationRemarkEmitter *ORE = nullptr); +Optional> getInlineCostBenefitPair( + CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI, + function_ref GetAssumptionCache, + function_ref GetBFI, + ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE); + +Optional> +getInlineCostBenefitPair(CallBase &CB, FunctionAnalysisManager &FAM, + const InlineParams &Params); + /// Minimal filter to detect invalid constructs for inlining. InlineResult isInlineViable(Function &Callee); 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 @@ -491,6 +491,9 @@ // Whether inlining is decided by cost-benefit analysis. bool DecidedByCostBenefit = false; + // The cost-benefit pair computed by cost-benefit analysis. + std::pair CostBenefitPair; + bool SingleBB = true; unsigned SROACostSavings = 0; @@ -788,6 +791,8 @@ // savings threshold. Size = Size > InlineSizeAllowance ? Size - InlineSizeAllowance : 1; + CostBenefitPair = std::make_pair(APInt(128, Size), CycleSavings); + // Return true if the savings justify the cost of inlining. Specifically, // we evaluate the following inequality: // @@ -935,6 +940,7 @@ virtual ~InlineCostCallAnalyzer() {} int getThreshold() { return Threshold; } int getCost() { return Cost; } + std::pair getCostBenefitPair() { return CostBenefitPair; } bool wasDecidedByCostBenefit() { return DecidedByCostBenefit; } }; } // namespace @@ -2505,6 +2511,47 @@ return CA.getCost(); } +Optional> llvm::getInlineCostBenefitPair( + CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI, + function_ref GetAssumptionCache, + function_ref GetBFI, + ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) { + + InlineCostCallAnalyzer CA(*Call.getCalledFunction(), Call, Params, CalleeTTI, + GetAssumptionCache, GetBFI, PSI, ORE, true, + /*IgnoreThreshold*/ true); + auto R = CA.analyze(); + if (!R.isSuccess()) + return None; + return CA.getCostBenefitPair(); +} + +Optional> +llvm::getInlineCostBenefitPair(CallBase &CB, FunctionAnalysisManager &FAM, + const InlineParams &Params) { + Function &Caller = *CB.getCaller(); + ProfileSummaryInfo *PSI = + FAM.getResult(Caller) + .getCachedResult( + *CB.getParent()->getParent()->getParent()); + + auto &ORE = FAM.getResult(Caller); + auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & { + return FAM.getResult(F); + }; + auto GetBFI = [&](Function &F) -> BlockFrequencyInfo & { + return FAM.getResult(F); + }; + + Function &Callee = *CB.getCalledFunction(); + auto &CalleeTTI = FAM.getResult(Callee); + bool RemarksEnabled = + Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled( + DEBUG_TYPE); + return getInlineCostBenefitPair(CB, Params, CalleeTTI, GetAssumptionCache, + GetBFI, PSI, RemarksEnabled ? &ORE : nullptr); +} + Optional llvm::getAttributeBasedInliningDecision( CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI, function_ref GetTLI) {