1 //===- LazyCallGraph.cpp - Analysis of a Module's call graph --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Analysis/LazyCallGraph.h" 11 #include "llvm/ADT/SCCIterator.h" 12 #include "llvm/IR/Instructions.h" 13 #include "llvm/IR/PassManager.h" 14 #include "llvm/Support/CallSite.h" 15 #include "llvm/Support/raw_ostream.h" 16 #include "llvm/InstVisitor.h" 17 18 using namespace llvm; 19 20 static void findCallees( 21 SmallVectorImpl<Constant *> &Worklist, SmallPtrSetImpl<Constant *> &Visited, 22 SmallVectorImpl<PointerUnion<Function *, LazyCallGraph::Node *> > &Callees, 23 SmallPtrSetImpl<Function *> &CalleeSet) { 24 while (!Worklist.empty()) { 25 Constant *C = Worklist.pop_back_val(); 26 27 if (Function *F = dyn_cast<Function>(C)) { 28 // Note that we consider *any* function with a definition to be a viable 29 // edge. Even if the function's definition is subject to replacement by 30 // some other module (say, a weak definition) there may still be 31 // optimizations which essentially speculate based on the definition and 32 // a way to check that the specific definition is in fact the one being 33 // used. For example, this could be done by moving the weak definition to 34 // a strong (internal) definition and making the weak definition be an 35 // alias. Then a test of the address of the weak function against the new 36 // strong definition's address would be an effective way to determine the 37 // safety of optimizing a direct call edge. 38 if (!F->isDeclaration() && CalleeSet.insert(F)) 39 Callees.push_back(F); 40 continue; 41 } 42 43 for (User::value_op_iterator OI = C->value_op_begin(), 44 OE = C->value_op_end(); 45 OI != OE; ++OI) 46 if (Visited.insert(cast<Constant>(*OI))) 47 Worklist.push_back(cast<Constant>(*OI)); 48 } 49 } 50 51 LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F) : G(G), F(F) { 52 SmallVector<Constant *, 16> Worklist; 53 SmallPtrSet<Constant *, 16> Visited; 54 // Find all the potential callees in this function. First walk the 55 // instructions and add every operand which is a constant to the worklist. 56 for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) 57 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE; 58 ++II) 59 for (User::value_op_iterator OI = II->value_op_begin(), 60 OE = II->value_op_end(); 61 OI != OE; ++OI) 62 if (Constant *C = dyn_cast<Constant>(*OI)) 63 if (Visited.insert(C)) 64 Worklist.push_back(C); 65 66 // We've collected all the constant (and thus potentially function or 67 // function containing) operands to all of the instructions in the function. 68 // Process them (recursively) collecting every function found. 69 findCallees(Worklist, Visited, Callees, CalleeSet); 70 } 71 72 LazyCallGraph::Node::Node(LazyCallGraph &G, const Node &OtherN) 73 : G(G), F(OtherN.F), CalleeSet(OtherN.CalleeSet) { 74 // Loop over the other node's callees, adding the Function*s to our list 75 // directly, and recursing to add the Node*s. 76 Callees.reserve(OtherN.Callees.size()); 77 for (NodeVectorImplT::iterator OI = OtherN.Callees.begin(), 78 OE = OtherN.Callees.end(); 79 OI != OE; ++OI) 80 if (Function *Callee = OI->dyn_cast<Function *>()) 81 Callees.push_back(Callee); 82 else 83 Callees.push_back(G.copyInto(*OI->get<Node *>())); 84 } 85 86 #if LLVM_HAS_RVALUE_REFERENCES 87 LazyCallGraph::Node::Node(LazyCallGraph &G, Node &&OtherN) 88 : G(G), F(OtherN.F), Callees(std::move(OtherN.Callees)), 89 CalleeSet(std::move(OtherN.CalleeSet)) { 90 // Loop over our Callees. They've been moved from another node, but we need 91 // to move the Node*s to live under our bump ptr allocator. 92 for (NodeVectorImplT::iterator CI = Callees.begin(), CE = Callees.end(); 93 CI != CE; ++CI) 94 if (Node *ChildN = CI->dyn_cast<Node *>()) 95 *CI = G.moveInto(std::move(*ChildN)); 96 } 97 #endif 98 99 LazyCallGraph::LazyCallGraph(Module &M) : M(M) { 100 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) 101 if (!FI->isDeclaration() && !FI->hasLocalLinkage()) 102 if (EntryNodeSet.insert(&*FI)) 103 EntryNodes.push_back(&*FI); 104 105 // Now add entry nodes for functions reachable via initializers to globals. 106 SmallVector<Constant *, 16> Worklist; 107 SmallPtrSet<Constant *, 16> Visited; 108 for (Module::global_iterator GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI) 109 if (GI->hasInitializer()) 110 if (Visited.insert(GI->getInitializer())) 111 Worklist.push_back(GI->getInitializer()); 112 113 findCallees(Worklist, Visited, EntryNodes, EntryNodeSet); 114 } 115 116 LazyCallGraph::LazyCallGraph(const LazyCallGraph &G) 117 : M(G.M), EntryNodeSet(G.EntryNodeSet) { 118 EntryNodes.reserve(G.EntryNodes.size()); 119 for (NodeVectorImplT::const_iterator EI = G.EntryNodes.begin(), 120 EE = G.EntryNodes.end(); 121 EI != EE; ++EI) 122 if (Function *Callee = EI->dyn_cast<Function *>()) 123 EntryNodes.push_back(Callee); 124 else 125 EntryNodes.push_back(copyInto(*EI->get<Node *>())); 126 } 127 128 #if LLVM_HAS_RVALUE_REFERENCES 129 // FIXME: This would be crazy simpler if BumpPtrAllocator were movable without 130 // invalidating any of the allocated memory. We should make that be the case at 131 // some point and delete this. 132 LazyCallGraph::LazyCallGraph(LazyCallGraph &&G) 133 : M(G.M), EntryNodes(std::move(G.EntryNodes)), 134 EntryNodeSet(std::move(G.EntryNodeSet)) { 135 // Loop over our EntryNodes. They've been moved from another graph, so we 136 // need to move the Node*s to live under our bump ptr allocator. We can just 137 // do this in-place. 138 for (NodeVectorImplT::iterator EI = EntryNodes.begin(), 139 EE = EntryNodes.end(); 140 EI != EE; ++EI) 141 if (Node *EntryN = EI->dyn_cast<Node *>()) 142 *EI = moveInto(std::move(*EntryN)); 143 } 144 #endif 145 146 LazyCallGraph::Node *LazyCallGraph::insertInto(Function &F, Node *&MappedN) { 147 return new (MappedN = BPA.Allocate()) Node(*this, F); 148 } 149 150 LazyCallGraph::Node *LazyCallGraph::copyInto(const Node &OtherN) { 151 Node *&N = NodeMap[&OtherN.F]; 152 if (N) 153 return N; 154 155 return new (N = BPA.Allocate()) Node(*this, OtherN); 156 } 157 158 #if LLVM_HAS_RVALUE_REFERENCES 159 LazyCallGraph::Node *LazyCallGraph::moveInto(Node &&OtherN) { 160 Node *&N = NodeMap[&OtherN.F]; 161 if (N) 162 return N; 163 164 return new (N = BPA.Allocate()) Node(*this, std::move(OtherN)); 165 } 166 #endif 167 168 char LazyCallGraphAnalysis::PassID; 169 170 LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {} 171 172 static void printNodes(raw_ostream &OS, LazyCallGraph::Node &N, 173 SmallPtrSetImpl<LazyCallGraph::Node *> &Printed) { 174 // Recurse depth first through the nodes. 175 for (LazyCallGraph::iterator I = N.begin(), E = N.end(); I != E; ++I) 176 if (Printed.insert(*I)) 177 printNodes(OS, **I, Printed); 178 179 OS << " Call edges in function: " << N.getFunction().getName() << "\n"; 180 for (LazyCallGraph::iterator I = N.begin(), E = N.end(); I != E; ++I) 181 OS << " -> " << I->getFunction().getName() << "\n"; 182 183 OS << "\n"; 184 } 185 186 PreservedAnalyses LazyCallGraphPrinterPass::run(Module *M, ModuleAnalysisManager *AM) { 187 LazyCallGraph &G = AM->getResult<LazyCallGraphAnalysis>(M); 188 189 OS << "Printing the call graph for module: " << M->getModuleIdentifier() << "\n\n"; 190 191 SmallPtrSet<LazyCallGraph::Node *, 16> Printed; 192 for (LazyCallGraph::iterator I = G.begin(), E = G.end(); I != E; ++I) 193 if (Printed.insert(*I)) 194 printNodes(OS, **I, Printed); 195 196 return PreservedAnalyses::all(); 197 } 198