16 #define DEBUG_TYPE "inline"
35 STATISTIC(NumInlined,
"Number of functions inlined");
36 STATISTIC(NumCallsDeleted,
"Number of call sites deleted, not inlined");
37 STATISTIC(NumDeleted,
"Number of functions deleted because all callers found");
38 STATISTIC(NumMergedAllocas,
"Number of allocas merged together");
43 STATISTIC(NumCallerCallersAnalyzed,
"Number of caller-callers analyzed");
47 cl::desc(
"Control the amount of inlining to perform (default = 225)"));
51 cl::desc(
"Threshold for inlining functions with inline hint"));
62 InsertLifetime(InsertLifetime) {}
85 AttributeSet::FunctionIndex,
90 if (CalleeAttr.hasAttribute(AttributeSet::FunctionIndex,
94 }
else if (CalleeAttr.hasAttribute(AttributeSet::FunctionIndex,
96 !CallerAttr.hasAttribute(AttributeSet::FunctionIndex,
100 }
else if (CalleeAttr.hasAttribute(AttributeSet::FunctionIndex,
102 !CallerAttr.hasAttribute(AttributeSet::FunctionIndex,
104 !CallerAttr.hasAttribute(AttributeSet::FunctionIndex,
119 int InlineHistory,
bool InsertLifetime,
166 if (InlineHistory != -1)
172 AllocaNo != e; ++AllocaNo) {
183 std::vector<AllocaInst*> &AllocasForType = InlinedArrayAllocas[ATy];
190 bool MergedAwayAlloca =
false;
191 for (
unsigned i = 0, e = AllocasForType.size(); i != e; ++i) {
192 AllocaInst *AvailableAlloca = AllocasForType[i];
199 if (!TD && (!Align1 || !Align2) && Align1 != Align2)
209 if (!UsedAllocas.
insert(AvailableAlloca))
214 DEBUG(
dbgs() <<
" ***MERGED ALLOCA: " << *AI <<
"\n\t\tINTO: "
215 << *AvailableAlloca <<
'\n');
219 if (Align1 != Align2) {
220 if (!Align1 || !Align2) {
221 assert(TD &&
"DataLayout required to compare default alignments");
224 Align1 = Align1 ? Align1 : TypeAlign;
225 Align2 = Align2 ? Align2 : TypeAlign;
233 MergedAwayAlloca =
true;
240 if (MergedAwayAlloca)
248 AllocasForType.push_back(AI);
256 int thres = InlineThreshold;
265 if (!(
InlineLimit.getNumOccurrences() > 0) && OptSize &&
285 bool Inliner::shouldInline(
CallSite CS) {
295 DEBUG(
dbgs() <<
" NOT Inlining: cost=never"
326 int TotalSecondaryCost = 0;
332 bool inliningPreventsSomeOuterInline =
false;
340 if (!CS2 || CS2.getCalledFunction() != Caller) {
341 callerWillBeRemoved =
false;
346 ++NumCallerCallersAnalyzed;
348 callerWillBeRemoved =
false;
358 inliningPreventsSomeOuterInline =
true;
359 TotalSecondaryCost += IC2.
getCost();
369 if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.
getCost()) {
372 ", outer Cost = " << TotalSecondaryCost <<
'\n');
387 while (InlineHistoryID != -1) {
388 assert(
unsigned(InlineHistoryID) < InlineHistory.size() &&
389 "Invalid inline history ID");
390 if (InlineHistory[InlineHistoryID].first == F)
392 InlineHistoryID = InlineHistory[InlineHistoryID].second;
398 CallGraph &CG = getAnalysis<CallGraph>();
399 const DataLayout *
TD = getAnalysisIfAvailable<DataLayout>();
403 DEBUG(
dbgs() <<
"Inliner visiting SCC:");
406 if (F) SCCFunctions.insert(F);
430 if (!CS || isa<IntrinsicInst>(
I))
439 CallSites.
push_back(std::make_pair(CS, -1));
443 DEBUG(
dbgs() <<
": " << CallSites.
size() <<
" call sites.\n");
446 if (CallSites.
empty())
451 unsigned FirstCallInSCC = CallSites.
size();
452 for (
unsigned i = 0; i < FirstCallInSCC; ++i)
453 if (
Function *
F = CallSites[i].first.getCalledFunction())
454 if (SCCFunctions.count(
F))
455 std::swap(CallSites[i--], CallSites[--FirstCallInSCC]);
463 bool Changed =
false;
469 for (
unsigned CSi = 0; CSi != CallSites.
size(); ++CSi) {
480 DEBUG(
dbgs() <<
" -> Deleting dead call: "
483 CG[Caller]->removeCallEdgeFor(CS);
495 int InlineHistoryID = CallSites[CSi].second;
496 if (InlineHistoryID != -1 &&
503 if (!shouldInline(CS))
508 InlineHistoryID, InsertLifetime, TD))
517 int NewHistoryID = InlineHistory.
size();
518 InlineHistory.
push_back(std::make_pair(Callee, InlineHistoryID));
520 for (
unsigned i = 0, e = InlineInfo.
InlinedCalls.size();
532 !SCCFunctions.count(Callee) &&
537 CG[Callee]->getNumReferences() == 0) {
538 DEBUG(
dbgs() <<
" -> Deleting dead function: "
543 CalleeNode->removeAllCalledFunctions();
555 CallSites[CSi] = CallSites.
back();
565 }
while (LocalChange);
592 if (AlwaysInlineOnly &&
615 if (FunctionsToRemove.
empty())
626 FunctionsToRemove.
erase(std::unique(FunctionsToRemove.
begin(),
627 FunctionsToRemove.
end()),
628 FunctionsToRemove.
end());
630 E = FunctionsToRemove.
end();
bool isDefTriviallyDead() const
void push_back(const T &Elt)
LinkageTypes getLinkage() const
virtual bool doFinalization(CallGraph &CG)
unsigned getInlineThreshold() const
LLVMContext & getContext() const
bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, bool InsertLifetime=true)
void setAlignment(unsigned Align)
std::vector< CallGraphNode * >::const_iterator iterator
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Source said inlining was desirable.
bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly=false)
FunctionMapTy::iterator iterator
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
Represents the cost of inlining a function.
virtual void getAnalysisUsage(AnalysisUsage &Info) const
SmallVector< AllocaInst *, 4 > StaticAllocas
StringRef getName() const
Function * getFunction() const
bool isArrayAllocation() const
FunTy * getCaller() const
DenseMap< ArrayType *, std::vector< AllocaInst * > > InlinedArrayAllocasTy
int getCost() const
Get the inline cost estimate. It is an error to call this on an "always" or "never" InlineCost...
Function * removeFunctionFromModule(CallGraphNode *CGN)
Type * getAllocatedType() const
ID
LLVM Calling Convention Representation.
void addFnAttr(Attribute::AttrKind N)
Add function attributes to this function.
const int OptSizeThreshold
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
const int LastCallToStaticBonus
void replaceAllUsesWith(Value *V)
int getCostDelta() const
Get the cost delta from the threshold for inlining. Only valid if the cost is of the variable kind...
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)"))
Same, but only replaced by something equivalent.
initializer< Ty > init(const Ty &Val)
void array_pod_sort(IteratorTy Start, IteratorTy End)
void removeAnyCallEdgeTo(CallGraphNode *Callee)
InstrTy * getInstruction() const
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0)
unsigned getAlignment() const
SmallVector< WeakVH, 8 > InlinedCalls
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)
virtual InlineCost getInlineCost(CallSite CS)=0
unsigned getABITypeAlignment(Type *Ty) const
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 - Return a circular-buffered debug stream.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
AttributeSet getAttributes() const
Return the attribute list for this Function.
void removeAllCalledFunctions()
bool isDeclaration() const
virtual void getAnalysisUsage(AnalysisUsage &Info) const
bool hasLocalLinkage() const
static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI, InlinedArrayAllocasTy &InlinedArrayAllocas, int InlineHistory, bool InsertLifetime, const DataLayout *TD)
static int const Threshold
void removeDeadConstantUsers() const
LLVM Value Representation.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
virtual bool runOnSCC(CallGraphSCC &SCC)
static bool InlineHistoryIncludes(Function *F, int InlineHistoryID, const SmallVectorImpl< std::pair< Function *, int > > &InlineHistory)
STATISTIC(NumInlined,"Number of functions inlined")
CallGraphNode * getExternalCallingNode() const
Stack protection required.
const BasicBlock * getParent() const
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
FunTy * getCalledFunction() const
Function must be optimized for size first.