Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Analysis/InlineCost.cpp
Show All 36 Lines | |||||
#include "llvm/IR/InstVisitor.h" | #include "llvm/IR/InstVisitor.h" | ||||
#include "llvm/IR/IntrinsicInst.h" | #include "llvm/IR/IntrinsicInst.h" | ||||
#include "llvm/IR/Operator.h" | #include "llvm/IR/Operator.h" | ||||
#include "llvm/IR/PatternMatch.h" | #include "llvm/IR/PatternMatch.h" | ||||
#include "llvm/Support/CommandLine.h" | #include "llvm/Support/CommandLine.h" | ||||
#include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | ||||
#include "llvm/Support/FormattedStream.h" | #include "llvm/Support/FormattedStream.h" | ||||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||
#include "llvm/Transforms/Coroutines.h" | |||||
using namespace llvm; | using namespace llvm; | ||||
#define DEBUG_TYPE "inline-cost" | #define DEBUG_TYPE "inline-cost" | ||||
STATISTIC(NumCallsAnalyzed, "Number of call sites analyzed"); | STATISTIC(NumCallsAnalyzed, "Number of call sites analyzed"); | ||||
static cl::opt<int> | static cl::opt<int> | ||||
▲ Show 20 Lines • Show All 2,270 Lines • ▼ Show 20 Lines | |||||
Optional<InlineResult> llvm::getAttributeBasedInliningDecision( | Optional<InlineResult> llvm::getAttributeBasedInliningDecision( | ||||
CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI, | CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI, | ||||
function_ref<const TargetLibraryInfo &(Function &)> GetTLI) { | function_ref<const TargetLibraryInfo &(Function &)> GetTLI) { | ||||
// Cannot inline indirect calls. | // Cannot inline indirect calls. | ||||
if (!Callee) | if (!Callee) | ||||
return InlineResult::failure("indirect call"); | return InlineResult::failure("indirect call"); | ||||
// When callee coroutine function is inlined into caller coroutine function | |||||
// before coro-split pass, | |||||
// coro-early pass can not handle this quiet well. | |||||
// So we won't inline the coroutine function if it have not been unsplited | |||||
if (Callee->hasFnAttribute(CORO_PRESPLIT_ATTR)) | |||||
return InlineResult::failure("unsplited coroutine call"); | |||||
// Never inline calls with byval arguments that does not have the alloca | // 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 | // address space. Since byval arguments can be replaced with a copy to an | ||||
// alloca, the inlined code would need to be adjusted to handle that the | // alloca, the inlined code would need to be adjusted to handle that the | ||||
// argument is in the alloca address space (so it is a little bit complicated | // argument is in the alloca address space (so it is a little bit complicated | ||||
// to solve). | // to solve). | ||||
unsigned AllocaAS = Callee->getParent()->getDataLayout().getAllocaAddrSpace(); | unsigned AllocaAS = Callee->getParent()->getDataLayout().getAllocaAddrSpace(); | ||||
for (unsigned I = 0, E = Call.arg_size(); I != E; ++I) | for (unsigned I = 0, E = Call.arg_size(); I != E; ++I) | ||||
if (Call.isByValArgument(I)) { | if (Call.isByValArgument(I)) { | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
InlineCost llvm::getInlineCost( | InlineCost llvm::getInlineCost( | ||||
CallBase &Call, Function *Callee, const InlineParams &Params, | CallBase &Call, Function *Callee, const InlineParams &Params, | ||||
TargetTransformInfo &CalleeTTI, | TargetTransformInfo &CalleeTTI, | ||||
function_ref<AssumptionCache &(Function &)> GetAssumptionCache, | function_ref<AssumptionCache &(Function &)> GetAssumptionCache, | ||||
function_ref<const TargetLibraryInfo &(Function &)> GetTLI, | function_ref<const TargetLibraryInfo &(Function &)> GetTLI, | ||||
function_ref<BlockFrequencyInfo &(Function &)> GetBFI, | function_ref<BlockFrequencyInfo &(Function &)> GetBFI, | ||||
ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) { | ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE) { | ||||
auto UserDecision = | auto UserDecision = | ||||
wenlei: I can see the problem with always inliner as that is outside of CGSCC pipeline, and caller… | |||||
llvm::getAttributeBasedInliningDecision(Call, Callee, CalleeTTI, GetTLI); | llvm::getAttributeBasedInliningDecision(Call, Callee, CalleeTTI, GetTLI); | ||||
if (UserDecision.hasValue()) { | if (UserDecision.hasValue()) { | ||||
if (UserDecision->isSuccess()) | if (UserDecision->isSuccess()) | ||||
return llvm::InlineCost::getAlways("always inline attribute"); | return llvm::InlineCost::getAlways("always inline attribute"); | ||||
return llvm::InlineCost::getNever(UserDecision->getFailureReason()); | return llvm::InlineCost::getNever(UserDecision->getFailureReason()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 194 Lines • Show Last 20 Lines |
I can see the problem with always inliner as that is outside of CGSCC pipeline, and caller could be processed before callee. However, do you actually run into this problem with CGSCC inliner? I'd expect callee to be split already as they should be processed earlier in the pipeline.