aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/IPA/CallGraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/IPA/CallGraph.cpp')
-rw-r--r--lib/Analysis/IPA/CallGraph.cpp40
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)