17d523365SDimitry Andric //===- CallGraph.cpp - Build a Module's call graph ------------------------===//
27d523365SDimitry Andric //
37d523365SDimitry Andric //                     The LLVM Compiler Infrastructure
47d523365SDimitry Andric //
57d523365SDimitry Andric // This file is distributed under the University of Illinois Open Source
67d523365SDimitry Andric // License. See LICENSE.TXT for details.
77d523365SDimitry Andric //
87d523365SDimitry Andric //===----------------------------------------------------------------------===//
97d523365SDimitry Andric 
107d523365SDimitry Andric #include "llvm/Analysis/CallGraph.h"
112cab237bSDimitry Andric #include "llvm/ADT/STLExtras.h"
122cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
134ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
147d523365SDimitry Andric #include "llvm/IR/CallSite.h"
157d523365SDimitry Andric #include "llvm/IR/Module.h"
162cab237bSDimitry Andric #include "llvm/IR/Function.h"
172cab237bSDimitry Andric #include "llvm/IR/Intrinsics.h"
182cab237bSDimitry Andric #include "llvm/IR/PassManager.h"
192cab237bSDimitry Andric #include "llvm/Pass.h"
202cab237bSDimitry Andric #include "llvm/Support/Compiler.h"
217d523365SDimitry Andric #include "llvm/Support/Debug.h"
227d523365SDimitry Andric #include "llvm/Support/raw_ostream.h"
232cab237bSDimitry Andric #include <algorithm>
242cab237bSDimitry Andric #include <cassert>
252cab237bSDimitry Andric 
267d523365SDimitry Andric using namespace llvm;
277d523365SDimitry Andric 
287d523365SDimitry Andric //===----------------------------------------------------------------------===//
297d523365SDimitry Andric // Implementations of the CallGraph class methods.
307d523365SDimitry Andric //
317d523365SDimitry Andric 
CallGraph(Module & M)327d523365SDimitry Andric CallGraph::CallGraph(Module &M)
335517e702SDimitry Andric     : M(M), ExternalCallingNode(getOrInsertFunction(nullptr)),
347d523365SDimitry Andric       CallsExternalNode(llvm::make_unique<CallGraphNode>(nullptr)) {
357d523365SDimitry Andric   // Add every function to the call graph.
367d523365SDimitry Andric   for (Function &F : M)
377d523365SDimitry Andric     addToCallGraph(&F);
387d523365SDimitry Andric }
397d523365SDimitry Andric 
CallGraph(CallGraph && Arg)407d523365SDimitry Andric CallGraph::CallGraph(CallGraph &&Arg)
415517e702SDimitry Andric     : M(Arg.M), FunctionMap(std::move(Arg.FunctionMap)),
427d523365SDimitry Andric       ExternalCallingNode(Arg.ExternalCallingNode),
437d523365SDimitry Andric       CallsExternalNode(std::move(Arg.CallsExternalNode)) {
447d523365SDimitry Andric   Arg.FunctionMap.clear();
457d523365SDimitry Andric   Arg.ExternalCallingNode = nullptr;
467d523365SDimitry Andric }
477d523365SDimitry Andric 
~CallGraph()487d523365SDimitry Andric CallGraph::~CallGraph() {
497d523365SDimitry Andric   // CallsExternalNode is not in the function map, delete it explicitly.
507d523365SDimitry Andric   if (CallsExternalNode)
517d523365SDimitry Andric     CallsExternalNode->allReferencesDropped();
527d523365SDimitry Andric 
537d523365SDimitry Andric // Reset all node's use counts to zero before deleting them to prevent an
547d523365SDimitry Andric // assertion from firing.
557d523365SDimitry Andric #ifndef NDEBUG
567d523365SDimitry Andric   for (auto &I : FunctionMap)
577d523365SDimitry Andric     I.second->allReferencesDropped();
587d523365SDimitry Andric #endif
597d523365SDimitry Andric }
607d523365SDimitry Andric 
addToCallGraph(Function * F)617d523365SDimitry Andric void CallGraph::addToCallGraph(Function *F) {
627d523365SDimitry Andric   CallGraphNode *Node = getOrInsertFunction(F);
637d523365SDimitry Andric 
645517e702SDimitry Andric   // If this function has external linkage or has its address taken, anything
655517e702SDimitry Andric   // could call it.
665517e702SDimitry Andric   if (!F->hasLocalLinkage() || F->hasAddressTaken())
677d523365SDimitry Andric     ExternalCallingNode->addCalledFunction(CallSite(), Node);
687d523365SDimitry Andric 
697d523365SDimitry Andric   // If this function is not defined in this translation unit, it could call
707d523365SDimitry Andric   // anything.
717d523365SDimitry Andric   if (F->isDeclaration() && !F->isIntrinsic())
727d523365SDimitry Andric     Node->addCalledFunction(CallSite(), CallsExternalNode.get());
737d523365SDimitry Andric 
747d523365SDimitry Andric   // Look for calls by this function.
753ca95b02SDimitry Andric   for (BasicBlock &BB : *F)
763ca95b02SDimitry Andric     for (Instruction &I : BB) {
773ca95b02SDimitry Andric       if (auto CS = CallSite(&I)) {
787d523365SDimitry Andric         const Function *Callee = CS.getCalledFunction();
797d523365SDimitry Andric         if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
807d523365SDimitry Andric           // Indirect calls of intrinsics are not allowed so no need to check.
817d523365SDimitry Andric           // We can be more precise here by using TargetArg returned by
827d523365SDimitry Andric           // Intrinsic::isLeaf.
837d523365SDimitry Andric           Node->addCalledFunction(CS, CallsExternalNode.get());
847d523365SDimitry Andric         else if (!Callee->isIntrinsic())
857d523365SDimitry Andric           Node->addCalledFunction(CS, getOrInsertFunction(Callee));
867d523365SDimitry Andric       }
877d523365SDimitry Andric     }
887d523365SDimitry Andric }
897d523365SDimitry Andric 
print(raw_ostream & OS) const907d523365SDimitry Andric void CallGraph::print(raw_ostream &OS) const {
917d523365SDimitry Andric   // Print in a deterministic order by sorting CallGraphNodes by name.  We do
927d523365SDimitry Andric   // this here to avoid slowing down the non-printing fast path.
937d523365SDimitry Andric 
947d523365SDimitry Andric   SmallVector<CallGraphNode *, 16> Nodes;
957d523365SDimitry Andric   Nodes.reserve(FunctionMap.size());
967d523365SDimitry Andric 
973ca95b02SDimitry Andric   for (const auto &I : *this)
983ca95b02SDimitry Andric     Nodes.push_back(I.second.get());
997d523365SDimitry Andric 
100*b5893f02SDimitry Andric   llvm::sort(Nodes, [](CallGraphNode *LHS, CallGraphNode *RHS) {
1017d523365SDimitry Andric     if (Function *LF = LHS->getFunction())
1027d523365SDimitry Andric       if (Function *RF = RHS->getFunction())
1037d523365SDimitry Andric         return LF->getName() < RF->getName();
1047d523365SDimitry Andric 
1057d523365SDimitry Andric     return RHS->getFunction() != nullptr;
1067d523365SDimitry Andric   });
1077d523365SDimitry Andric 
1087d523365SDimitry Andric   for (CallGraphNode *CN : Nodes)
1097d523365SDimitry Andric     CN->print(OS);
1107d523365SDimitry Andric }
1117d523365SDimitry Andric 
1127a7e6055SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1137a7e6055SDimitry Andric LLVM_DUMP_METHOD void CallGraph::dump() const { print(dbgs()); }
1147a7e6055SDimitry Andric #endif
1157d523365SDimitry Andric 
1167d523365SDimitry Andric // removeFunctionFromModule - Unlink the function from this module, returning
1177d523365SDimitry Andric // it.  Because this removes the function from the module, the call graph node
1187d523365SDimitry Andric // is destroyed.  This is only valid if the function does not call any other
1197d523365SDimitry Andric // functions (ie, there are no edges in it's CGN).  The easiest way to do this
1207d523365SDimitry Andric // is to dropAllReferences before calling this.
1217d523365SDimitry Andric //
removeFunctionFromModule(CallGraphNode * CGN)1227d523365SDimitry Andric Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) {
1237d523365SDimitry Andric   assert(CGN->empty() && "Cannot remove function from call "
1247d523365SDimitry Andric          "graph if it references other functions!");
1257d523365SDimitry Andric   Function *F = CGN->getFunction(); // Get the function for the call graph node
1267d523365SDimitry Andric   FunctionMap.erase(F);             // Remove the call graph node from the map
1277d523365SDimitry Andric 
1287d523365SDimitry Andric   M.getFunctionList().remove(F);
1297d523365SDimitry Andric   return F;
1307d523365SDimitry Andric }
1317d523365SDimitry Andric 
1327d523365SDimitry Andric /// spliceFunction - Replace the function represented by this node by another.
1337d523365SDimitry Andric /// This does not rescan the body of the function, so it is suitable when
1347d523365SDimitry Andric /// splicing the body of the old function to the new while also updating all
1357d523365SDimitry Andric /// callers from old to new.
spliceFunction(const Function * From,const Function * To)1367d523365SDimitry Andric void CallGraph::spliceFunction(const Function *From, const Function *To) {
1377d523365SDimitry Andric   assert(FunctionMap.count(From) && "No CallGraphNode for function!");
1387d523365SDimitry Andric   assert(!FunctionMap.count(To) &&
1397d523365SDimitry Andric          "Pointing CallGraphNode at a function that already exists");
1407d523365SDimitry Andric   FunctionMapTy::iterator I = FunctionMap.find(From);
1417d523365SDimitry Andric   I->second->F = const_cast<Function*>(To);
1427d523365SDimitry Andric   FunctionMap[To] = std::move(I->second);
1437d523365SDimitry Andric   FunctionMap.erase(I);
1447d523365SDimitry Andric }
1457d523365SDimitry Andric 
1467d523365SDimitry Andric // getOrInsertFunction - This method is identical to calling operator[], but
1477d523365SDimitry Andric // it will insert a new CallGraphNode for the specified function if one does
1487d523365SDimitry Andric // not already exist.
getOrInsertFunction(const Function * F)1497d523365SDimitry Andric CallGraphNode *CallGraph::getOrInsertFunction(const Function *F) {
1507d523365SDimitry Andric   auto &CGN = FunctionMap[F];
1517d523365SDimitry Andric   if (CGN)
1527d523365SDimitry Andric     return CGN.get();
1537d523365SDimitry Andric 
1547d523365SDimitry Andric   assert((!F || F->getParent() == &M) && "Function not in current module!");
1557d523365SDimitry Andric   CGN = llvm::make_unique<CallGraphNode>(const_cast<Function *>(F));
1567d523365SDimitry Andric   return CGN.get();
1577d523365SDimitry Andric }
1587d523365SDimitry Andric 
1597d523365SDimitry Andric //===----------------------------------------------------------------------===//
1607d523365SDimitry Andric // Implementations of the CallGraphNode class methods.
1617d523365SDimitry Andric //
1627d523365SDimitry Andric 
print(raw_ostream & OS) const1637d523365SDimitry Andric void CallGraphNode::print(raw_ostream &OS) const {
1647d523365SDimitry Andric   if (Function *F = getFunction())
1657d523365SDimitry Andric     OS << "Call graph node for function: '" << F->getName() << "'";
1667d523365SDimitry Andric   else
1677d523365SDimitry Andric     OS << "Call graph node <<null function>>";
1687d523365SDimitry Andric 
1697d523365SDimitry Andric   OS << "<<" << this << ">>  #uses=" << getNumReferences() << '\n';
1707d523365SDimitry Andric 
1713ca95b02SDimitry Andric   for (const auto &I : *this) {
1723ca95b02SDimitry Andric     OS << "  CS<" << I.first << "> calls ";
1733ca95b02SDimitry Andric     if (Function *FI = I.second->getFunction())
1747d523365SDimitry Andric       OS << "function '" << FI->getName() <<"'\n";
1757d523365SDimitry Andric     else
1767d523365SDimitry Andric       OS << "external node\n";
1777d523365SDimitry Andric   }
1787d523365SDimitry Andric   OS << '\n';
1797d523365SDimitry Andric }
1807d523365SDimitry Andric 
1817a7e6055SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1827a7e6055SDimitry Andric LLVM_DUMP_METHOD void CallGraphNode::dump() const { print(dbgs()); }
1837a7e6055SDimitry Andric #endif
1847d523365SDimitry Andric 
1857d523365SDimitry Andric /// removeCallEdgeFor - This method removes the edge in the node for the
1867d523365SDimitry Andric /// specified call site.  Note that this method takes linear time, so it
1877d523365SDimitry Andric /// should be used sparingly.
removeCallEdgeFor(CallSite CS)1887d523365SDimitry Andric void CallGraphNode::removeCallEdgeFor(CallSite CS) {
1897d523365SDimitry Andric   for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
1907d523365SDimitry Andric     assert(I != CalledFunctions.end() && "Cannot find callsite to remove!");
1917d523365SDimitry Andric     if (I->first == CS.getInstruction()) {
1927d523365SDimitry Andric       I->second->DropRef();
1937d523365SDimitry Andric       *I = CalledFunctions.back();
1947d523365SDimitry Andric       CalledFunctions.pop_back();
1957d523365SDimitry Andric       return;
1967d523365SDimitry Andric     }
1977d523365SDimitry Andric   }
1987d523365SDimitry Andric }
1997d523365SDimitry Andric 
2007d523365SDimitry Andric // removeAnyCallEdgeTo - This method removes any call edges from this node to
2017d523365SDimitry Andric // the specified callee function.  This takes more time to execute than
2027d523365SDimitry Andric // removeCallEdgeTo, so it should not be used unless necessary.
removeAnyCallEdgeTo(CallGraphNode * Callee)2037d523365SDimitry Andric void CallGraphNode::removeAnyCallEdgeTo(CallGraphNode *Callee) {
2047d523365SDimitry Andric   for (unsigned i = 0, e = CalledFunctions.size(); i != e; ++i)
2057d523365SDimitry Andric     if (CalledFunctions[i].second == Callee) {
2067d523365SDimitry Andric       Callee->DropRef();
2077d523365SDimitry Andric       CalledFunctions[i] = CalledFunctions.back();
2087d523365SDimitry Andric       CalledFunctions.pop_back();
2097d523365SDimitry Andric       --i; --e;
2107d523365SDimitry Andric     }
2117d523365SDimitry Andric }
2127d523365SDimitry Andric 
2137d523365SDimitry Andric /// removeOneAbstractEdgeTo - Remove one edge associated with a null callsite
2147d523365SDimitry Andric /// from this node to the specified callee function.
removeOneAbstractEdgeTo(CallGraphNode * Callee)2157d523365SDimitry Andric void CallGraphNode::removeOneAbstractEdgeTo(CallGraphNode *Callee) {
2167d523365SDimitry Andric   for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
2177d523365SDimitry Andric     assert(I != CalledFunctions.end() && "Cannot find callee to remove!");
2187d523365SDimitry Andric     CallRecord &CR = *I;
2197d523365SDimitry Andric     if (CR.second == Callee && CR.first == nullptr) {
2207d523365SDimitry Andric       Callee->DropRef();
2217d523365SDimitry Andric       *I = CalledFunctions.back();
2227d523365SDimitry Andric       CalledFunctions.pop_back();
2237d523365SDimitry Andric       return;
2247d523365SDimitry Andric     }
2257d523365SDimitry Andric   }
2267d523365SDimitry Andric }
2277d523365SDimitry Andric 
2287d523365SDimitry Andric /// replaceCallEdge - This method replaces the edge in the node for the
2297d523365SDimitry Andric /// specified call site with a new one.  Note that this method takes linear
2307d523365SDimitry Andric /// time, so it should be used sparingly.
replaceCallEdge(CallSite CS,CallSite NewCS,CallGraphNode * NewNode)2317d523365SDimitry Andric void CallGraphNode::replaceCallEdge(CallSite CS,
2327d523365SDimitry Andric                                     CallSite NewCS, CallGraphNode *NewNode){
2337d523365SDimitry Andric   for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
2347d523365SDimitry Andric     assert(I != CalledFunctions.end() && "Cannot find callsite to remove!");
2357d523365SDimitry Andric     if (I->first == CS.getInstruction()) {
2367d523365SDimitry Andric       I->second->DropRef();
2377d523365SDimitry Andric       I->first = NewCS.getInstruction();
2387d523365SDimitry Andric       I->second = NewNode;
2397d523365SDimitry Andric       NewNode->AddRef();
2407d523365SDimitry Andric       return;
2417d523365SDimitry Andric     }
2427d523365SDimitry Andric   }
2437d523365SDimitry Andric }
2447d523365SDimitry Andric 
2453ca95b02SDimitry Andric // Provide an explicit template instantiation for the static ID.
246d88c1a5aSDimitry Andric AnalysisKey CallGraphAnalysis::Key;
2473ca95b02SDimitry Andric 
run(Module & M,ModuleAnalysisManager & AM)2483ca95b02SDimitry Andric PreservedAnalyses CallGraphPrinterPass::run(Module &M,
249d88c1a5aSDimitry Andric                                             ModuleAnalysisManager &AM) {
2503ca95b02SDimitry Andric   AM.getResult<CallGraphAnalysis>(M).print(OS);
2513ca95b02SDimitry Andric   return PreservedAnalyses::all();
2523ca95b02SDimitry Andric }
2533ca95b02SDimitry Andric 
2547d523365SDimitry Andric //===----------------------------------------------------------------------===//
2557d523365SDimitry Andric // Out-of-line definitions of CallGraphAnalysis class members.
2567d523365SDimitry Andric //
2577d523365SDimitry Andric 
2587d523365SDimitry Andric //===----------------------------------------------------------------------===//
2597d523365SDimitry Andric // Implementations of the CallGraphWrapperPass class methods.
2607d523365SDimitry Andric //
2617d523365SDimitry Andric 
CallGraphWrapperPass()2627d523365SDimitry Andric CallGraphWrapperPass::CallGraphWrapperPass() : ModulePass(ID) {
2637d523365SDimitry Andric   initializeCallGraphWrapperPassPass(*PassRegistry::getPassRegistry());
2647d523365SDimitry Andric }
2657d523365SDimitry Andric 
2662cab237bSDimitry Andric CallGraphWrapperPass::~CallGraphWrapperPass() = default;
2677d523365SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const2687d523365SDimitry Andric void CallGraphWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
2697d523365SDimitry Andric   AU.setPreservesAll();
2707d523365SDimitry Andric }
2717d523365SDimitry Andric 
runOnModule(Module & M)2727d523365SDimitry Andric bool CallGraphWrapperPass::runOnModule(Module &M) {
2737d523365SDimitry Andric   // All the real work is done in the constructor for the CallGraph.
2747d523365SDimitry Andric   G.reset(new CallGraph(M));
2757d523365SDimitry Andric   return false;
2767d523365SDimitry Andric }
2777d523365SDimitry Andric 
2787d523365SDimitry Andric INITIALIZE_PASS(CallGraphWrapperPass, "basiccg", "CallGraph Construction",
2797d523365SDimitry Andric                 false, true)
2807d523365SDimitry Andric 
2817d523365SDimitry Andric char CallGraphWrapperPass::ID = 0;
2827d523365SDimitry Andric 
releaseMemory()2837d523365SDimitry Andric void CallGraphWrapperPass::releaseMemory() { G.reset(); }
2847d523365SDimitry Andric 
print(raw_ostream & OS,const Module *) const2857d523365SDimitry Andric void CallGraphWrapperPass::print(raw_ostream &OS, const Module *) const {
2867d523365SDimitry Andric   if (!G) {
2877d523365SDimitry Andric     OS << "No call graph has been built!\n";
2887d523365SDimitry Andric     return;
2897d523365SDimitry Andric   }
2907d523365SDimitry Andric 
2917d523365SDimitry Andric   // Just delegate.
2927d523365SDimitry Andric   G->print(OS);
2937d523365SDimitry Andric }
2947d523365SDimitry Andric 
2957a7e6055SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2967d523365SDimitry Andric LLVM_DUMP_METHOD
dump() const2977d523365SDimitry Andric void CallGraphWrapperPass::dump() const { print(dbgs(), nullptr); }
2987a7e6055SDimitry Andric #endif
2993ca95b02SDimitry Andric 
3003ca95b02SDimitry Andric namespace {
3012cab237bSDimitry Andric 
3023ca95b02SDimitry Andric struct CallGraphPrinterLegacyPass : public ModulePass {
3033ca95b02SDimitry Andric   static char ID; // Pass ID, replacement for typeid
3042cab237bSDimitry Andric 
CallGraphPrinterLegacyPass__anonb6eff0760211::CallGraphPrinterLegacyPass3053ca95b02SDimitry Andric   CallGraphPrinterLegacyPass() : ModulePass(ID) {
3063ca95b02SDimitry Andric     initializeCallGraphPrinterLegacyPassPass(*PassRegistry::getPassRegistry());
3073ca95b02SDimitry Andric   }
3083ca95b02SDimitry Andric 
getAnalysisUsage__anonb6eff0760211::CallGraphPrinterLegacyPass3093ca95b02SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
3103ca95b02SDimitry Andric     AU.setPreservesAll();
3113ca95b02SDimitry Andric     AU.addRequiredTransitive<CallGraphWrapperPass>();
3123ca95b02SDimitry Andric   }
3132cab237bSDimitry Andric 
runOnModule__anonb6eff0760211::CallGraphPrinterLegacyPass3143ca95b02SDimitry Andric   bool runOnModule(Module &M) override {
3153ca95b02SDimitry Andric     getAnalysis<CallGraphWrapperPass>().print(errs(), &M);
3163ca95b02SDimitry Andric     return false;
3173ca95b02SDimitry Andric   }
3183ca95b02SDimitry Andric };
3192cab237bSDimitry Andric 
3202cab237bSDimitry Andric } // end anonymous namespace
3213ca95b02SDimitry Andric 
3223ca95b02SDimitry Andric char CallGraphPrinterLegacyPass::ID = 0;
3233ca95b02SDimitry Andric 
3243ca95b02SDimitry Andric INITIALIZE_PASS_BEGIN(CallGraphPrinterLegacyPass, "print-callgraph",
3253ca95b02SDimitry Andric                       "Print a call graph", true, true)
3263ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
3273ca95b02SDimitry Andric INITIALIZE_PASS_END(CallGraphPrinterLegacyPass, "print-callgraph",
3283ca95b02SDimitry Andric                     "Print a call graph", true, true)
329