37 #define DEBUG_TYPE "inline"
39 STATISTIC(NumInlined,
"Number of functions inlined");
40 STATISTIC(NumCallsDeleted,
"Number of call sites deleted, not inlined");
41 STATISTIC(NumDeleted,
"Number of functions deleted because all callers found");
42 STATISTIC(NumMergedAllocas,
"Number of allocas merged together");
47 STATISTIC(NumCallerCallersAnalyzed,
"Number of caller-callers analyzed");
51 cl::desc(
"Control the amount of inlining to perform (default = 225)"));
55 cl::desc(
"Threshold for inlining functions with inline hint"));
62 cl::desc(
"Threshold for inlining functions with cold attribute"));
73 InsertLifetime(InsertLifetime) {}
131 int InlineHistory,
bool InsertLifetime) {
177 if (InlineHistory != -1)
183 AllocaNo != e; ++AllocaNo) {
194 std::vector<AllocaInst*> &AllocasForType = InlinedArrayAllocas[ATy];
201 bool MergedAwayAlloca =
false;
202 for (
AllocaInst *AvailableAlloca : AllocasForType) {
205 Align2 = AvailableAlloca->getAlignment();
209 if (AvailableAlloca->getParent() != AI->
getParent())
214 if (!UsedAllocas.
insert(AvailableAlloca).second)
219 DEBUG(
dbgs() <<
" ***MERGED ALLOCA: " << *AI <<
"\n\t\tINTO: "
220 << *AvailableAlloca <<
'\n');
224 if (Align1 != Align2) {
225 if (!Align1 || !Align2) {
229 Align1 = Align1 ? Align1 : TypeAlign;
230 Align2 = Align2 ? Align2 : TypeAlign;
238 MergedAwayAlloca =
true;
245 if (MergedAwayAlloca)
253 AllocasForType.push_back(AI);
261 int thres = InlineThreshold;
269 if (!(
InlineLimit.getNumOccurrences() > 0) && OptSize &&
304 bool Inliner::shouldInline(
CallSite CS) {
311 " should always be inlined (cost=always)");
316 DEBUG(
dbgs() <<
" NOT Inlining: cost=never"
319 " should never be inlined (cost=never)"));
329 " too costly to inline (cost=") +
352 int TotalSecondaryCost = 0;
358 bool inliningPreventsSomeOuterInline =
false;
365 if (!CS2 || CS2.getCalledFunction() != Caller) {
366 callerWillBeRemoved =
false;
371 ++NumCallerCallersAnalyzed;
373 callerWillBeRemoved =
false;
383 inliningPreventsSomeOuterInline =
true;
384 TotalSecondaryCost += IC2.
getCost();
391 if (callerWillBeRemoved && !Caller->
use_empty())
394 if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.
getCost()) {
397 ", outer Cost = " << TotalSecondaryCost <<
'\n');
399 CS,
Twine(
"Not inlining. Cost of inlining " +
401 " increases the cost of inlining " +
421 while (InlineHistoryID != -1) {
422 assert(
unsigned(InlineHistoryID) < InlineHistory.size() &&
423 "Invalid inline history ID");
424 if (InlineHistory[InlineHistoryID].first == F)
426 InlineHistoryID = InlineHistory[InlineHistoryID].second;
432 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
434 auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
439 DEBUG(
dbgs() <<
"Inliner visiting SCC:");
442 if (F) SCCFunctions.insert(F);
466 if (!CS || isa<IntrinsicInst>(
I))
475 CallSites.
push_back(std::make_pair(CS, -1));
479 DEBUG(
dbgs() <<
": " << CallSites.
size() <<
" call sites.\n");
482 if (CallSites.
empty())
487 unsigned FirstCallInSCC = CallSites.
size();
488 for (
unsigned i = 0; i < FirstCallInSCC; ++i)
489 if (
Function *
F = CallSites[i].first.getCalledFunction())
490 if (SCCFunctions.count(
F))
491 std::swap(CallSites[i--], CallSites[--FirstCallInSCC]);
499 bool Changed =
false;
506 for (
unsigned CSi = 0; CSi != CallSites.
size(); ++CSi) {
517 DEBUG(
dbgs() <<
" -> Deleting dead call: "
520 CG[Caller]->removeCallEdgeFor(CS);
532 int InlineHistoryID = CallSites[CSi].second;
533 if (InlineHistoryID != -1 &&
544 if (!shouldInline(CS)) {
547 " will not be inlined into " +
554 InlineHistoryID, InsertLifetime)) {
557 " will not be inlined into " +
573 int NewHistoryID = InlineHistory.
size();
574 InlineHistory.
push_back(std::make_pair(Callee, InlineHistoryID));
585 !SCCFunctions.count(Callee) &&
590 CG[Callee]->getNumReferences() == 0) {
591 DEBUG(
dbgs() <<
" -> Deleting dead function: "
596 CalleeNode->removeAllCalledFunctions();
607 if (SCC.isSingular()) {
608 CallSites[CSi] = CallSites.
back();
618 }
while (LocalChange);
637 CGN->removeAllCalledFunctions();
675 --ComdatEntriesAlive[
C];
683 if (!DeadFunctionsInComdats.
empty()) {
685 auto ComdatGroupReferenced = [&](
const Comdat *
C) {
686 auto I = ComdatEntriesAlive.
find(
C);
687 if (
I != ComdatEntriesAlive.
end())
691 if (
const Comdat *
C =
F.getComdat())
692 ComdatGroupReferenced(
C);
694 if (
const Comdat *
C = GV.getComdat())
695 ComdatGroupReferenced(
C);
696 for (
const GlobalAlias &GA : CG.getModule().aliases())
697 if (
const Comdat *
C = GA.getComdat())
698 ComdatGroupReferenced(
C);
702 int NumAlive = ComdatEntriesAlive[
C];
704 assert(NumAlive >= 0);
712 if (FunctionsToRemove.
empty())
723 FunctionsToRemove.
erase(std::unique(FunctionsToRemove.
begin(),
724 FunctionsToRemove.
end()),
725 FunctionsToRemove.
end());
727 delete CG.removeFunctionFromModule(CGN);
bool isDefTriviallyDead() const
isDefTriviallyDead - Return true if it is trivially safe to remove this function definition from the ...
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
unsigned getInlineThreshold() const
This method returns the value specified by the -inline-threshold value, specified on the command line...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
STATISTIC(NumFunctions,"Total number of functions")
bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, bool InsertLifetime=true)
InlineFunction - This function inlines the called function into the basic block of the caller...
InstrTy * getInstruction() const
An immutable pass that tracks lazily created AssumptionCache objects.
Source said inlining was desirable.
bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly=false)
removeDeadFunctions - Remove dead functions.
FunTy * getCaller() const
getCaller - Return the caller function for this call site
bool doFinalization(CallGraph &CG) override
Remove now-dead linkonce functions at the end of processing to avoid breaking the SCC traversal...
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
InlineFunctionInfo - This class captures the data input to the InlineFunction call, and records the auxiliary results produced by it.
A node in the call graph for a module.
void getAnalysisUsage(AnalysisUsage &Info) const override
getAnalysisUsage - For this class, we declare that we require and preserve the call graph...
void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-applied message.
Represents the cost of inlining a function.
StringRef getName() const
Return a constant reference to the value's name.
Function * getFunction() const
Returns the function that this call graph node represents.
bool isArrayAllocation() const
isArrayAllocation - Return true if there is an allocation size parameter to the allocation instructio...
AnalysisUsage & addRequired()
DenseMap< ArrayType *, std::vector< AllocaInst * > > InlinedArrayAllocasTy
void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization analysis remark message.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
int getCost() const
Get the inline cost estimate.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Function * removeFunctionFromModule(CallGraphNode *CGN)
Unlink the function from this module, returning it.
void addFnAttr(Attribute::AttrKind N)
Add function attributes to this function.
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
const int OptSizeThreshold
void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-missed message.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
ArrayType - Class to represent array types.
void getAnalysisUsage(AnalysisUsage &Info) const override
getAnalysisUsage - For this class, we declare that we require and preserve the call graph...
const int LastCallToStaticBonus
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
int getCostDelta() const
Get the cost delta from the threshold for inlining.
void removeAttributes(unsigned i, AttributeSet attr)
removes the attributes from the list of attributes.
static cl::opt< int > InlineLimit("inline-threshold", cl::Hidden, cl::init(225), cl::ZeroOrMore, cl::desc("Control the amount of inlining to perform (default = 225)"))
static cl::opt< int > ColdThreshold("inlinecold-threshold", cl::Hidden, cl::init(225), cl::desc("Threshold for inlining functions with cold attribute"))
initializer< Ty > init(const Ty &Val)
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
void removeAnyCallEdgeTo(CallGraphNode *Callee)
Removes all call edges from this node to the specified callee function.
LLVM Basic Block Representation.
This is an important class for using LLVM in a threaded context.
FunTy * getCalledFunction() const
getCalledFunction - Return the function being called if this is a direct call, otherwise return null ...
const Comdat * getComdat() const
unsigned getAlignment() const
getAlignment - Return the alignment of the memory that is being allocated by the instruction.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
Represent the analysis usage information of a pass.
SmallVector< WeakVH, 8 > InlinedCalls
InlinedCalls - InlineFunction fills this in with callsites that were inlined from the callee...
Marks function as being in a cold path.
static void AdjustCallerSSPLevel(Function *Caller, Function *Callee)
If the inlined function had a higher stack protection level than the calling function, then bump up the caller's stack protection level.
iterator erase(iterator I)
bool runOnSCC(CallGraphSCC &SCC) override
runOnSCC - This method should be implemented by the subclass to perform whatever action is necessary ...
virtual InlineCost getInlineCost(CallSite CS)=0
getInlineCost - This method must be implemented by the subclass to determine the cost of inlining the...
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static void emitAnalysis(CallSite CS, const Twine &Msg)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
static cl::opt< int > HintThreshold("inlinehint-threshold", cl::Hidden, cl::init(325), cl::desc("Threshold for inlining functions with inline hint"))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
iterator_range< user_iterator > users()
static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI, InlinedArrayAllocasTy &InlinedArrayAllocas, int InlineHistory, bool InsertLifetime)
If it is possible to inline the specified call site, do so and update the CallGraph for this operatio...
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
SmallVector< AllocaInst *, 4 > StaticAllocas
StaticAllocas - InlineFunction fills this in with all static allocas that get copied into the caller...
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
The basic data container for the call graph of a Module of IR.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool hasLinkOnceODRLinkage() const
iterator find(const KeyT &Val)
bool hasLocalLinkage() const
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
void removeDeadConstantUsers() const
removeDeadConstantUsers - If there are any dead constant users dangling off of this constant...
Module * getParent()
Get the module that this global value is contained inside of...
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
isInstructionTriviallyDead - Return true if the result produced by the instruction is not used...
LLVM Value Representation.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
static bool InlineHistoryIncludes(Function *F, int InlineHistoryID, const SmallVectorImpl< std::pair< Function *, int > > &InlineHistory)
Return true if the specified inline history ID indicates an inline history that includes the specifie...
Type * getAllocatedType() const
getAllocatedType - Return the type that is being allocated by the instruction.
CallGraphNode * getExternalCallingNode() const
Returns the CallGraphNode which is used to represent undetermined calls into the callgraph.
Stack protection required.
const BasicBlock * getParent() const
AllocaInst - an instruction to allocate memory on the stack.
Function must be optimized for size first.