forked from OSchip/llvm-project
[Analysis] Introduce getStaticBonusApplied (NFC)
InlineCostCallAnalyzer encourages inlining of the last call to the static function by subtracting LastCallToStaticBonus from Cost. This patch introduces getStaticBonusApplied to make available the amount of LastCallToStaticBonus applied. The intent is to allow the module inliner to determine whether inlining a given call site is expected to reduce the caller size with an expression like: IC.getCost() + IC.getStaticBonusApplied() < 0 This patch does not add a use of getStaticBonus yet. Differential Revision: https://reviews.llvm.org/D134373
This commit is contained in:
parent
06b1e5fdc3
commit
e2398a4d7c
|
@ -95,6 +95,9 @@ class InlineCost {
|
|||
/// 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 @@ class InlineCost {
|
|||
Optional<CostBenefitPair> 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<CostBenefitPair> 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<CostBenefitPair> CostBenefit = None) {
|
||||
return InlineCost(AlwaysInlineCost, 0, Reason, CostBenefit);
|
||||
return InlineCost(AlwaysInlineCost, 0, 0, Reason, CostBenefit);
|
||||
}
|
||||
static InlineCost getNever(const char *Reason,
|
||||
Optional<CostBenefitPair> 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 @@ public:
|
|||
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<CostBenefitPair> getCostBenefit() const { return CostBenefit; }
|
||||
|
||||
|
|
|
@ -549,6 +549,9 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
|
|||
/// 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 @@ public:
|
|||
virtual ~InlineCostCallAnalyzer() = default;
|
||||
int getThreshold() const { return Threshold; }
|
||||
int getCost() const { return Cost; }
|
||||
int getStaticBonusApplied() const { return StaticBonusApplied; }
|
||||
Optional<CostBenefitPair> getCostBenefitPair() { return CostBenefit; }
|
||||
bool wasDecidedByCostBenefit() const { return DecidedByCostBenefit; }
|
||||
bool wasDecidedByCostThreshold() const { return DecidedByCostThreshold; }
|
||||
|
@ -1922,8 +1926,10 @@ void InlineCostCallAnalyzer::updateThreshold(CallBase &Call, Function &Callee) {
|
|||
// 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 @@ InlineCost llvm::getInlineCost(
|
|||
}
|
||||
|
||||
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()
|
||||
|
|
Loading…
Reference in New Issue