reduce inlining factor some stuff out to a static helper function,

and other code cleanups.  No functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80199 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2009-08-27 03:51:50 +00:00
parent 639217cb6a
commit 135755dae4
2 changed files with 255 additions and 209 deletions

View File

@@ -69,8 +69,8 @@ bool Inliner::InlineCallIfPossible(CallSite CS, CallGraph &CG,
// If we inlined the last possible call site to the function, delete the // If we inlined the last possible call site to the function, delete the
// function body now. // function body now.
if (Callee->use_empty() && (Callee->hasLocalLinkage() || if (Callee->use_empty() &&
Callee->hasAvailableExternallyLinkage()) && (Callee->hasLocalLinkage() || Callee->hasAvailableExternallyLinkage()) &&
!SCCFunctions.count(Callee)) { !SCCFunctions.count(Callee)) {
DEBUG(errs() << " -> Deleting dead function: " DEBUG(errs() << " -> Deleting dead function: "
<< Callee->getName() << "\n"); << Callee->getName() << "\n");
@@ -92,7 +92,6 @@ bool Inliner::InlineCallIfPossible(CallSite CS, CallGraph &CG,
/// at the given CallSite. /// at the given CallSite.
bool Inliner::shouldInline(CallSite CS) { bool Inliner::shouldInline(CallSite CS) {
InlineCost IC = getInlineCost(CS); InlineCost IC = getInlineCost(CS);
float FudgeFactor = getInlineFudgeFactor(CS);
if (IC.isAlways()) { if (IC.isAlways()) {
DEBUG(errs() << " Inlining: cost=always" DEBUG(errs() << " Inlining: cost=always"
@@ -114,15 +113,16 @@ bool Inliner::shouldInline(CallSite CS) {
InlineThreshold != 50) InlineThreshold != 50)
CurrentThreshold = 50; CurrentThreshold = 50;
float FudgeFactor = getInlineFudgeFactor(CS);
if (Cost >= (int)(CurrentThreshold * FudgeFactor)) { if (Cost >= (int)(CurrentThreshold * FudgeFactor)) {
DEBUG(errs() << " NOT Inlining: cost=" << Cost DEBUG(errs() << " NOT Inlining: cost=" << Cost
<< ", Call: " << *CS.getInstruction() << "\n"); << ", Call: " << *CS.getInstruction() << "\n");
return false; return false;
} else { }
DEBUG(errs() << " Inlining: cost=" << Cost DEBUG(errs() << " Inlining: cost=" << Cost
<< ", Call: " << *CS.getInstruction() << "\n"); << ", Call: " << *CS.getInstruction() << "\n");
return true; return true;
}
} }
bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) { bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
@@ -142,16 +142,21 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
// from inlining other functions. // from inlining other functions.
std::vector<CallSite> CallSites; std::vector<CallSite> CallSites;
for (unsigned i = 0, e = SCC.size(); i != e; ++i) for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
if (Function *F = SCC[i]->getFunction()) Function *F = SCC[i]->getFunction();
if (!F) continue;
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
CallSite CS = CallSite::get(I); CallSite CS = CallSite::get(I);
if (CS.getInstruction() && !isa<DbgInfoIntrinsic>(I) && if (CS.getInstruction() == 0 || isa<DbgInfoIntrinsic>(I))
(!CS.getCalledFunction() || continue;
!CS.getCalledFunction()->isDeclaration()))
if (CS.getCalledFunction() == 0 ||
!CS.getCalledFunction()->isDeclaration())
CallSites.push_back(CS); CallSites.push_back(CS);
} }
}
DEBUG(errs() << ": " << CallSites.size() << " call sites.\n"); DEBUG(errs() << ": " << CallSites.size() << " call sites.\n");
@@ -171,8 +176,11 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
LocalChange = false; LocalChange = false;
// Iterate over the outer loop because inlining functions can cause indirect // Iterate over the outer loop because inlining functions can cause indirect
// calls to become direct calls. // calls to become direct calls.
for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi) for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi) {
if (Function *Callee = CallSites[CSi].getCalledFunction()) { // We can only inline direct calls.
Function *Callee = CallSites[CSi].getCalledFunction();
if (!Callee) continue;
// Calls to external functions are never inlinable. // Calls to external functions are never inlinable.
if (Callee->isDeclaration()) { if (Callee->isDeclaration()) {
if (SCC.size() == 1) { if (SCC.size() == 1) {
@@ -189,10 +197,14 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
// If the policy determines that we should inline this function, // If the policy determines that we should inline this function,
// try to do so. // try to do so.
CallSite CS = CallSites[CSi]; CallSite CS = CallSites[CSi];
if (shouldInline(CS)) { if (!shouldInline(CS))
continue;
Function *Caller = CS.getCaller(); Function *Caller = CS.getCaller();
// Attempt to inline the function... // Attempt to inline the function...
if (InlineCallIfPossible(CS, CG, SCCFunctions, TD)) { if (!InlineCallIfPossible(CS, CG, SCCFunctions, TD))
continue;
// Remove any cached cost info for this caller, as inlining the // Remove any cached cost info for this caller, as inlining the
// callee has increased the size of the caller (which may be the // callee has increased the size of the caller (which may be the
// same as the callee). // same as the callee).
@@ -214,8 +226,6 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
Changed = true; Changed = true;
LocalChange = true; LocalChange = true;
} }
}
}
} while (LocalChange); } while (LocalChange);
return Changed; return Changed;
@@ -227,26 +237,31 @@ bool Inliner::doFinalization(CallGraph &CG) {
return removeDeadFunctions(CG); return removeDeadFunctions(CG);
} }
/// removeDeadFunctions - Remove dead functions that are not included in /// removeDeadFunctions - Remove dead functions that are not included in
/// DNR (Do Not Remove) list. /// DNR (Do Not Remove) list.
bool Inliner::removeDeadFunctions(CallGraph &CG, bool Inliner::removeDeadFunctions(CallGraph &CG,
SmallPtrSet<const Function *, 16> *DNR) { SmallPtrSet<const Function *, 16> *DNR) {
std::set<CallGraphNode*> FunctionsToRemove; SmallPtrSet<CallGraphNode*, 16> FunctionsToRemove;
// Scan for all of the functions, looking for ones that should now be removed // Scan for all of the functions, looking for ones that should now be removed
// from the program. Insert the dead ones in the FunctionsToRemove set. // from the program. Insert the dead ones in the FunctionsToRemove set.
for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) { for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) {
CallGraphNode *CGN = I->second; CallGraphNode *CGN = I->second;
if (Function *F = CGN ? CGN->getFunction() : 0) { if (CGN == 0 || CGN->getFunction() == 0)
continue;
Function *F = CGN->getFunction();
// If the only remaining users of the function are dead constants, remove // If the only remaining users of the function are dead constants, remove
// them. // them.
F->removeDeadConstantUsers(); F->removeDeadConstantUsers();
if (DNR && DNR->count(F)) if (DNR && DNR->count(F))
continue; continue;
if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage())
if ((F->hasLinkOnceLinkage() || F->hasLocalLinkage()) && continue;
F->use_empty()) { if (!F->use_empty())
continue;
// Remove any call graph edges from the function to its callees. // Remove any call graph edges from the function to its callees.
CGN->removeAllCalledFunctions(); CGN->removeAllCalledFunctions();
@@ -259,14 +274,16 @@ bool Inliner::removeDeadFunctions(CallGraph &CG,
// Removing the node for callee from the call graph and delete it. // Removing the node for callee from the call graph and delete it.
FunctionsToRemove.insert(CGN); FunctionsToRemove.insert(CGN);
} }
}
}
// Now that we know which functions to delete, do so. We didn't want to do // Now that we know which functions to delete, do so. We didn't want to do
// this inline, because that would invalidate our CallGraph::iterator // this inline, because that would invalidate our CallGraph::iterator
// objects. :( // objects. :(
//
// Note that it doesn't matter that we are iterating over a non-stable set
// here to do this, it doesn't matter which order the functions are deleted
// in.
bool Changed = false; bool Changed = false;
for (std::set<CallGraphNode*>::iterator I = FunctionsToRemove.begin(), for (SmallPtrSet<CallGraphNode*, 16>::iterator I = FunctionsToRemove.begin(),
E = FunctionsToRemove.end(); I != E; ++I) { E = FunctionsToRemove.end(); I != E; ++I) {
resetCachedCostInfo((*I)->getFunction()); resetCachedCostInfo((*I)->getFunction());
delete CG.removeFunctionFromModule(*I); delete CG.removeFunctionFromModule(*I);

View File

@@ -36,45 +36,25 @@ bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD) {
return InlineFunction(CallSite(II), CG, TD); return InlineFunction(CallSite(II), CG, TD);
} }
/// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls
/// in the body of the inlined function into invokes and turn unwind /// HandleCallsInBlockInlinedThroughInvoke - When we inline a basic block into
/// instructions into branches to the invoke unwind dest. /// an invoke, we have to check all of all of the calls that can throw into
/// invokes. This function analyze BB to see if there are any calls, and if so,
/// it rewrites them to be invokes that jump to InvokeDest and fills in the PHI
/// nodes in that block with the values specified in InvokeDestPHIValues. If
/// CallerCGN is specified, this function updates the call graph.
/// ///
/// II is the invoke instruction being inlined. FirstNewBlock is the first static void HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB,
/// block of the inlined code (the last block is the end of the function), BasicBlock *InvokeDest,
/// and InlineCodeInfo is information about the code that got inlined. const SmallVectorImpl<Value*> &InvokeDestPHIValues,
static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, CallGraphNode *CallerCGN) {
ClonedCodeInfo &InlinedCodeInfo, for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
CallGraph *CG) {
BasicBlock *InvokeDest = II->getUnwindDest();
std::vector<Value*> InvokeDestPHIValues;
// If there are PHI nodes in the unwind destination block, we need to
// keep track of which values came into them from this invoke, then remove
// the entry for this block.
BasicBlock *InvokeBlock = II->getParent();
for (BasicBlock::iterator I = InvokeDest->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I);
// Save the value to use for this edge.
InvokeDestPHIValues.push_back(PN->getIncomingValueForBlock(InvokeBlock));
}
Function *Caller = FirstNewBlock->getParent();
// The inlined code is currently at the end of the function, scan from the
// start of the inlined code to its end, checking for stuff we need to
// rewrite.
if (InlinedCodeInfo.ContainsCalls || InlinedCodeInfo.ContainsUnwinds) {
for (Function::iterator BB = FirstNewBlock, E = Caller->end();
BB != E; ++BB) {
if (InlinedCodeInfo.ContainsCalls) {
for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ){
Instruction *I = BBI++; Instruction *I = BBI++;
// We only need to check for function calls: inlined invoke // We only need to check for function calls: inlined invoke
// instructions require no special handling. // instructions require no special handling.
if (!isa<CallInst>(I)) continue; CallInst *CI = dyn_cast<CallInst>(I);
CallInst *CI = cast<CallInst>(I); if (CI == 0) continue;
// If this call cannot unwind, don't convert it to an invoke. // If this call cannot unwind, don't convert it to an invoke.
if (CI->doesNotThrow()) if (CI->doesNotThrow())
@@ -97,14 +77,13 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
// Make sure that anything using the call now uses the invoke! // Make sure that anything using the call now uses the invoke!
CI->replaceAllUsesWith(II); CI->replaceAllUsesWith(II);
// Update the callgraph. // Update the callgraph if present.
if (CG) { if (CallerCGN) {
// We should be able to do this: // We should be able to do this:
// (*CG)[Caller]->replaceCallSite(CI, II); // (*CG)[Caller]->replaceCallSite(CI, II);
// but that fails if the old call site isn't in the call graph, // but that fails if the old call site isn't in the call graph,
// which, because of LLVM bug 3601, it sometimes isn't. // which, because of LLVM bug 3601, it sometimes isn't.
CallGraphNode *CGN = (*CG)[Caller]; for (CallGraphNode::iterator NI = CallerCGN->begin(), NE = CallerCGN->end();
for (CallGraphNode::iterator NI = CGN->begin(), NE = CGN->end();
NI != NE; ++NI) { NI != NE; ++NI) {
if (NI->first == CI) { if (NI->first == CI) {
NI->first = II; NI->first = II;
@@ -121,16 +100,62 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
// there is now a new entry in them. // there is now a new entry in them.
unsigned i = 0; unsigned i = 0;
for (BasicBlock::iterator I = InvokeDest->begin(); for (BasicBlock::iterator I = InvokeDest->begin();
isa<PHINode>(I); ++I, ++i) { isa<PHINode>(I); ++I, ++i)
cast<PHINode>(I)->addIncoming(InvokeDestPHIValues[i], BB);
// This basic block is now complete, the caller will continue scanning the
// next one.
return;
}
}
/// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls
/// in the body of the inlined function into invokes and turn unwind
/// instructions into branches to the invoke unwind dest.
///
/// II is the invoke instruction being inlined. FirstNewBlock is the first
/// block of the inlined code (the last block is the end of the function),
/// and InlineCodeInfo is information about the code that got inlined.
static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
ClonedCodeInfo &InlinedCodeInfo,
CallGraph *CG) {
BasicBlock *InvokeDest = II->getUnwindDest();
SmallVector<Value*, 8> InvokeDestPHIValues;
// If there are PHI nodes in the unwind destination block, we need to
// keep track of which values came into them from this invoke, then remove
// the entry for this block.
BasicBlock *InvokeBlock = II->getParent();
for (BasicBlock::iterator I = InvokeDest->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I); PHINode *PN = cast<PHINode>(I);
PN->addIncoming(InvokeDestPHIValues[i], BB); // Save the value to use for this edge.
InvokeDestPHIValues.push_back(PN->getIncomingValueForBlock(InvokeBlock));
} }
// This basic block is now complete, start scanning the next one. Function *Caller = FirstNewBlock->getParent();
break;
} // The inlined code is currently at the end of the function, scan from the
// start of the inlined code to its end, checking for stuff we need to
// rewrite. If the code doesn't have calls or unwinds, we know there is
// nothing to rewrite.
if (!InlinedCodeInfo.ContainsCalls && !InlinedCodeInfo.ContainsUnwinds) {
// Now that everything is happy, we have one final detail. The PHI nodes in
// the exception destination block still have entries due to the original
// invoke instruction. Eliminate these entries (which might even delete the
// PHI node) now.
InvokeDest->removePredecessor(II->getParent());
return;
} }
CallGraphNode *CallerCGN = 0;
if (CG) CallerCGN = (*CG)[Caller];
for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB){
if (InlinedCodeInfo.ContainsCalls)
HandleCallsInBlockInlinedThroughInvoke(BB, InvokeDest,
InvokeDestPHIValues, CallerCGN);
if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) { if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
// An UnwindInst requires special handling when it gets inlined into an // An UnwindInst requires special handling when it gets inlined into an
// invoke site. Once this happens, we know that the unwind would cause // invoke site. Once this happens, we know that the unwind would cause
@@ -151,7 +176,6 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
} }
} }
} }
}
// Now that everything is happy, we have one final detail. The PHI nodes in // Now that everything is happy, we have one final detail. The PHI nodes in
// the exception destination block still have entries due to the original // the exception destination block still have entries due to the original
@@ -190,13 +214,15 @@ static void UpdateCallGraphAfterInlining(CallSite CS,
DenseMap<const Value*, Value*>::iterator VMI = ValueMap.find(OrigCall); DenseMap<const Value*, Value*>::iterator VMI = ValueMap.find(OrigCall);
// Only copy the edge if the call was inlined! // Only copy the edge if the call was inlined!
if (VMI != ValueMap.end() && VMI->second) { if (VMI == ValueMap.end() || VMI->second == 0)
continue;
// If the call was inlined, but then constant folded, there is no edge to // If the call was inlined, but then constant folded, there is no edge to
// add. Check for this case. // add. Check for this case.
if (Instruction *NewCall = dyn_cast<Instruction>(VMI->second)) if (Instruction *NewCall = dyn_cast<Instruction>(VMI->second))
CallerNode->addCalledFunction(CallSite::get(NewCall), I->second); CallerNode->addCalledFunction(CallSite::get(NewCall), I->second);
} }
}
// Update the call graph by deleting the edge from Callee to Caller. We must // Update the call graph by deleting the edge from Callee to Caller. We must
// do this after the loop above in case Caller and Callee are the same. // do this after the loop above in case Caller and Callee are the same.
CallerNode->removeCallEdgeFor(CS); CallerNode->removeCallEdgeFor(CS);
@@ -205,6 +231,7 @@ static void UpdateCallGraphAfterInlining(CallSite CS,
/// findFnRegionEndMarker - This is a utility routine that is used by /// findFnRegionEndMarker - This is a utility routine that is used by
/// InlineFunction. Return llvm.dbg.region.end intrinsic that corresponds /// InlineFunction. Return llvm.dbg.region.end intrinsic that corresponds
/// to the llvm.dbg.func.start of the function F. Otherwise return NULL. /// to the llvm.dbg.func.start of the function F. Otherwise return NULL.
///
static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) { static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) {
GlobalVariable *FnStart = NULL; GlobalVariable *FnStart = NULL;
@@ -219,12 +246,13 @@ static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) {
if (SP.describes(F)) if (SP.describes(F))
FnStart = SP.getGV(); FnStart = SP.getGV();
} }
} else { continue;
}
if (const DbgRegionEndInst *REI = dyn_cast<DbgRegionEndInst>(BI)) if (const DbgRegionEndInst *REI = dyn_cast<DbgRegionEndInst>(BI))
if (REI->getContext() == FnStart) if (REI->getContext() == FnStart)
FnEnd = REI; FnEnd = REI;
} }
}
return FnEnd; return FnEnd;
} }
@@ -358,10 +386,9 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
// call site. The function body cloner does not clone original // call site. The function body cloner does not clone original
// region end marker from the CalledFunc. This will ensure that // region end marker from the CalledFunc. This will ensure that
// inlined function's scope ends at the right place. // inlined function's scope ends at the right place.
const DbgRegionEndInst *DREI = findFnRegionEndMarker(CalledFunc); if (const DbgRegionEndInst *DREI = findFnRegionEndMarker(CalledFunc)) {
if (DREI) { for (BasicBlock::iterator BI = TheCall, BE = TheCall->getParent()->end();
for (BasicBlock::iterator BI = TheCall, BI != BE; ++BI) {
BE = TheCall->getParent()->end(); BI != BE; ++BI) {
if (DbgStopPointInst *DSPI = dyn_cast<DbgStopPointInst>(BI)) { if (DbgStopPointInst *DSPI = dyn_cast<DbgStopPointInst>(BI)) {
if (DbgRegionEndInst *NewDREI = if (DbgRegionEndInst *NewDREI =
dyn_cast<DbgRegionEndInst>(DREI->clone(Context))) dyn_cast<DbgRegionEndInst>(DREI->clone(Context)))
@@ -394,8 +421,10 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
{ {
BasicBlock::iterator InsertPoint = Caller->begin()->begin(); BasicBlock::iterator InsertPoint = Caller->begin()->begin();
for (BasicBlock::iterator I = FirstNewBlock->begin(), for (BasicBlock::iterator I = FirstNewBlock->begin(),
E = FirstNewBlock->end(); I != E; ) E = FirstNewBlock->end(); I != E; ) {
if (AllocaInst *AI = dyn_cast<AllocaInst>(I++)) { AllocaInst *AI = dyn_cast<AllocaInst>(I++);
if (AI == 0) continue;
// If the alloca is now dead, remove it. This often occurs due to code // If the alloca is now dead, remove it. This often occurs due to code
// specialization. // specialization.
if (AI->use_empty()) { if (AI->use_empty()) {
@@ -403,7 +432,9 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
continue; continue;
} }
if (isa<Constant>(AI->getArraySize())) { if (!isa<Constant>(AI->getArraySize()))
continue;
// Scan for the block of allocas that we can move over, and move them // Scan for the block of allocas that we can move over, and move them
// all at once. // all at once.
while (isa<AllocaInst>(I) && while (isa<AllocaInst>(I) &&
@@ -413,13 +444,11 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
// Transfer all of the allocas over in a block. Using splice means // Transfer all of the allocas over in a block. Using splice means
// that the instructions aren't removed from the symbol table, then // that the instructions aren't removed from the symbol table, then
// reinserted. // reinserted.
Caller->getEntryBlock().getInstList().splice( Caller->getEntryBlock().getInstList().splice(InsertPoint,
InsertPoint,
FirstNewBlock->getInstList(), FirstNewBlock->getInstList(),
AI, I); AI, I);
} }
} }
}
// If the inlined code contained dynamic alloca instructions, wrap the inlined // If the inlined code contained dynamic alloca instructions, wrap the inlined
// code with llvm.stacksave/llvm.stackrestore intrinsics. // code with llvm.stacksave/llvm.stackrestore intrinsics.