[llvm] 201498c - [llvm][NFC] Factor out cost-model independent inling decision
Mircea Trofin via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 23 11:15:09 PDT 2020
Author: Mircea Trofin
Date: 2020-04-23T10:58:43-07:00
New Revision: 201498c6f34ef1a052d9c3f46cfdf4263606f232
URL: https://github.com/llvm/llvm-project/commit/201498c6f34ef1a052d9c3f46cfdf4263606f232
DIFF: https://github.com/llvm/llvm-project/commit/201498c6f34ef1a052d9c3f46cfdf4263606f232.diff
LOG: [llvm][NFC] Factor out cost-model independent inling decision
Summary:
llvm::getInlineCost starts off by determining whether inlining should
happen or not because of user directives or easily determinable
unviability. This CL refactors this functionality as a reusable API.
Reviewers: davidxl, eraman
Reviewed By: davidxl, eraman
Subscribers: hiraditya, haicheng, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D73825
Added:
Modified:
llvm/include/llvm/Analysis/InlineCost.h
llvm/lib/Analysis/InlineCost.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/InlineCost.h b/llvm/include/llvm/Analysis/InlineCost.h
index 0900162fa9d5..df3bc1b87921 100644
--- a/llvm/include/llvm/Analysis/InlineCost.h
+++ b/llvm/include/llvm/Analysis/InlineCost.h
@@ -236,6 +236,16 @@ getInlineCost(CallBase &Call, Function *Callee, const InlineParams &Params,
function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE);
+/// Returns InlineResult::success() if the call site should be always inlined
+/// because of user directives, and the inlining is viable. Returns
+/// InlineResult::failure() if the inlining may never happen because of user
+/// directives or incompatibilities detectable without needing callee traversal.
+/// Otherwise returns None, meaning that inlining should be decided based on
+/// other criteria (e.g. cost modeling).
+Optional<InlineResult> getAttributeBasedInliningDecision(
+ CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI);
+
/// Minimal filter to detect invalid constructs for inlining.
InlineResult isInlineViable(Function &Callee);
} // namespace llvm
diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index 548def45eccb..e247d8f48df2 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -2215,17 +2215,13 @@ InlineCost llvm::getInlineCost(
GetAssumptionCache, GetBFI, GetTLI, PSI, ORE);
}
-InlineCost llvm::getInlineCost(
- CallBase &Call, Function *Callee, const InlineParams &Params,
- TargetTransformInfo &CalleeTTI,
- std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
- Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
- function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
- ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) {
+Optional<InlineResult> llvm::getAttributeBasedInliningDecision(
+ CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {
// Cannot inline indirect calls.
if (!Callee)
- return llvm::InlineCost::getNever("indirect call");
+ return InlineResult::failure("indirect call");
// Never inline calls with byval arguments that does not have the alloca
// address space. Since byval arguments can be replaced with a copy to an
@@ -2237,8 +2233,8 @@ InlineCost llvm::getInlineCost(
if (Call.isByValArgument(I)) {
PointerType *PTy = cast<PointerType>(Call.getArgOperand(I)->getType());
if (PTy->getAddressSpace() != AllocaAS)
- return llvm::InlineCost::getNever("byval arguments without alloca"
- " address space");
+ return InlineResult::failure("byval arguments without alloca"
+ " address space");
}
// Calls to functions with always-inline attributes should be inlined
@@ -2246,39 +2242,60 @@ InlineCost llvm::getInlineCost(
if (Call.hasFnAttr(Attribute::AlwaysInline)) {
auto IsViable = isInlineViable(*Callee);
if (IsViable.isSuccess())
- return llvm::InlineCost::getAlways("always inline attribute");
- return llvm::InlineCost::getNever(IsViable.getFailureReason());
+ return InlineResult::success();
+ return InlineResult::failure(IsViable.getFailureReason());
}
// Never inline functions with conflicting attributes (unless callee has
// always-inline attribute).
Function *Caller = Call.getCaller();
if (!functionsHaveCompatibleAttributes(Caller, Callee, CalleeTTI, GetTLI))
- return llvm::InlineCost::getNever("conflicting attributes");
+ return InlineResult::failure("conflicting attributes");
// Don't inline this call if the caller has the optnone attribute.
if (Caller->hasOptNone())
- return llvm::InlineCost::getNever("optnone attribute");
+ return InlineResult::failure("optnone attribute");
// Don't inline a function that treats null pointer as valid into a caller
// that does not have this attribute.
if (!Caller->nullPointerIsDefined() && Callee->nullPointerIsDefined())
- return llvm::InlineCost::getNever("nullptr definitions incompatible");
+ return InlineResult::failure("nullptr definitions incompatible");
// Don't inline functions which can be interposed at link-time.
if (Callee->isInterposable())
- return llvm::InlineCost::getNever("interposable");
+ return InlineResult::failure("interposable");
// Don't inline functions marked noinline.
if (Callee->hasFnAttribute(Attribute::NoInline))
- return llvm::InlineCost::getNever("noinline function attribute");
+ return InlineResult::failure("noinline function attribute");
// Don't inline call sites marked noinline.
if (Call.isNoInline())
- return llvm::InlineCost::getNever("noinline call site attribute");
+ return InlineResult::failure("noinline call site attribute");
+
+ return None;
+}
+
+InlineCost llvm::getInlineCost(
+ CallBase &Call, Function *Callee, const InlineParams &Params,
+ TargetTransformInfo &CalleeTTI,
+ std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
+ Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
+ ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) {
+
+ auto UserDecision =
+ llvm::getAttributeBasedInliningDecision(Call, Callee, CalleeTTI, GetTLI);
+
+ if (UserDecision.hasValue()) {
+ if (UserDecision->isSuccess())
+ return llvm::InlineCost::getAlways("always inline attribute");
+ return llvm::InlineCost::getNever(UserDecision->getFailureReason());
+ }
LLVM_DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName()
- << "... (caller:" << Caller->getName() << ")\n");
+ << "... (caller:" << Call.getCaller()->getName()
+ << ")\n");
InlineCostCallAnalyzer CA(CalleeTTI, GetAssumptionCache, GetBFI, PSI, ORE,
*Callee, Call, Params);
More information about the llvm-commits
mailing list