1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 03:53:04 +02:00

[Inliner] clang-format various parts of the inliner prior to changes

here. NFC.

llvm-svn: 277557
This commit is contained in:
Chandler Carruth 2016-08-03 01:02:31 +00:00
parent 2b69153c7d
commit dc1947bc2e
3 changed files with 71 additions and 71 deletions

View File

@ -12,7 +12,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CallGraph.h"
@ -26,6 +25,7 @@
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/IR/Type.h" #include "llvm/IR/Type.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/InlinerPass.h" #include "llvm/Transforms/IPO/InlinerPass.h"
using namespace llvm; using namespace llvm;
@ -55,21 +55,20 @@ public:
using llvm::Pass::doFinalization; using llvm::Pass::doFinalization;
bool doFinalization(CallGraph &CG) override { bool doFinalization(CallGraph &CG) override {
return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/ true); return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/true);
} }
}; };
} }
char AlwaysInliner::ID = 0; char AlwaysInliner::ID = 0;
INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline",
"Inliner for always_inline functions", false, false) "Inliner for always_inline functions", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(AlwaysInliner, "always-inline", INITIALIZE_PASS_END(AlwaysInliner, "always-inline",
"Inliner for always_inline functions", false, false) "Inliner for always_inline functions", false, false)
Pass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); } Pass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); }

View File

@ -61,8 +61,8 @@ public:
InlineCost getInlineCost(CallSite CS) override { InlineCost getInlineCost(CallSite CS) override {
Function *Callee = CS.getCalledFunction(); Function *Callee = CS.getCalledFunction();
TargetTransformInfo &TTI = TTIWP->getTTI(*Callee); TargetTransformInfo &TTI = TTIWP->getTTI(*Callee);
std::function<AssumptionCache &(Function &)> GetAssumptionCache = [&]( std::function<AssumptionCache &(Function &)> GetAssumptionCache =
Function &F) -> AssumptionCache & { [&](Function &F) -> AssumptionCache & {
return ACT->getAssumptionCache(F); return ACT->getAssumptionCache(F);
}; };
return llvm::getInlineCost(CS, DefaultThreshold, TTI, GetAssumptionCache, return llvm::getInlineCost(CS, DefaultThreshold, TTI, GetAssumptionCache,
@ -79,15 +79,15 @@ private:
} // end anonymous namespace } // end anonymous namespace
char SimpleInliner::ID = 0; char SimpleInliner::ID = 0;
INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining",
"Function Integration/Inlining", false, false) false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(SimpleInliner, "inline", INITIALIZE_PASS_END(SimpleInliner, "inline", "Function Integration/Inlining",
"Function Integration/Inlining", false, false) false, false)
Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); } Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }

View File

