diff options
Diffstat (limited to 'lib/Analysis/IPA/CallGraph.cpp')
-rw-r--r-- | lib/Analysis/IPA/CallGraph.cpp | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp index 67cf7f86e072..e2799d965a7d 100644 --- a/lib/Analysis/IPA/CallGraph.cpp +++ b/lib/Analysis/IPA/CallGraph.cpp @@ -24,8 +24,8 @@ CallGraph::CallGraph(Module &M) : M(M), Root(nullptr), ExternalCallingNode(getOrInsertFunction(nullptr)), CallsExternalNode(new CallGraphNode(nullptr)) { // Add every function to the call graph. - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - addToCallGraph(I); + for (Function &F : M) + addToCallGraph(&F); // If we didn't find a main function, use the external call graph node if (!Root) @@ -40,13 +40,11 @@ CallGraph::~CallGraph() { // Reset all node's use counts to zero before deleting them to prevent an // assertion from firing. #ifndef NDEBUG - for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end(); - I != E; ++I) - I->second->allReferencesDropped(); + for (auto &I : FunctionMap) + I.second->allReferencesDropped(); #endif - for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end(); - I != E; ++I) - delete I->second; + for (auto &I : FunctionMap) + delete I.second; } void CallGraph::addToCallGraph(Function *F) { @@ -81,8 +79,10 @@ void CallGraph::addToCallGraph(Function *F) { CallSite CS(cast<Value>(II)); if (CS) { const Function *Callee = CS.getCalledFunction(); - if (!Callee) + if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID())) // Indirect calls of intrinsics are not allowed so no need to check. + // We can be more precise here by using TargetArg returned by + // Intrinsic::isLeaf. Node->addCalledFunction(CS, CallsExternalNode); else if (!Callee->isIntrinsic()) Node->addCalledFunction(CS, getOrInsertFunction(Callee)); @@ -98,8 +98,26 @@ void CallGraph::print(raw_ostream &OS) const { OS << "<<null function: 0x" << Root << ">>\n"; } - for (CallGraph::const_iterator I = begin(), E = end(); I != E; ++I) - I->second->print(OS); + // Print in a deterministic order by sorting CallGraphNodes by name. We do + // this here to avoid slowing down the non-printing fast path. + + SmallVector<CallGraphNode *, 16> Nodes; + Nodes.reserve(FunctionMap.size()); + + for (auto I = begin(), E = end(); I != E; ++I) + Nodes.push_back(I->second); + + std::sort(Nodes.begin(), Nodes.end(), + [](CallGraphNode *LHS, CallGraphNode *RHS) { + if (Function *LF = LHS->getFunction()) + if (Function *RF = RHS->getFunction()) + return LF->getName() < RF->getName(); + + return RHS->getFunction() != nullptr; + }); + + for (CallGraphNode *CN : Nodes) + CN->print(OS); } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |