1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[llvm][Inline] Add interface to return cost-benefit stuff

Return cost-benefit stuff which is computed by cost-benefit analysis.

Reviewed By: mtrofin

Differential Revision: https://reviews.llvm.org/D105349
This commit is contained in:
Liqiang Tao 2021-07-25 20:17:30 +08:00
parent bd7a7d5ff0
commit 4952863892
2 changed files with 41 additions and 8 deletions

View File

@ -55,6 +55,22 @@ const unsigned TotalAllocaSizeRecursiveCaller = 1024;
const uint64_t MaxSimplifiedDynamicAllocaToInline = 65536;
} // namespace InlineConstants
// The cost-benefit pair computed by cost-benefit analysis.
class CostBenefitPair {
public:
CostBenefitPair(APInt Cost, APInt Benefit) : Cost(Cost), Benefit(Benefit) {}
CostBenefitPair(const CostBenefitPair &CBP)
: Cost(CBP.getCost()), Benefit(CBP.getBenefit()) {}
const APInt &getCost() const { return Cost; }
const APInt &getBenefit() const { return Benefit; }
private:
APInt Cost;
APInt Benefit;
};
/// Represents the cost of inlining a function.
///
/// This supports special values for functions which should "always" or
@ -77,9 +93,14 @@ class InlineCost {
/// Must be set for Always and Never instances.
const char *Reason = nullptr;
/// The cost-benefit pair computed by cost-benefit analysis.
Optional<CostBenefitPair> CostBenefit = None;
// Trivial constructor, interesting logic in the factory functions below.
InlineCost(int Cost, int Threshold, const char *Reason = nullptr)
: Cost(Cost), Threshold(Threshold), Reason(Reason) {
InlineCost(int Cost, int Threshold, const char *Reason = nullptr,
Optional<CostBenefitPair> CostBenefit = None)
: Cost(Cost), Threshold(Threshold), Reason(Reason),
CostBenefit(CostBenefit) {
assert((isVariable() || Reason) &&
"Reason must be provided for Never or Always");
}
@ -90,11 +111,13 @@ public:
assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
return InlineCost(Cost, Threshold);
}
static InlineCost getAlways(const char *Reason) {
return InlineCost(AlwaysInlineCost, 0, Reason);
static InlineCost getAlways(const char *Reason,
Optional<CostBenefitPair> CostBenefit = None) {
return InlineCost(AlwaysInlineCost, 0, Reason, CostBenefit);
}
static InlineCost getNever(const char *Reason) {
return InlineCost(NeverInlineCost, 0, Reason);
static InlineCost getNever(const char *Reason,
Optional<CostBenefitPair> CostBenefit = None) {
return InlineCost(NeverInlineCost, 0, Reason, CostBenefit);
}
/// Test whether the inline cost is low enough for inlining.
@ -117,6 +140,9 @@ public:
return Threshold;
}
/// Get the cost-benefit pair which was computed by cost-benefit analysis
Optional<CostBenefitPair> getCostBenefit() const { return CostBenefit; }
/// Get the reason of Always or Never.
const char *getReason() const {
assert((Reason || isVariable()) &&

View File

@ -509,6 +509,9 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
// Whether inlining is decided by cost-benefit analysis.
bool DecidedByCostBenefit = false;
// The cost-benefit pair computed by cost-benefit analysis.
Optional<CostBenefitPair> CostBenefit = None;
bool SingleBB = true;
unsigned SROACostSavings = 0;
@ -794,6 +797,8 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
// savings threshold.
Size = Size > InlineSizeAllowance ? Size - InlineSizeAllowance : 1;
CostBenefit.emplace(APInt(128, Size), CycleSavings);
// Return true if the savings justify the cost of inlining. Specifically,
// we evaluate the following inequality:
//
@ -941,6 +946,7 @@ public:
virtual ~InlineCostCallAnalyzer() {}
int getThreshold() const { return Threshold; }
int getCost() const { return Cost; }
Optional<CostBenefitPair> getCostBenefitPair() { return CostBenefit; }
bool wasDecidedByCostBenefit() const { return DecidedByCostBenefit; }
};
@ -2834,9 +2840,10 @@ InlineCost llvm::getInlineCost(
// as it's not what drives cost-benefit analysis.
if (CA.wasDecidedByCostBenefit()) {
if (ShouldInline.isSuccess())
return InlineCost::getAlways("benefit over cost");
return InlineCost::getAlways("benefit over cost",
CA.getCostBenefitPair());
else
return InlineCost::getNever("cost over benefit");
return InlineCost::getNever("cost over benefit", CA.getCostBenefitPair());
}
// Check if there was a reason to force inlining or no inlining.