@ -81,9 +81,7 @@ void Inliner::getAnalysisUsage(AnalysisUsage &AU) const {
CallGraphSCCPass::getAnalysisUsage(AU); CallGraphSCCPass::getAnalysisUsage(AU);
} }
typedef DenseMap<ArrayType *, std::vector<AllocaInst *>> InlinedArrayAllocasTy;
typedef DenseMap<ArrayType*, std::vector<AllocaInst*> >
InlinedArrayAllocasTy;
/// If it is possible to inline the specified call site, /// If it is possible to inline the specified call site,
/// do so and update the CallGraph for this operation. /// do so and update the CallGraph for this operation.
@ -134,8 +132,8 @@ static bool InlineCallIfPossible(
// //
// Because we don't have this information, we do this simple and useful hack. // Because we don't have this information, we do this simple and useful hack.
// //
SmallPtrSet<AllocaInst*, 16> UsedAllocas; SmallPtrSet<AllocaInst *, 16> UsedAllocas;
// When processing our SCC, check to see if CS was inlined from some other // When processing our SCC, check to see if CS was inlined from some other
// call site. For example, if we're processing "A" in this code: // call site. For example, if we're processing "A" in this code:
// A() { B() } // A() { B() }
@ -148,25 +146,25 @@ static bool InlineCallIfPossible(
// because their scopes are not disjoint. We could make this smarter by // because their scopes are not disjoint. We could make this smarter by
// keeping track of the inline history for each alloca in the // keeping track of the inline history for each alloca in the
// InlinedArrayAllocas but this isn't likely to be a significant win. // InlinedArrayAllocas but this isn't likely to be a significant win.
if (InlineHistory != -1) // Only do merging for top-level call sites in SCC. if (InlineHistory != -1) // Only do merging for top-level call sites in SCC.
return true; return true;
// Loop over all the allocas we have so far and see if they can be merged with // Loop over all the allocas we have so far and see if they can be merged with
// a previously inlined alloca. If not, remember that we had it. // a previously inlined alloca. If not, remember that we had it.
for (unsigned AllocaNo = 0, e = IFI.StaticAllocas.size(); for (unsigned AllocaNo = 0, e = IFI.StaticAllocas.size(); AllocaNo != e;
AllocaNo != e; ++AllocaNo) { ++AllocaNo) {
AllocaInst *AI = IFI.StaticAllocas[AllocaNo]; AllocaInst *AI = IFI.StaticAllocas[AllocaNo];
// Don't bother trying to merge array allocations (they will usually be // Don't bother trying to merge array allocations (they will usually be
// canonicalized to be an allocation *of* an array), or allocations whose // canonicalized to be an allocation *of* an array), or allocations whose
// type is not itself an array (because we're afraid of pessimizing SRoA). // type is not itself an array (because we're afraid of pessimizing SRoA).
ArrayType *ATy = dyn_cast<ArrayType>(AI->getAllocatedType()); ArrayType *ATy = dyn_cast<ArrayType>(AI->getAllocatedType());
if (!ATy || AI->isArrayAllocation()) if (!ATy || AI->isArrayAllocation())
continue; continue;
// Get the list of all available allocas for this array type. // Get the list of all available allocas for this array type.
std::vector<AllocaInst*> &AllocasForType = InlinedArrayAllocas[ATy]; std::vector<AllocaInst *> &AllocasForType = InlinedArrayAllocas[ATy];
// Loop over the allocas in AllocasForType to see if we can reuse one. Note // Loop over the allocas in AllocasForType to see if we can reuse one. Note
// that we have to be careful not to reuse the same "available" alloca for // that we have to be careful not to reuse the same "available" alloca for
// multiple different allocas that we just inlined, we use the 'UsedAllocas' // multiple different allocas that we just inlined, we use the 'UsedAllocas'
@ -177,22 +175,22 @@ static bool InlineCallIfPossible(
unsigned Align1 = AI->getAlignment(), unsigned Align1 = AI->getAlignment(),
Align2 = AvailableAlloca->getAlignment(); Align2 = AvailableAlloca->getAlignment();
// The available alloca has to be in the right function, not in some other // The available alloca has to be in the right function, not in some other
// function in this SCC. // function in this SCC.
if (AvailableAlloca->getParent() != AI->getParent()) if (AvailableAlloca->getParent() != AI->getParent())
continue; continue;
// If the inlined function already uses this alloca then we can't reuse // If the inlined function already uses this alloca then we can't reuse
// it. // it.
if (!UsedAllocas.insert(AvailableAlloca).second) if (!UsedAllocas.insert(AvailableAlloca).second)
continue; continue;
// Otherwise, we *can* reuse it, RAUW AI into AvailableAlloca and declare // Otherwise, we *can* reuse it, RAUW AI into AvailableAlloca and declare
// success! // success!
DEBUG(dbgs() << " ***MERGED ALLOCA: " << *AI << "\n\t\tINTO: " DEBUG(dbgs() << " ***MERGED ALLOCA: " << *AI
<< *AvailableAlloca << '\n'); << "\n\t\tINTO: " << *AvailableAlloca << '\n');
// Move affected dbg.declare calls immediately after the new alloca to // Move affected dbg.declare calls immediately after the new alloca to
// avoid the situation when a dbg.declare preceeds its alloca. // avoid the situation when a dbg.declare preceeds its alloca.
if (auto *L = LocalAsMetadata::getIfExists(AI)) if (auto *L = LocalAsMetadata::getIfExists(AI))
@ -226,7 +224,7 @@ static bool InlineCallIfPossible(
// If we already nuked the alloca, we're done with it. // If we already nuked the alloca, we're done with it.
if (MergedAwayAlloca) if (MergedAwayAlloca)
continue; continue;
// If we were unable to merge away the alloca either because there are no // If we were unable to merge away the alloca either because there are no
// allocas of the right type available or because we reused them all // allocas of the right type available or because we reused them all
// already, remember that this alloca came from an inlined function and mark // already, remember that this alloca came from an inlined function and mark
@ -235,7 +233,7 @@ static bool InlineCallIfPossible(
AllocasForType.push_back(AI); AllocasForType.push_back(AI);
UsedAllocas.insert(AI); UsedAllocas.insert(AI);
} }
return true; return true;
} }
@ -327,28 +325,28 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
static bool shouldInline(CallSite CS, static bool shouldInline(CallSite CS,
std::function<InlineCost(CallSite CS)> GetInlineCost) { std::function<InlineCost(CallSite CS)> GetInlineCost) {
InlineCost IC = GetInlineCost(CS); InlineCost IC = GetInlineCost(CS);
if (IC.isAlways()) { if (IC.isAlways()) {
DEBUG(dbgs() << " Inlining: cost=always" DEBUG(dbgs() << " Inlining: cost=always"
<< ", Call: " << *CS.getInstruction() << "\n"); << ", Call: " << *CS.getInstruction() << "\n");
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName()) + emitAnalysis(CS, Twine(CS.getCalledFunction()->getName()) +
" should always be inlined (cost=always)"); " should always be inlined (cost=always)");
return true; return true;
} }
if (IC.isNever()) { if (IC.isNever()) {
DEBUG(dbgs() << " NOT Inlining: cost=never" DEBUG(dbgs() << " NOT Inlining: cost=never"
<< ", Call: " << *CS.getInstruction() << "\n"); << ", Call: " << *CS.getInstruction() << "\n");
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() + emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() +
" should never be inlined (cost=never)")); " should never be inlined (cost=never)"));
return false; return false;
} }
Function *Caller = CS.getCaller(); Function *Caller = CS.getCaller();
if (!IC) { if (!IC) {
DEBUG(dbgs() << " NOT Inlining: cost=" << IC.getCost() DEBUG(dbgs() << " NOT Inlining: cost=" << IC.getCost()
<< ", thres=" << (IC.getCostDelta() + IC.getCost()) << ", thres=" << (IC.getCostDelta() + IC.getCost())
<< ", Call: " << *CS.getInstruction() << "\n"); << ", Call: " << *CS.getInstruction() << "\n");
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() + emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() +
" too costly to inline (cost=") + " too costly to inline (cost=") +
Twine(IC.getCost()) + ", threshold=" + Twine(IC.getCost()) + ", threshold=" +
@ -359,8 +357,8 @@ static bool shouldInline(CallSite CS,
int TotalSecondaryCost = 0; int TotalSecondaryCost = 0;
if (shouldBeDeferred(Caller, CS, IC, TotalSecondaryCost, GetInlineCost)) { if (shouldBeDeferred(Caller, CS, IC, TotalSecondaryCost, GetInlineCost)) {
DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction() DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction()
<< " Cost = " << IC.getCost() << " Cost = " << IC.getCost()
<< ", outer Cost = " << TotalSecondaryCost << '\n'); << ", outer Cost = " << TotalSecondaryCost << '\n');
emitAnalysis(CS, Twine("Not inlining. Cost of inlining " + emitAnalysis(CS, Twine("Not inlining. Cost of inlining " +
CS.getCalledFunction()->getName() + CS.getCalledFunction()->getName() +
" increases the cost of inlining " + " increases the cost of inlining " +
@ -369,8 +367,8 @@ static bool shouldInline(CallSite CS,
} }
DEBUG(dbgs() << " Inlining: cost=" << IC.getCost() DEBUG(dbgs() << " Inlining: cost=" << IC.getCost()
<< ", thres=" << (IC.getCostDelta() + IC.getCost()) << ", thres=" << (IC.getCostDelta() + IC.getCost())
<< ", Call: " << *CS.getInstruction() << '\n'); << ", Call: " << *CS.getInstruction() << '\n');
emitAnalysis( emitAnalysis(
CS, CS.getCalledFunction()->getName() + Twine(" can be inlined into ") + CS, CS.getCalledFunction()->getName() + Twine(" can be inlined into ") +
CS.getCaller()->getName() + " with cost=" + Twine(IC.getCost()) + CS.getCaller()->getName() + " with cost=" + Twine(IC.getCost()) +
@ -380,8 +378,9 @@ static bool shouldInline(CallSite CS,
/// Return true if the specified inline history ID /// Return true if the specified inline history ID
/// indicates an inline history that includes the specified function. /// indicates an inline history that includes the specified function.
static bool InlineHistoryIncludes(Function *F, int InlineHistoryID, static bool InlineHistoryIncludes(
const SmallVectorImpl<std::pair<Function*, int> > &InlineHistory) { Function *F, int InlineHistoryID,
const SmallVectorImpl<std::pair<Function *, int>> &InlineHistory) {
while (InlineHistoryID != -1) { while (InlineHistoryID != -1) {
assert(unsigned(InlineHistoryID) < InlineHistory.size() && assert(unsigned(InlineHistoryID) < InlineHistory.size() &&
"Invalid inline history ID"); "Invalid inline history ID");
@ -412,11 +411,12 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
std::function<InlineCost(CallSite CS)> GetInlineCost, std::function<InlineCost(CallSite CS)> GetInlineCost,
std::function<AAResults &(Function &)> AARGetter, std::function<AAResults &(Function &)> AARGetter,
ImportedFunctionsInliningStatistics &ImportedFunctionsStats) { ImportedFunctionsInliningStatistics &ImportedFunctionsStats) {
SmallPtrSet<Function*, 8> SCCFunctions; SmallPtrSet<Function *, 8> SCCFunctions;
DEBUG(dbgs() << "Inliner visiting SCC:"); DEBUG(dbgs() << "Inliner visiting SCC:");
for (CallGraphNode *Node : SCC) { for (CallGraphNode *Node : SCC) {
Function *F = Node->getFunction(); Function *F = Node->getFunction();
if (F) SCCFunctions.insert(F); if (F)
SCCFunctions.insert(F);
DEBUG(dbgs() << " " << (F ? F->getName() : "INDIRECTNODE")); DEBUG(dbgs() << " " << (F ? F->getName() : "INDIRECTNODE"));
} }
@ -424,17 +424,18 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// inline call sites in the original functions, not call sites that result // inline call sites in the original functions, not call sites that result
// from inlining other functions. // from inlining other functions.
SmallVector<std::pair<CallSite, int>, 16> CallSites; SmallVector<std::pair<CallSite, int>, 16> CallSites;
// When inlining a callee produces new call sites, we want to keep track of // When inlining a callee produces new call sites, we want to keep track of
// the fact that they were inlined from the callee. This allows us to avoid // the fact that they were inlined from the callee. This allows us to avoid
// infinite inlining in some obscure cases. To represent this, we use an // infinite inlining in some obscure cases. To represent this, we use an
// index into the InlineHistory vector. // index into the InlineHistory vector.
SmallVector<std::pair<Function*, int>, 8> InlineHistory; SmallVector<std::pair<Function *, int>, 8> InlineHistory;
for (CallGraphNode *Node : SCC) { for (CallGraphNode *Node : SCC) {
Function *F = Node->getFunction(); Function *F = Node->getFunction();
if (!F) continue; if (!F)
continue;
for (BasicBlock &BB : *F) for (BasicBlock &BB : *F)
for (Instruction &I : BB) { for (Instruction &I : BB) {
CallSite CS(cast<Value>(&I)); CallSite CS(cast<Value>(&I));
@ -442,14 +443,14 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// never be inlined. // never be inlined.
if (!CS || isa<IntrinsicInst>(I)) if (!CS || isa<IntrinsicInst>(I))
continue; continue;
// If this is a direct call to an external function, we can never inline // If this is a direct call to an external function, we can never inline
// it. If it is an indirect call, inlining may resolve it to be a // it. If it is an indirect call, inlining may resolve it to be a
// direct call, so we keep it. // direct call, so we keep it.
if (Function *Callee = CS.getCalledFunction()) if (Function *Callee = CS.getCalledFunction())
if (Callee->isDeclaration()) if (Callee->isDeclaration())
continue; continue;
CallSites.push_back(std::make_pair(CS, -1)); CallSites.push_back(std::make_pair(CS, -1));
} }
} }
@ -468,7 +469,6 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
if (SCCFunctions.count(F)) if (SCCFunctions.count(F))
std::swap(CallSites[i--], CallSites[--FirstCallInSCC]); std::swap(CallSites[i--], CallSites[--FirstCallInSCC]);
InlinedArrayAllocasTy InlinedArrayAllocas; InlinedArrayAllocasTy InlinedArrayAllocas;
InlineFunctionInfo InlineInfo(&CG, &GetAssumptionCache); InlineFunctionInfo InlineInfo(&CG, &GetAssumptionCache);
@ -483,7 +483,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// CallSites may be modified inside so ranged for loop can not be used. // CallSites may be modified inside so ranged for loop can not be used.
for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi) { for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi) {
CallSite CS = CallSites[CSi].first; CallSite CS = CallSites[CSi].first;
Function *Caller = CS.getCaller(); Function *Caller = CS.getCaller();
Function *Callee = CS.getCalledFunction(); Function *Callee = CS.getCalledFunction();
@ -492,16 +492,17 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// size. This happens because IPSCCP propagates the result out of the // size. This happens because IPSCCP propagates the result out of the
// call and then we're left with the dead call. // call and then we're left with the dead call.
if (isInstructionTriviallyDead(CS.getInstruction(), &TLI)) { if (isInstructionTriviallyDead(CS.getInstruction(), &TLI)) {
DEBUG(dbgs() << " -> Deleting dead call: " DEBUG(dbgs() << " -> Deleting dead call: " << *CS.getInstruction()
<< *CS.getInstruction() << "\n"); << "\n");
// Update the call graph by deleting the edge from Callee to Caller. // Update the call graph by deleting the edge from Callee to Caller.
CG[Caller]->removeCallEdgeFor(CS); CG[Caller]->removeCallEdgeFor(CS);
CS.getInstruction()->eraseFromParent(); CS.getInstruction()->eraseFromParent();
++NumCallsDeleted; ++NumCallsDeleted;
} else { } else {
// We can only inline direct calls to non-declarations. // We can only inline direct calls to non-declarations.
if (!Callee || Callee->isDeclaration()) continue; if (!Callee || Callee->isDeclaration())
continue;
// If this call site was obtained by inlining another function, verify // If this call site was obtained by inlining another function, verify
// that the include path for the function did not include the callee // that the include path for the function did not include the callee
// itself. If so, we'd be recursively inlining the same function, // itself. If so, we'd be recursively inlining the same function,
@ -511,7 +512,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
if (InlineHistoryID != -1 && if (InlineHistoryID != -1 &&
InlineHistoryIncludes(Callee, InlineHistoryID, InlineHistory)) InlineHistoryIncludes(Callee, InlineHistoryID, InlineHistory))
continue; continue;
LLVMContext &CallerCtx = Caller->getContext(); LLVMContext &CallerCtx = Caller->getContext();
// Get DebugLoc to report. CS will be invalid after Inliner. // Get DebugLoc to report. CS will be invalid after Inliner.
@ -556,30 +557,30 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
CallSites.push_back(std::make_pair(CallSite(Ptr), NewHistoryID)); CallSites.push_back(std::make_pair(CallSite(Ptr), NewHistoryID));
} }
} }
// If we inlined or deleted the last possible call site to the function, // If we inlined or deleted the last possible call site to the function,
// delete the function body now. // delete the function body now.
if (Callee && Callee->use_empty() && Callee->hasLocalLinkage() && if (Callee && Callee->use_empty() && Callee->hasLocalLinkage() &&
// TODO: Can remove if in SCC now. // TODO: Can remove if in SCC now.
!SCCFunctions.count(Callee) && !SCCFunctions.count(Callee) &&
// The function may be apparently dead, but if there are indirect // The function may be apparently dead, but if there are indirect
// callgraph references to the node, we cannot delete it yet, this // callgraph references to the node, we cannot delete it yet, this
// could invalidate the CGSCC iterator. // could invalidate the CGSCC iterator.
CG[Callee]->getNumReferences() == 0) { CG[Callee]->getNumReferences() == 0) {
DEBUG(dbgs() << " -> Deleting dead function: " DEBUG(dbgs() << " -> Deleting dead function: " << Callee->getName()
<< Callee->getName() << "\n"); << "\n");
CallGraphNode *CalleeNode = CG[Callee]; CallGraphNode *CalleeNode = CG[Callee];
// Remove any call graph edges from the callee to its callees. // Remove any call graph edges from the callee to its callees.
CalleeNode->removeAllCalledFunctions(); CalleeNode->removeAllCalledFunctions();
// Removing the node for callee from the call graph and delete it. // Removing the node for callee from the call graph and delete it.
delete CG.removeFunctionFromModule(CalleeNode); delete CG.removeFunctionFromModule(CalleeNode);
++NumDeleted; ++NumDeleted;
} }
// Remove this call site from the list. If possible, use // Remove this call site from the list. If possible, use
// swap/pop_back for efficiency, but do not use it if doing so would // swap/pop_back for efficiency, but do not use it if doing so would
// move a call site to a function in this SCC before the // move a call site to a function in this SCC before the
// 'FirstCallInSCC' barrier. // 'FirstCallInSCC' barrier.
@ -587,7 +588,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
CallSites[CSi] = CallSites.back(); CallSites[CSi] = CallSites.back();
CallSites.pop_back(); CallSites.pop_back();
} else { } else {
CallSites.erase(CallSites.begin()+CSi); CallSites.erase(CallSites.begin() + CSi);
} }
--CSi; --CSi;
@ -633,7 +634,7 @@ bool Inliner::doFinalization(CallGraph &CG) {
/// Remove dead functions that are not included in DNR (Do Not Remove) list. /// Remove dead functions that are not included in DNR (Do Not Remove) list.
bool Inliner::removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly) { bool Inliner::removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly) {
SmallVector<CallGraphNode*, 16> FunctionsToRemove; SmallVector<CallGraphNode *, 16> FunctionsToRemove;
SmallVector<CallGraphNode *, 16> DeadFunctionsInComdats; SmallVector<CallGraphNode *, 16> DeadFunctionsInComdats;
SmallDenseMap<const Comdat *, int, 16> ComdatEntriesAlive; SmallDenseMap<const Comdat *, int, 16> ComdatEntriesAlive;
@ -725,9 +726,9 @@ bool Inliner::removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly) {
// here to do this, it doesn't matter which order the functions are deleted // here to do this, it doesn't matter which order the functions are deleted
// in. // in.
array_pod_sort(FunctionsToRemove.begin(), FunctionsToRemove.end()); array_pod_sort(FunctionsToRemove.begin(), FunctionsToRemove.end());
FunctionsToRemove.erase(std::unique(FunctionsToRemove.begin(), FunctionsToRemove.erase(
FunctionsToRemove.end()), std::unique(FunctionsToRemove.begin(), FunctionsToRemove.end()),
FunctionsToRemove.end()); FunctionsToRemove.end());
for (CallGraphNode *CGN : FunctionsToRemove) { for (CallGraphNode *CGN : FunctionsToRemove) {
delete CG.removeFunctionFromModule(CGN); delete CG.removeFunctionFromModule(CGN);
++NumDeleted; ++NumDeleted;