xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- CallGraph.cpp - Build a Module's call graph ------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/Analysis/CallGraph.h"
10bdd1243dSDimitry Andric #include "llvm/ADT/SCCIterator.h"
110b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
120b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
130b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
145ffd83dbSDimitry Andric #include "llvm/IR/AbstractCallSite.h"
150b57cec5SDimitry Andric #include "llvm/IR/Function.h"
165ffd83dbSDimitry Andric #include "llvm/IR/IntrinsicInst.h"
17480093f4SDimitry Andric #include "llvm/IR/Module.h"
180b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
19480093f4SDimitry Andric #include "llvm/InitializePasses.h"
200b57cec5SDimitry Andric #include "llvm/Pass.h"
210b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
220b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
230b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
240b57cec5SDimitry Andric #include <cassert>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
290b57cec5SDimitry Andric // Implementations of the CallGraph class methods.
300b57cec5SDimitry Andric //
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric CallGraph::CallGraph(Module &M)
330b57cec5SDimitry Andric     : M(M), ExternalCallingNode(getOrInsertFunction(nullptr)),
345ffd83dbSDimitry Andric       CallsExternalNode(std::make_unique<CallGraphNode>(this, nullptr)) {
355ffd83dbSDimitry Andric   // Add every interesting function to the call graph.
360b57cec5SDimitry Andric   for (Function &F : M)
375ffd83dbSDimitry Andric     if (!isDbgInfoIntrinsic(F.getIntrinsicID()))
380b57cec5SDimitry Andric       addToCallGraph(&F);
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric CallGraph::CallGraph(CallGraph &&Arg)
420b57cec5SDimitry Andric     : M(Arg.M), FunctionMap(std::move(Arg.FunctionMap)),
430b57cec5SDimitry Andric       ExternalCallingNode(Arg.ExternalCallingNode),
440b57cec5SDimitry Andric       CallsExternalNode(std::move(Arg.CallsExternalNode)) {
450b57cec5SDimitry Andric   Arg.FunctionMap.clear();
460b57cec5SDimitry Andric   Arg.ExternalCallingNode = nullptr;
475ffd83dbSDimitry Andric 
485ffd83dbSDimitry Andric   // Update parent CG for all call graph's nodes.
495ffd83dbSDimitry Andric   CallsExternalNode->CG = this;
505ffd83dbSDimitry Andric   for (auto &P : FunctionMap)
515ffd83dbSDimitry Andric     P.second->CG = this;
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric CallGraph::~CallGraph() {
550b57cec5SDimitry Andric   // CallsExternalNode is not in the function map, delete it explicitly.
560b57cec5SDimitry Andric   if (CallsExternalNode)
570b57cec5SDimitry Andric     CallsExternalNode->allReferencesDropped();
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric // Reset all node's use counts to zero before deleting them to prevent an
600b57cec5SDimitry Andric // assertion from firing.
610b57cec5SDimitry Andric #ifndef NDEBUG
620b57cec5SDimitry Andric   for (auto &I : FunctionMap)
630b57cec5SDimitry Andric     I.second->allReferencesDropped();
640b57cec5SDimitry Andric #endif
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
675ffd83dbSDimitry Andric bool CallGraph::invalidate(Module &, const PreservedAnalyses &PA,
685ffd83dbSDimitry Andric                            ModuleAnalysisManager::Invalidator &) {
695ffd83dbSDimitry Andric   // Check whether the analysis, all analyses on functions, or the function's
705ffd83dbSDimitry Andric   // CFG have been preserved.
715ffd83dbSDimitry Andric   auto PAC = PA.getChecker<CallGraphAnalysis>();
7281ad6265SDimitry Andric   return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>());
735ffd83dbSDimitry Andric }
745ffd83dbSDimitry Andric 
750b57cec5SDimitry Andric void CallGraph::addToCallGraph(Function *F) {
760b57cec5SDimitry Andric   CallGraphNode *Node = getOrInsertFunction(F);
770b57cec5SDimitry Andric 
785ffd83dbSDimitry Andric   // If this function has external linkage or has its address taken and
795ffd83dbSDimitry Andric   // it is not a callback, then anything could call it.
805ffd83dbSDimitry Andric   if (!F->hasLocalLinkage() ||
81fe6060f1SDimitry Andric       F->hasAddressTaken(nullptr, /*IgnoreCallbackUses=*/true,
82fe6060f1SDimitry Andric                          /* IgnoreAssumeLikeCalls */ true,
83fe6060f1SDimitry Andric                          /* IgnoreLLVMUsed */ false))
840b57cec5SDimitry Andric     ExternalCallingNode->addCalledFunction(nullptr, Node);
850b57cec5SDimitry Andric 
865ffd83dbSDimitry Andric   populateCallGraphNode(Node);
875ffd83dbSDimitry Andric }
885ffd83dbSDimitry Andric 
895ffd83dbSDimitry Andric void CallGraph::populateCallGraphNode(CallGraphNode *Node) {
905ffd83dbSDimitry Andric   Function *F = Node->getFunction();
915ffd83dbSDimitry Andric 
920b57cec5SDimitry Andric   // If this function is not defined in this translation unit, it could call
930b57cec5SDimitry Andric   // anything.
94bdd1243dSDimitry Andric   if (F->isDeclaration() && !F->hasFnAttribute(Attribute::NoCallback))
950b57cec5SDimitry Andric     Node->addCalledFunction(nullptr, CallsExternalNode.get());
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   // Look for calls by this function.
980b57cec5SDimitry Andric   for (BasicBlock &BB : *F)
990b57cec5SDimitry Andric     for (Instruction &I : BB) {
1000b57cec5SDimitry Andric       if (auto *Call = dyn_cast<CallBase>(&I)) {
1010b57cec5SDimitry Andric         const Function *Callee = Call->getCalledFunction();
102bdd1243dSDimitry Andric         if (!Callee)
1030b57cec5SDimitry Andric           Node->addCalledFunction(Call, CallsExternalNode.get());
104bdd1243dSDimitry Andric         else if (!isDbgInfoIntrinsic(Callee->getIntrinsicID()))
1050b57cec5SDimitry Andric           Node->addCalledFunction(Call, getOrInsertFunction(Callee));
1065ffd83dbSDimitry Andric 
1075ffd83dbSDimitry Andric         // Add reference to callback functions.
1085ffd83dbSDimitry Andric         forEachCallbackFunction(*Call, [=](Function *CB) {
1095ffd83dbSDimitry Andric           Node->addCalledFunction(nullptr, getOrInsertFunction(CB));
1105ffd83dbSDimitry Andric         });
1110b57cec5SDimitry Andric       }
1120b57cec5SDimitry Andric     }
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric void CallGraph::print(raw_ostream &OS) const {
1160b57cec5SDimitry Andric   // Print in a deterministic order by sorting CallGraphNodes by name.  We do
1170b57cec5SDimitry Andric   // this here to avoid slowing down the non-printing fast path.
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   SmallVector<CallGraphNode *, 16> Nodes;
1200b57cec5SDimitry Andric   Nodes.reserve(FunctionMap.size());
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   for (const auto &I : *this)
1230b57cec5SDimitry Andric     Nodes.push_back(I.second.get());
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   llvm::sort(Nodes, [](CallGraphNode *LHS, CallGraphNode *RHS) {
1260b57cec5SDimitry Andric     if (Function *LF = LHS->getFunction())
1270b57cec5SDimitry Andric       if (Function *RF = RHS->getFunction())
1280b57cec5SDimitry Andric         return LF->getName() < RF->getName();
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric     return RHS->getFunction() != nullptr;
1310b57cec5SDimitry Andric   });
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   for (CallGraphNode *CN : Nodes)
1340b57cec5SDimitry Andric     CN->print(OS);
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1380b57cec5SDimitry Andric LLVM_DUMP_METHOD void CallGraph::dump() const { print(dbgs()); }
1390b57cec5SDimitry Andric #endif
1400b57cec5SDimitry Andric 
1415ffd83dbSDimitry Andric void CallGraph::ReplaceExternalCallEdge(CallGraphNode *Old,
1425ffd83dbSDimitry Andric                                         CallGraphNode *New) {
1435ffd83dbSDimitry Andric   for (auto &CR : ExternalCallingNode->CalledFunctions)
1445ffd83dbSDimitry Andric     if (CR.second == Old) {
1455ffd83dbSDimitry Andric       CR.second->DropRef();
1465ffd83dbSDimitry Andric       CR.second = New;
1475ffd83dbSDimitry Andric       CR.second->AddRef();
1485ffd83dbSDimitry Andric     }
1495ffd83dbSDimitry Andric }
1505ffd83dbSDimitry Andric 
1510b57cec5SDimitry Andric // removeFunctionFromModule - Unlink the function from this module, returning
1520b57cec5SDimitry Andric // it.  Because this removes the function from the module, the call graph node
1530b57cec5SDimitry Andric // is destroyed.  This is only valid if the function does not call any other
1540b57cec5SDimitry Andric // functions (ie, there are no edges in it's CGN).  The easiest way to do this
1550b57cec5SDimitry Andric // is to dropAllReferences before calling this.
1560b57cec5SDimitry Andric //
1570b57cec5SDimitry Andric Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) {
1580b57cec5SDimitry Andric   assert(CGN->empty() && "Cannot remove function from call "
1590b57cec5SDimitry Andric          "graph if it references other functions!");
1600b57cec5SDimitry Andric   Function *F = CGN->getFunction(); // Get the function for the call graph node
1610b57cec5SDimitry Andric   FunctionMap.erase(F);             // Remove the call graph node from the map
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   M.getFunctionList().remove(F);
1640b57cec5SDimitry Andric   return F;
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric // getOrInsertFunction - This method is identical to calling operator[], but
1680b57cec5SDimitry Andric // it will insert a new CallGraphNode for the specified function if one does
1690b57cec5SDimitry Andric // not already exist.
1700b57cec5SDimitry Andric CallGraphNode *CallGraph::getOrInsertFunction(const Function *F) {
1710b57cec5SDimitry Andric   auto &CGN = FunctionMap[F];
1720b57cec5SDimitry Andric   if (CGN)
1730b57cec5SDimitry Andric     return CGN.get();
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   assert((!F || F->getParent() == &M) && "Function not in current module!");
1765ffd83dbSDimitry Andric   CGN = std::make_unique<CallGraphNode>(this, const_cast<Function *>(F));
1770b57cec5SDimitry Andric   return CGN.get();
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1810b57cec5SDimitry Andric // Implementations of the CallGraphNode class methods.
1820b57cec5SDimitry Andric //
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric void CallGraphNode::print(raw_ostream &OS) const {
1850b57cec5SDimitry Andric   if (Function *F = getFunction())
1860b57cec5SDimitry Andric     OS << "Call graph node for function: '" << F->getName() << "'";
1870b57cec5SDimitry Andric   else
1880b57cec5SDimitry Andric     OS << "Call graph node <<null function>>";
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   OS << "<<" << this << ">>  #uses=" << getNumReferences() << '\n';
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   for (const auto &I : *this) {
1930b57cec5SDimitry Andric     OS << "  CS<" << I.first << "> calls ";
1940b57cec5SDimitry Andric     if (Function *FI = I.second->getFunction())
1950b57cec5SDimitry Andric       OS << "function '" << FI->getName() <<"'\n";
1960b57cec5SDimitry Andric     else
1970b57cec5SDimitry Andric       OS << "external node\n";
1980b57cec5SDimitry Andric   }
1990b57cec5SDimitry Andric   OS << '\n';
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2030b57cec5SDimitry Andric LLVM_DUMP_METHOD void CallGraphNode::dump() const { print(dbgs()); }
2040b57cec5SDimitry Andric #endif
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric /// removeCallEdgeFor - This method removes the edge in the node for the
2070b57cec5SDimitry Andric /// specified call site.  Note that this method takes linear time, so it
2080b57cec5SDimitry Andric /// should be used sparingly.
2090b57cec5SDimitry Andric void CallGraphNode::removeCallEdgeFor(CallBase &Call) {
2100b57cec5SDimitry Andric   for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
2110b57cec5SDimitry Andric     assert(I != CalledFunctions.end() && "Cannot find callsite to remove!");
2125ffd83dbSDimitry Andric     if (I->first && *I->first == &Call) {
2130b57cec5SDimitry Andric       I->second->DropRef();
2140b57cec5SDimitry Andric       *I = CalledFunctions.back();
2150b57cec5SDimitry Andric       CalledFunctions.pop_back();
2165ffd83dbSDimitry Andric 
2175ffd83dbSDimitry Andric       // Remove all references to callback functions if there are any.
2185ffd83dbSDimitry Andric       forEachCallbackFunction(Call, [=](Function *CB) {
2195ffd83dbSDimitry Andric         removeOneAbstractEdgeTo(CG->getOrInsertFunction(CB));
2205ffd83dbSDimitry Andric       });
2210b57cec5SDimitry Andric       return;
2220b57cec5SDimitry Andric     }
2230b57cec5SDimitry Andric   }
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric // removeAnyCallEdgeTo - This method removes any call edges from this node to
2270b57cec5SDimitry Andric // the specified callee function.  This takes more time to execute than
2280b57cec5SDimitry Andric // removeCallEdgeTo, so it should not be used unless necessary.
2290b57cec5SDimitry Andric void CallGraphNode::removeAnyCallEdgeTo(CallGraphNode *Callee) {
2300b57cec5SDimitry Andric   for (unsigned i = 0, e = CalledFunctions.size(); i != e; ++i)
2310b57cec5SDimitry Andric     if (CalledFunctions[i].second == Callee) {
2320b57cec5SDimitry Andric       Callee->DropRef();
2330b57cec5SDimitry Andric       CalledFunctions[i] = CalledFunctions.back();
2340b57cec5SDimitry Andric       CalledFunctions.pop_back();
2350b57cec5SDimitry Andric       --i; --e;
2360b57cec5SDimitry Andric     }
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric /// removeOneAbstractEdgeTo - Remove one edge associated with a null callsite
2400b57cec5SDimitry Andric /// from this node to the specified callee function.
2410b57cec5SDimitry Andric void CallGraphNode::removeOneAbstractEdgeTo(CallGraphNode *Callee) {
2420b57cec5SDimitry Andric   for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
2430b57cec5SDimitry Andric     assert(I != CalledFunctions.end() && "Cannot find callee to remove!");
2440b57cec5SDimitry Andric     CallRecord &CR = *I;
2455ffd83dbSDimitry Andric     if (CR.second == Callee && !CR.first) {
2460b57cec5SDimitry Andric       Callee->DropRef();
2470b57cec5SDimitry Andric       *I = CalledFunctions.back();
2480b57cec5SDimitry Andric       CalledFunctions.pop_back();
2490b57cec5SDimitry Andric       return;
2500b57cec5SDimitry Andric     }
2510b57cec5SDimitry Andric   }
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric /// replaceCallEdge - This method replaces the edge in the node for the
2550b57cec5SDimitry Andric /// specified call site with a new one.  Note that this method takes linear
2560b57cec5SDimitry Andric /// time, so it should be used sparingly.
2570b57cec5SDimitry Andric void CallGraphNode::replaceCallEdge(CallBase &Call, CallBase &NewCall,
2580b57cec5SDimitry Andric                                     CallGraphNode *NewNode) {
2590b57cec5SDimitry Andric   for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
2600b57cec5SDimitry Andric     assert(I != CalledFunctions.end() && "Cannot find callsite to remove!");
2615ffd83dbSDimitry Andric     if (I->first && *I->first == &Call) {
2620b57cec5SDimitry Andric       I->second->DropRef();
2630b57cec5SDimitry Andric       I->first = &NewCall;
2640b57cec5SDimitry Andric       I->second = NewNode;
2650b57cec5SDimitry Andric       NewNode->AddRef();
2665ffd83dbSDimitry Andric 
267e8d8bef9SDimitry Andric       // Refresh callback references. Do not resize CalledFunctions if the
268e8d8bef9SDimitry Andric       // number of callbacks is the same for new and old call sites.
269e8d8bef9SDimitry Andric       SmallVector<CallGraphNode *, 4u> OldCBs;
270e8d8bef9SDimitry Andric       SmallVector<CallGraphNode *, 4u> NewCBs;
271e8d8bef9SDimitry Andric       forEachCallbackFunction(Call, [this, &OldCBs](Function *CB) {
272e8d8bef9SDimitry Andric         OldCBs.push_back(CG->getOrInsertFunction(CB));
2735ffd83dbSDimitry Andric       });
274e8d8bef9SDimitry Andric       forEachCallbackFunction(NewCall, [this, &NewCBs](Function *CB) {
275e8d8bef9SDimitry Andric         NewCBs.push_back(CG->getOrInsertFunction(CB));
2765ffd83dbSDimitry Andric       });
277e8d8bef9SDimitry Andric       if (OldCBs.size() == NewCBs.size()) {
278e8d8bef9SDimitry Andric         for (unsigned N = 0; N < OldCBs.size(); ++N) {
279e8d8bef9SDimitry Andric           CallGraphNode *OldNode = OldCBs[N];
280e8d8bef9SDimitry Andric           CallGraphNode *NewNode = NewCBs[N];
281e8d8bef9SDimitry Andric           for (auto J = CalledFunctions.begin();; ++J) {
282e8d8bef9SDimitry Andric             assert(J != CalledFunctions.end() &&
283e8d8bef9SDimitry Andric                    "Cannot find callsite to update!");
284e8d8bef9SDimitry Andric             if (!J->first && J->second == OldNode) {
285e8d8bef9SDimitry Andric               J->second = NewNode;
286e8d8bef9SDimitry Andric               OldNode->DropRef();
287e8d8bef9SDimitry Andric               NewNode->AddRef();
288e8d8bef9SDimitry Andric               break;
289e8d8bef9SDimitry Andric             }
290e8d8bef9SDimitry Andric           }
291e8d8bef9SDimitry Andric         }
292e8d8bef9SDimitry Andric       } else {
293e8d8bef9SDimitry Andric         for (auto *CGN : OldCBs)
294e8d8bef9SDimitry Andric           removeOneAbstractEdgeTo(CGN);
295e8d8bef9SDimitry Andric         for (auto *CGN : NewCBs)
296e8d8bef9SDimitry Andric           addCalledFunction(nullptr, CGN);
297e8d8bef9SDimitry Andric       }
2980b57cec5SDimitry Andric       return;
2990b57cec5SDimitry Andric     }
3000b57cec5SDimitry Andric   }
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric // Provide an explicit template instantiation for the static ID.
3040b57cec5SDimitry Andric AnalysisKey CallGraphAnalysis::Key;
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric PreservedAnalyses CallGraphPrinterPass::run(Module &M,
3070b57cec5SDimitry Andric                                             ModuleAnalysisManager &AM) {
3080b57cec5SDimitry Andric   AM.getResult<CallGraphAnalysis>(M).print(OS);
3090b57cec5SDimitry Andric   return PreservedAnalyses::all();
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
312bdd1243dSDimitry Andric PreservedAnalyses CallGraphSCCsPrinterPass::run(Module &M,
313bdd1243dSDimitry Andric                                                 ModuleAnalysisManager &AM) {
314bdd1243dSDimitry Andric   auto &CG = AM.getResult<CallGraphAnalysis>(M);
315bdd1243dSDimitry Andric   unsigned sccNum = 0;
316bdd1243dSDimitry Andric   OS << "SCCs for the program in PostOrder:";
317bdd1243dSDimitry Andric   for (scc_iterator<CallGraph *> SCCI = scc_begin(&CG); !SCCI.isAtEnd();
318bdd1243dSDimitry Andric        ++SCCI) {
319bdd1243dSDimitry Andric     const std::vector<CallGraphNode *> &nextSCC = *SCCI;
320bdd1243dSDimitry Andric     OS << "\nSCC #" << ++sccNum << ": ";
321bdd1243dSDimitry Andric     bool First = true;
322*0fca6ea1SDimitry Andric     for (CallGraphNode *CGN : nextSCC) {
323bdd1243dSDimitry Andric       if (First)
324bdd1243dSDimitry Andric         First = false;
325bdd1243dSDimitry Andric       else
326bdd1243dSDimitry Andric         OS << ", ";
327*0fca6ea1SDimitry Andric       OS << (CGN->getFunction() ? CGN->getFunction()->getName()
328bdd1243dSDimitry Andric                                 : "external node");
329bdd1243dSDimitry Andric     }
330bdd1243dSDimitry Andric 
331bdd1243dSDimitry Andric     if (nextSCC.size() == 1 && SCCI.hasCycle())
332bdd1243dSDimitry Andric       OS << " (Has self-loop).";
333bdd1243dSDimitry Andric   }
334bdd1243dSDimitry Andric   OS << "\n";
335bdd1243dSDimitry Andric   return PreservedAnalyses::all();
336bdd1243dSDimitry Andric }
337bdd1243dSDimitry Andric 
3380b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3390b57cec5SDimitry Andric // Out-of-line definitions of CallGraphAnalysis class members.
3400b57cec5SDimitry Andric //
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3430b57cec5SDimitry Andric // Implementations of the CallGraphWrapperPass class methods.
3440b57cec5SDimitry Andric //
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric CallGraphWrapperPass::CallGraphWrapperPass() : ModulePass(ID) {
3470b57cec5SDimitry Andric   initializeCallGraphWrapperPassPass(*PassRegistry::getPassRegistry());
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric CallGraphWrapperPass::~CallGraphWrapperPass() = default;
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric void CallGraphWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
3530b57cec5SDimitry Andric   AU.setPreservesAll();
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric bool CallGraphWrapperPass::runOnModule(Module &M) {
3570b57cec5SDimitry Andric   // All the real work is done in the constructor for the CallGraph.
3580b57cec5SDimitry Andric   G.reset(new CallGraph(M));
3590b57cec5SDimitry Andric   return false;
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric INITIALIZE_PASS(CallGraphWrapperPass, "basiccg", "CallGraph Construction",
3630b57cec5SDimitry Andric                 false, true)
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric char CallGraphWrapperPass::ID = 0;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric void CallGraphWrapperPass::releaseMemory() { G.reset(); }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric void CallGraphWrapperPass::print(raw_ostream &OS, const Module *) const {
3700b57cec5SDimitry Andric   if (!G) {
3710b57cec5SDimitry Andric     OS << "No call graph has been built!\n";
3720b57cec5SDimitry Andric     return;
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   // Just delegate.
3760b57cec5SDimitry Andric   G->print(OS);
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3800b57cec5SDimitry Andric LLVM_DUMP_METHOD
3810b57cec5SDimitry Andric void CallGraphWrapperPass::dump() const { print(dbgs(), nullptr); }
3820b57cec5SDimitry Andric #endif
383