CallGraph::CallGraph(Module &M)
: M(M), Root(nullptr), ExternalCallingNode(getOrInsertFunction(nullptr)),
- CallsExternalNode(new CallGraphNode(nullptr)) {
+ CallsExternalNode(llvm::make_unique<CallGraphNode>(nullptr)) {
// Add every function to the call graph.
for (Function &F : M)
addToCallGraph(&F);
CallGraph::~CallGraph() {
// CallsExternalNode is not in the function map, delete it explicitly.
- CallsExternalNode->allReferencesDropped();
- delete CallsExternalNode;
+ if (CallsExternalNode)
+ CallsExternalNode->allReferencesDropped();
// Reset all node's use counts to zero before deleting them to prevent an
// assertion from firing.
for (auto &I : FunctionMap)
I.second->allReferencesDropped();
#endif
- for (auto &I : FunctionMap)
- delete I.second;
}
void CallGraph::addToCallGraph(Function *F) {
// If this function is not defined in this translation unit, it could call
// anything.
if (F->isDeclaration() && !F->isIntrinsic())
- Node->addCalledFunction(CallSite(), CallsExternalNode);
+ Node->addCalledFunction(CallSite(), CallsExternalNode.get());
// Look for calls by this function.
for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB)
// 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);
+ Node->addCalledFunction(CS, CallsExternalNode.get());
else if (!Callee->isIntrinsic())
Node->addCalledFunction(CS, getOrInsertFunction(Callee));
}
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.get());
+
+ 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)
assert(CGN->empty() && "Cannot remove function from call "
"graph if it references other functions!");
Function *F = CGN->getFunction(); // Get the function for the call graph node
- delete CGN; // Delete the call graph node for this func
FunctionMap.erase(F); // Remove the call graph node from the map
M.getFunctionList().remove(F);
"Pointing CallGraphNode at a function that already exists");
FunctionMapTy::iterator I = FunctionMap.find(From);
I->second->F = const_cast<Function*>(To);
- FunctionMap[To] = I->second;
+ FunctionMap[To] = std::move(I->second);
FunctionMap.erase(I);
}
// it will insert a new CallGraphNode for the specified function if one does
// not already exist.
CallGraphNode *CallGraph::getOrInsertFunction(const Function *F) {
- CallGraphNode *&CGN = FunctionMap[F];
+ auto &CGN = FunctionMap[F];
if (CGN)
- return CGN;
+ return CGN.get();
assert((!F || F->getParent() == &M) && "Function not in current module!");
- return CGN = new CallGraphNode(const_cast<Function*>(F));
+ CGN = llvm::make_unique<CallGraphNode>(const_cast<Function *>(F));
+ return CGN.get();
}
//===----------------------------------------------------------------------===//
}
}
-//===----------------------------------------------------------------------===//
-// Out-of-line definitions of CallGraphAnalysis class members.
-//
-
-char CallGraphAnalysis::PassID;
-
//===----------------------------------------------------------------------===//
// Implementations of the CallGraphWrapperPass class methods.
//