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:
parent
bd7a7d5ff0
commit
4952863892
@ -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()) &&
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user