mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[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
This commit is contained in:
parent
f55cc8b846
commit
a65579c739
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user