blob: 11e1166001a5908ba78d3be2bac8529a1592ee35 [file] [log] [blame]
Chandler Carruthbf71a342014-02-06 04:37:03 +00001//===- 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"
Chandler Carruth18eadd922014-04-18 10:50:32 +000011#include "llvm/ADT/STLExtras.h"
Chandler Carruth219b89b2014-03-04 11:01:28 +000012#include "llvm/IR/CallSite.h"
Chandler Carruth7da14f12014-03-06 03:23:41 +000013#include "llvm/IR/InstVisitor.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000014#include "llvm/IR/Instructions.h"
15#include "llvm/IR/PassManager.h"
Chandler Carruth99b756d2014-04-21 05:04:24 +000016#include "llvm/Support/Debug.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000017#include "llvm/Support/raw_ostream.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000018
19using namespace llvm;
20
Chandler Carruthf1221bd2014-04-22 02:48:03 +000021#define DEBUG_TYPE "lcg"
22
Chandler Carrutha4499e92016-02-02 03:57:13 +000023static void addEdge(SmallVectorImpl<LazyCallGraph::Edge> &Edges,
24 DenseMap<Function *, size_t> &EdgeIndexMap, Function &F,
25 LazyCallGraph::Edge::Kind EK) {
26 // Note that we consider *any* function with a definition to be a viable
27 // edge. Even if the function's definition is subject to replacement by
28 // some other module (say, a weak definition) there may still be
29 // optimizations which essentially speculate based on the definition and
30 // a way to check that the specific definition is in fact the one being
31 // used. For example, this could be done by moving the weak definition to
32 // a strong (internal) definition and making the weak definition be an
33 // alias. Then a test of the address of the weak function against the new
34 // strong definition's address would be an effective way to determine the
35 // safety of optimizing a direct call edge.
36 if (!F.isDeclaration() &&
37 EdgeIndexMap.insert(std::make_pair(&F, Edges.size())).second) {
38 DEBUG(dbgs() << " Added callable function: " << F.getName() << "\n");
39 Edges.emplace_back(LazyCallGraph::Edge(F, EK));
40 }
41}
42
43static void findReferences(
44 SmallVectorImpl<Constant *> &Worklist,
45 SmallPtrSetImpl<Constant *> &Visited,
46 SmallVectorImpl<LazyCallGraph::Edge> &Edges,
47 DenseMap<Function *, size_t> &EdgeIndexMap) {
Chandler Carruthbf71a342014-02-06 04:37:03 +000048 while (!Worklist.empty()) {
49 Constant *C = Worklist.pop_back_val();
50
51 if (Function *F = dyn_cast<Function>(C)) {
Chandler Carrutha4499e92016-02-02 03:57:13 +000052 addEdge(Edges, EdgeIndexMap, *F, LazyCallGraph::Edge::Ref);
Chandler Carruthbf71a342014-02-06 04:37:03 +000053 continue;
54 }
55
Chandler Carruth1583e992014-03-03 10:42:58 +000056 for (Value *Op : C->operand_values())
David Blaikie70573dc2014-11-19 07:49:26 +000057 if (Visited.insert(cast<Constant>(Op)).second)
Chandler Carruth1583e992014-03-03 10:42:58 +000058 Worklist.push_back(cast<Constant>(Op));
Chandler Carruthbf71a342014-02-06 04:37:03 +000059 }
60}
61
Chandler Carruth18eadd922014-04-18 10:50:32 +000062LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F)
63 : G(&G), F(F), DFSNumber(0), LowLink(0) {
Chandler Carruth99b756d2014-04-21 05:04:24 +000064 DEBUG(dbgs() << " Adding functions called by '" << F.getName()
65 << "' to the graph.\n");
66
Chandler Carruthbf71a342014-02-06 04:37:03 +000067 SmallVector<Constant *, 16> Worklist;
Chandler Carrutha4499e92016-02-02 03:57:13 +000068 SmallPtrSet<Function *, 4> Callees;
Chandler Carruthbf71a342014-02-06 04:37:03 +000069 SmallPtrSet<Constant *, 16> Visited;
Chandler Carrutha4499e92016-02-02 03:57:13 +000070
71 // Find all the potential call graph edges in this function. We track both
72 // actual call edges and indirect references to functions. The direct calls
73 // are trivially added, but to accumulate the latter we walk the instructions
74 // and add every operand which is a constant to the worklist to process
75 // afterward.
Chandler Carruthb9e2f8c2014-03-09 12:20:34 +000076 for (BasicBlock &BB : F)
Chandler Carrutha4499e92016-02-02 03:57:13 +000077 for (Instruction &I : BB) {
78 if (auto CS = CallSite(&I))
79 if (Function *Callee = CS.getCalledFunction())
80 if (Callees.insert(Callee).second) {
81 Visited.insert(Callee);
82 addEdge(Edges, EdgeIndexMap, *Callee, LazyCallGraph::Edge::Call);
83 }
84
Chandler Carruthb9e2f8c2014-03-09 12:20:34 +000085 for (Value *Op : I.operand_values())
Chandler Carruth1583e992014-03-03 10:42:58 +000086 if (Constant *C = dyn_cast<Constant>(Op))
David Blaikie70573dc2014-11-19 07:49:26 +000087 if (Visited.insert(C).second)
Chandler Carruthbf71a342014-02-06 04:37:03 +000088 Worklist.push_back(C);
Chandler Carrutha4499e92016-02-02 03:57:13 +000089 }
Chandler Carruthbf71a342014-02-06 04:37:03 +000090
91 // We've collected all the constant (and thus potentially function or
92 // function containing) operands to all of the instructions in the function.
93 // Process them (recursively) collecting every function found.
Chandler Carrutha4499e92016-02-02 03:57:13 +000094 findReferences(Worklist, Visited, Edges, EdgeIndexMap);
Chandler Carruthbf71a342014-02-06 04:37:03 +000095}
96
Chandler Carrutha4499e92016-02-02 03:57:13 +000097void LazyCallGraph::Node::insertEdgeInternal(Function &Child, Edge::Kind EK) {
98 if (Node *N = G->lookup(Child))
99 return insertEdgeInternal(*N, EK);
Chandler Carruth5217c942014-04-30 10:48:36 +0000100
Chandler Carrutha4499e92016-02-02 03:57:13 +0000101 EdgeIndexMap.insert(std::make_pair(&Child, Edges.size()));
102 Edges.emplace_back(Child, EK);
Chandler Carruth5217c942014-04-30 10:48:36 +0000103}
104
Chandler Carrutha4499e92016-02-02 03:57:13 +0000105void LazyCallGraph::Node::insertEdgeInternal(Node &ChildN, Edge::Kind EK) {
106 EdgeIndexMap.insert(std::make_pair(&ChildN.getFunction(), Edges.size()));
107 Edges.emplace_back(ChildN, EK);
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000108}
109
Chandler Carrutha4499e92016-02-02 03:57:13 +0000110void LazyCallGraph::Node::removeEdgeInternal(Function &Child) {
111 auto IndexMapI = EdgeIndexMap.find(&Child);
112 assert(IndexMapI != EdgeIndexMap.end() &&
113 "Child not in the edge set for this caller?");
Chandler Carruthaa839b22014-04-27 01:59:50 +0000114
Chandler Carrutha4499e92016-02-02 03:57:13 +0000115 Edges[IndexMapI->second] = Edge();
116 EdgeIndexMap.erase(IndexMapI);
Chandler Carruthaa839b22014-04-27 01:59:50 +0000117}
118
Chandler Carruth2174f442014-04-18 20:44:16 +0000119LazyCallGraph::LazyCallGraph(Module &M) : NextDFSNumber(0) {
Chandler Carruth99b756d2014-04-21 05:04:24 +0000120 DEBUG(dbgs() << "Building CG for module: " << M.getModuleIdentifier()
121 << "\n");
Chandler Carruthb9e2f8c2014-03-09 12:20:34 +0000122 for (Function &F : M)
123 if (!F.isDeclaration() && !F.hasLocalLinkage())
Chandler Carrutha4499e92016-02-02 03:57:13 +0000124 if (EntryIndexMap.insert(std::make_pair(&F, EntryEdges.size())).second) {
Chandler Carruth99b756d2014-04-21 05:04:24 +0000125 DEBUG(dbgs() << " Adding '" << F.getName()
126 << "' to entry set of the graph.\n");
Chandler Carrutha4499e92016-02-02 03:57:13 +0000127 EntryEdges.emplace_back(F, Edge::Ref);
Chandler Carruth99b756d2014-04-21 05:04:24 +0000128 }
Chandler Carruthbf71a342014-02-06 04:37:03 +0000129
130 // Now add entry nodes for functions reachable via initializers to globals.
131 SmallVector<Constant *, 16> Worklist;
132 SmallPtrSet<Constant *, 16> Visited;
Chandler Carruthb9e2f8c2014-03-09 12:20:34 +0000133 for (GlobalVariable &GV : M.globals())
134 if (GV.hasInitializer())
David Blaikie70573dc2014-11-19 07:49:26 +0000135 if (Visited.insert(GV.getInitializer()).second)
Chandler Carruthb9e2f8c2014-03-09 12:20:34 +0000136 Worklist.push_back(GV.getInitializer());
Chandler Carruthbf71a342014-02-06 04:37:03 +0000137
Chandler Carruth99b756d2014-04-21 05:04:24 +0000138 DEBUG(dbgs() << " Adding functions referenced by global initializers to the "
139 "entry set.\n");
Chandler Carrutha4499e92016-02-02 03:57:13 +0000140 findReferences(Worklist, Visited, EntryEdges, EntryIndexMap);
Chandler Carruth18eadd922014-04-18 10:50:32 +0000141
Chandler Carrutha4499e92016-02-02 03:57:13 +0000142 for (const Edge &E : EntryEdges)
143 SCCEntryNodes.push_back(&E.getFunction());
Chandler Carruthbf71a342014-02-06 04:37:03 +0000144}
145
Chandler Carruthbf71a342014-02-06 04:37:03 +0000146LazyCallGraph::LazyCallGraph(LazyCallGraph &&G)
Chandler Carruth2174f442014-04-18 20:44:16 +0000147 : BPA(std::move(G.BPA)), NodeMap(std::move(G.NodeMap)),
Chandler Carrutha4499e92016-02-02 03:57:13 +0000148 EntryEdges(std::move(G.EntryEdges)),
Chandler Carruth0b623ba2014-04-23 04:00:17 +0000149 EntryIndexMap(std::move(G.EntryIndexMap)), SCCBPA(std::move(G.SCCBPA)),
Chandler Carruth18eadd922014-04-18 10:50:32 +0000150 SCCMap(std::move(G.SCCMap)), LeafSCCs(std::move(G.LeafSCCs)),
151 DFSStack(std::move(G.DFSStack)),
Chandler Carruth2174f442014-04-18 20:44:16 +0000152 SCCEntryNodes(std::move(G.SCCEntryNodes)),
153 NextDFSNumber(G.NextDFSNumber) {
Chandler Carruthd8d865e2014-04-18 11:02:33 +0000154 updateGraphPtrs();
155}
156
157LazyCallGraph &LazyCallGraph::operator=(LazyCallGraph &&G) {
158 BPA = std::move(G.BPA);
Chandler Carruth2174f442014-04-18 20:44:16 +0000159 NodeMap = std::move(G.NodeMap);
Chandler Carrutha4499e92016-02-02 03:57:13 +0000160 EntryEdges = std::move(G.EntryEdges);
Chandler Carruth0b623ba2014-04-23 04:00:17 +0000161 EntryIndexMap = std::move(G.EntryIndexMap);
Chandler Carruthd8d865e2014-04-18 11:02:33 +0000162 SCCBPA = std::move(G.SCCBPA);
163 SCCMap = std::move(G.SCCMap);
164 LeafSCCs = std::move(G.LeafSCCs);
165 DFSStack = std::move(G.DFSStack);
166 SCCEntryNodes = std::move(G.SCCEntryNodes);
Chandler Carruth2174f442014-04-18 20:44:16 +0000167 NextDFSNumber = G.NextDFSNumber;
Chandler Carruthd8d865e2014-04-18 11:02:33 +0000168 updateGraphPtrs();
169 return *this;
170}
171
Chandler Carruthaa839b22014-04-27 01:59:50 +0000172void LazyCallGraph::SCC::insert(Node &N) {
Chandler Carruth8f92d6d2014-04-26 01:03:46 +0000173 N.DFSNumber = N.LowLink = -1;
174 Nodes.push_back(&N);
Chandler Carruthaa839b22014-04-27 01:59:50 +0000175 G->SCCMap[&N] = this;
Chandler Carruth8f92d6d2014-04-26 01:03:46 +0000176}
177
Chandler Carruth4b096742014-05-01 12:12:42 +0000178bool LazyCallGraph::SCC::isDescendantOf(const SCC &C) const {
179 // Walk up the parents of this SCC and verify that we eventually find C.
180 SmallVector<const SCC *, 4> AncestorWorklist;
181 AncestorWorklist.push_back(this);
182 do {
183 const SCC *AncestorC = AncestorWorklist.pop_back_val();
184 if (AncestorC->isChildOf(C))
185 return true;
186 for (const SCC *ParentC : AncestorC->ParentSCCs)
187 AncestorWorklist.push_back(ParentC);
188 } while (!AncestorWorklist.empty());
189
190 return false;
191}
192
Chandler Carrutha4499e92016-02-02 03:57:13 +0000193void LazyCallGraph::SCC::insertIntraSCCEdge(Node &ParentN, Node &ChildN,
194 Edge::Kind EK) {
Chandler Carruth5217c942014-04-30 10:48:36 +0000195 // First insert it into the caller.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000196 ParentN.insertEdgeInternal(ChildN, EK);
Chandler Carruth5217c942014-04-30 10:48:36 +0000197
Chandler Carrutha4499e92016-02-02 03:57:13 +0000198 assert(G->SCCMap.lookup(&ParentN) == this && "Parent must be in this SCC.");
199 assert(G->SCCMap.lookup(&ChildN) == this && "Child must be in this SCC.");
Chandler Carruth5217c942014-04-30 10:48:36 +0000200
201 // Nothing changes about this SCC or any other.
202}
203
Chandler Carrutha4499e92016-02-02 03:57:13 +0000204void LazyCallGraph::SCC::insertOutgoingEdge(Node &ParentN, Node &ChildN,
205 Edge::Kind EK) {
Chandler Carruth7cc4ed82014-05-01 12:18:20 +0000206 // First insert it into the caller.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000207 ParentN.insertEdgeInternal(ChildN, EK);
Chandler Carruth7cc4ed82014-05-01 12:18:20 +0000208
Chandler Carrutha4499e92016-02-02 03:57:13 +0000209 assert(G->SCCMap.lookup(&ParentN) == this && "Parent must be in this SCC.");
Chandler Carruth7cc4ed82014-05-01 12:18:20 +0000210
Chandler Carrutha4499e92016-02-02 03:57:13 +0000211 SCC &ChildC = *G->SCCMap.lookup(&ChildN);
212 assert(&ChildC != this && "Child must not be in this SCC.");
213 assert(ChildC.isDescendantOf(*this) &&
214 "Child must be a descendant of the Parent.");
Chandler Carruth7cc4ed82014-05-01 12:18:20 +0000215
Chandler Carruth91539112015-12-28 01:54:20 +0000216 // The only change required is to add this SCC to the parent set of the
217 // callee.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000218 ChildC.ParentSCCs.insert(this);
Chandler Carruth7cc4ed82014-05-01 12:18:20 +0000219}
220
Chandler Carruth312dddf2014-05-04 09:38:32 +0000221SmallVector<LazyCallGraph::SCC *, 1>
Chandler Carrutha4499e92016-02-02 03:57:13 +0000222LazyCallGraph::SCC::insertIncomingEdge(Node &ParentN, Node &ChildN,
223 Edge::Kind EK) {
Chandler Carruth312dddf2014-05-04 09:38:32 +0000224 // First insert it into the caller.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000225 ParentN.insertEdgeInternal(ChildN, EK);
Chandler Carruth312dddf2014-05-04 09:38:32 +0000226
Chandler Carrutha4499e92016-02-02 03:57:13 +0000227 assert(G->SCCMap.lookup(&ChildN) == this && "Child must be in this SCC.");
Chandler Carruth312dddf2014-05-04 09:38:32 +0000228
Chandler Carrutha4499e92016-02-02 03:57:13 +0000229 SCC &ParentC = *G->SCCMap.lookup(&ParentN);
230 assert(&ParentC != this && "Parent must not be in this SCC.");
231 assert(ParentC.isDescendantOf(*this) &&
232 "Parent must be a descendant of the Child.");
Chandler Carruth312dddf2014-05-04 09:38:32 +0000233
234 // The algorithm we use for merging SCCs based on the cycle introduced here
235 // is to walk the SCC inverted DAG formed by the parent SCC sets. The inverse
236 // graph has the same cycle properties as the actual DAG of the SCCs, and
237 // when forming SCCs lazily by a DFS, the bottom of the graph won't exist in
238 // many cases which should prune the search space.
239 //
240 // FIXME: We can get this pruning behavior even after the incremental SCC
241 // formation by leaving behind (conservative) DFS numberings in the nodes,
242 // and pruning the search with them. These would need to be cleverly updated
243 // during the removal of intra-SCC edges, but could be preserved
244 // conservatively.
245
246 // The set of SCCs that are connected to the caller, and thus will
247 // participate in the merged connected component.
248 SmallPtrSet<SCC *, 8> ConnectedSCCs;
249 ConnectedSCCs.insert(this);
Chandler Carrutha4499e92016-02-02 03:57:13 +0000250 ConnectedSCCs.insert(&ParentC);
Chandler Carruth312dddf2014-05-04 09:38:32 +0000251
252 // We build up a DFS stack of the parents chains.
253 SmallVector<std::pair<SCC *, SCC::parent_iterator>, 8> DFSSCCs;
254 SmallPtrSet<SCC *, 8> VisitedSCCs;
255 int ConnectedDepth = -1;
256 SCC *C = this;
257 parent_iterator I = parent_begin(), E = parent_end();
258 for (;;) {
259 while (I != E) {
260 SCC &ParentSCC = *I++;
261
262 // If we have already processed this parent SCC, skip it, and remember
263 // whether it was connected so we don't have to check the rest of the
264 // stack. This also handles when we reach a child of the 'this' SCC (the
265 // callee) which terminates the search.
266 if (ConnectedSCCs.count(&ParentSCC)) {
267 ConnectedDepth = std::max<int>(ConnectedDepth, DFSSCCs.size());
268 continue;
269 }
270 if (VisitedSCCs.count(&ParentSCC))
271 continue;
272
273 // We fully explore the depth-first space, adding nodes to the connected
274 // set only as we pop them off, so "recurse" by rotating to the parent.
275 DFSSCCs.push_back(std::make_pair(C, I));
276 C = &ParentSCC;
277 I = ParentSCC.parent_begin();
278 E = ParentSCC.parent_end();
279 }
280
281 // If we've found a connection anywhere below this point on the stack (and
282 // thus up the parent graph from the caller), the current node needs to be
283 // added to the connected set now that we've processed all of its parents.
284 if ((int)DFSSCCs.size() == ConnectedDepth) {
285 --ConnectedDepth; // We're finished with this connection.
286 ConnectedSCCs.insert(C);
287 } else {
288 // Otherwise remember that its parents don't ever connect.
289 assert(ConnectedDepth < (int)DFSSCCs.size() &&
290 "Cannot have a connected depth greater than the DFS depth!");
291 VisitedSCCs.insert(C);
292 }
293
294 if (DFSSCCs.empty())
295 break; // We've walked all the parents of the caller transitively.
296
297 // Pop off the prior node and position to unwind the depth first recursion.
298 std::tie(C, I) = DFSSCCs.pop_back_val();
299 E = C->parent_end();
300 }
301
302 // Now that we have identified all of the SCCs which need to be merged into
303 // a connected set with the inserted edge, merge all of them into this SCC.
304 // FIXME: This operation currently creates ordering stability problems
305 // because we don't use stably ordered containers for the parent SCCs or the
306 // connected SCCs.
307 unsigned NewNodeBeginIdx = Nodes.size();
308 for (SCC *C : ConnectedSCCs) {
309 if (C == this)
310 continue;
311 for (SCC *ParentC : C->ParentSCCs)
312 if (!ConnectedSCCs.count(ParentC))
313 ParentSCCs.insert(ParentC);
314 C->ParentSCCs.clear();
315
316 for (Node *N : *C) {
Chandler Carrutha4499e92016-02-02 03:57:13 +0000317 for (Edge &E : *N) {
318 assert(E.getNode() && "Cannot have a null node within a visited SCC!");
319 SCC &ChildC = *G->SCCMap.lookup(E.getNode());
Chandler Carruth312dddf2014-05-04 09:38:32 +0000320 if (&ChildC != C)
321 ChildC.ParentSCCs.erase(C);
322 }
323 G->SCCMap[N] = this;
324 Nodes.push_back(N);
325 }
326 C->Nodes.clear();
327 }
328 for (auto I = Nodes.begin() + NewNodeBeginIdx, E = Nodes.end(); I != E; ++I)
Chandler Carrutha4499e92016-02-02 03:57:13 +0000329 for (Edge &E : **I) {
330 assert(E.getNode() && "Cannot have a null node within a visited SCC!");
331 SCC &ChildC = *G->SCCMap.lookup(E.getNode());
Chandler Carruth312dddf2014-05-04 09:38:32 +0000332 if (&ChildC != this)
333 ChildC.ParentSCCs.insert(this);
334 }
335
336 // We return the list of SCCs which were merged so that callers can
337 // invalidate any data they have associated with those SCCs. Note that these
338 // SCCs are no longer in an interesting state (they are totally empty) but
339 // the pointers will remain stable for the life of the graph itself.
340 return SmallVector<SCC *, 1>(ConnectedSCCs.begin(), ConnectedSCCs.end());
341}
342
Chandler Carrutha4499e92016-02-02 03:57:13 +0000343void LazyCallGraph::SCC::removeInterSCCEdge(Node &ParentN, Node &ChildN) {
Chandler Carruthaa839b22014-04-27 01:59:50 +0000344 // First remove it from the node.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000345 ParentN.removeEdgeInternal(ChildN.getFunction());
Chandler Carruthaa839b22014-04-27 01:59:50 +0000346
Chandler Carrutha4499e92016-02-02 03:57:13 +0000347 assert(G->SCCMap.lookup(&ParentN) == this &&
Chandler Carruthaa839b22014-04-27 01:59:50 +0000348 "The caller must be a member of this SCC.");
349
Chandler Carrutha4499e92016-02-02 03:57:13 +0000350 SCC &ChildC = *G->SCCMap.lookup(&ChildN);
351 assert(&ChildC != this &&
Chandler Carruthaa839b22014-04-27 01:59:50 +0000352 "This API only supports the rmoval of inter-SCC edges.");
353
354 assert(std::find(G->LeafSCCs.begin(), G->LeafSCCs.end(), this) ==
355 G->LeafSCCs.end() &&
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000356 "Cannot have a leaf SCC caller with a different SCC callee.");
357
Chandler Carrutha4499e92016-02-02 03:57:13 +0000358 bool HasOtherEdgeToChildC = false;
359 bool HasOtherChildC = false;
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000360 for (Node *N : *this) {
Chandler Carrutha4499e92016-02-02 03:57:13 +0000361 for (Edge &E : *N) {
362 assert(E.getNode() && "Cannot have a missing node in a visited SCC!");
363 SCC &OtherChildC = *G->SCCMap.lookup(E.getNode());
364 if (&OtherChildC == &ChildC) {
365 HasOtherEdgeToChildC = true;
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000366 break;
367 }
Chandler Carrutha4499e92016-02-02 03:57:13 +0000368 if (&OtherChildC != this)
369 HasOtherChildC = true;
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000370 }
Chandler Carrutha4499e92016-02-02 03:57:13 +0000371 if (HasOtherEdgeToChildC)
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000372 break;
373 }
374 // Because the SCCs form a DAG, deleting such an edge cannot change the set
375 // of SCCs in the graph. However, it may cut an edge of the SCC DAG, making
Chandler Carrutha4499e92016-02-02 03:57:13 +0000376 // the parent SCC no longer connected to the child SCC. If so, we need to
377 // update the child SCC's map of its parents.
378 if (!HasOtherEdgeToChildC) {
379 bool Removed = ChildC.ParentSCCs.erase(this);
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000380 (void)Removed;
381 assert(Removed &&
Chandler Carrutha4499e92016-02-02 03:57:13 +0000382 "Did not find the parent SCC in the child SCC's parent list!");
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000383
384 // It may orphan an SCC if it is the last edge reaching it, but that does
385 // not violate any invariants of the graph.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000386 if (ChildC.ParentSCCs.empty())
387 DEBUG(dbgs() << "LCG: Update removing " << ParentN.getFunction().getName()
388 << " -> " << ChildN.getFunction().getName()
Chandler Carruthaa839b22014-04-27 01:59:50 +0000389 << " edge orphaned the callee's SCC!\n");
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000390 }
391
Chandler Carrutha4499e92016-02-02 03:57:13 +0000392 // It may make the Parent SCC a leaf SCC.
393 if (!HasOtherChildC)
Chandler Carruthaa839b22014-04-27 01:59:50 +0000394 G->LeafSCCs.push_back(this);
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000395}
396
Chandler Carruthaca48d02014-04-26 09:06:53 +0000397void LazyCallGraph::SCC::internalDFS(
Chandler Carrutha4499e92016-02-02 03:57:13 +0000398 SmallVectorImpl<std::pair<Node *, Node::edge_iterator>> &DFSStack,
Chandler Carruthaca48d02014-04-26 09:06:53 +0000399 SmallVectorImpl<Node *> &PendingSCCStack, Node *N,
400 SmallVectorImpl<SCC *> &ResultSCCs) {
Chandler Carrutha4499e92016-02-02 03:57:13 +0000401 auto I = N->begin();
Chandler Carruthaca48d02014-04-26 09:06:53 +0000402 N->LowLink = N->DFSNumber = 1;
403 int NextDFSNumber = 2;
404 for (;;) {
405 assert(N->DFSNumber != 0 && "We should always assign a DFS number "
406 "before processing a node.");
407
408 // We simulate recursion by popping out of the nested loop and continuing.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000409 auto E = N->end();
Chandler Carruthaca48d02014-04-26 09:06:53 +0000410 while (I != E) {
Chandler Carrutha4499e92016-02-02 03:57:13 +0000411 Node &ChildN = I->getNode(*G);
Chandler Carruthaa839b22014-04-27 01:59:50 +0000412 if (SCC *ChildSCC = G->SCCMap.lookup(&ChildN)) {
Chandler Carruthaca48d02014-04-26 09:06:53 +0000413 // Check if we have reached a node in the new (known connected) set of
414 // this SCC. If so, the entire stack is necessarily in that set and we
415 // can re-start.
416 if (ChildSCC == this) {
Chandler Carruthaa839b22014-04-27 01:59:50 +0000417 insert(*N);
Chandler Carruthaca48d02014-04-26 09:06:53 +0000418 while (!PendingSCCStack.empty())
Chandler Carruthaa839b22014-04-27 01:59:50 +0000419 insert(*PendingSCCStack.pop_back_val());
Chandler Carruthaca48d02014-04-26 09:06:53 +0000420 while (!DFSStack.empty())
Chandler Carruthaa839b22014-04-27 01:59:50 +0000421 insert(*DFSStack.pop_back_val().first);
Chandler Carruthaca48d02014-04-26 09:06:53 +0000422 return;
423 }
424
425 // If this child isn't currently in this SCC, no need to process it.
426 // However, we do need to remove this SCC from its SCC's parent set.
427 ChildSCC->ParentSCCs.erase(this);
428 ++I;
429 continue;
430 }
431
432 if (ChildN.DFSNumber == 0) {
433 // Mark that we should start at this child when next this node is the
434 // top of the stack. We don't start at the next child to ensure this
435 // child's lowlink is reflected.
436 DFSStack.push_back(std::make_pair(N, I));
437
438 // Continue, resetting to the child node.
439 ChildN.LowLink = ChildN.DFSNumber = NextDFSNumber++;
440 N = &ChildN;
441 I = ChildN.begin();
442 E = ChildN.end();
443 continue;
444 }
445
Alp Tokerbeaca192014-05-15 01:52:21 +0000446 // Track the lowest link of the children, if any are still in the stack.
Chandler Carruthaca48d02014-04-26 09:06:53 +0000447 // Any child not on the stack will have a LowLink of -1.
448 assert(ChildN.LowLink != 0 &&
449 "Low-link must not be zero with a non-zero DFS number.");
450 if (ChildN.LowLink >= 0 && ChildN.LowLink < N->LowLink)
451 N->LowLink = ChildN.LowLink;
452 ++I;
453 }
454
455 if (N->LowLink == N->DFSNumber) {
Chandler Carruthaa839b22014-04-27 01:59:50 +0000456 ResultSCCs.push_back(G->formSCC(N, PendingSCCStack));
Chandler Carruthaca48d02014-04-26 09:06:53 +0000457 if (DFSStack.empty())
458 return;
459 } else {
460 // At this point we know that N cannot ever be an SCC root. Its low-link
461 // is not its dfs-number, and we've processed all of its children. It is
462 // just sitting here waiting until some node further down the stack gets
463 // low-link == dfs-number and pops it off as well. Move it to the pending
464 // stack which is pulled into the next SCC to be formed.
465 PendingSCCStack.push_back(N);
466
467 assert(!DFSStack.empty() && "We shouldn't have an empty stack!");
468 }
469
470 N = DFSStack.back().first;
471 I = DFSStack.back().second;
472 DFSStack.pop_back();
473 }
474}
475
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000476SmallVector<LazyCallGraph::SCC *, 1>
Chandler Carrutha4499e92016-02-02 03:57:13 +0000477LazyCallGraph::SCC::removeIntraSCCEdge(Node &ParentN, Node &ChildN) {
Chandler Carruthaa839b22014-04-27 01:59:50 +0000478 // First remove it from the node.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000479 ParentN.removeEdgeInternal(ChildN.getFunction());
Chandler Carruthaa839b22014-04-27 01:59:50 +0000480
Chandler Carruth3f5f5fe2014-04-28 10:49:06 +0000481 // We return a list of the resulting *new* SCCs in postorder.
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000482 SmallVector<SCC *, 1> ResultSCCs;
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000483
Chandler Carrutha7205b62014-04-26 03:36:37 +0000484 // Direct recursion doesn't impact the SCC graph at all.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000485 if (&ParentN == &ChildN)
Chandler Carrutha7205b62014-04-26 03:36:37 +0000486 return ResultSCCs;
487
Chandler Carruth770060d2014-04-25 09:08:05 +0000488 // The worklist is every node in the original SCC.
489 SmallVector<Node *, 1> Worklist;
490 Worklist.swap(Nodes);
491 for (Node *N : Worklist) {
Chandler Carruth2e6ef0e2014-04-25 09:08:10 +0000492 // The nodes formerly in this SCC are no longer in any SCC.
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000493 N->DFSNumber = 0;
494 N->LowLink = 0;
Chandler Carruthaa839b22014-04-27 01:59:50 +0000495 G->SCCMap.erase(N);
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000496 }
Chandler Carrutha7205b62014-04-26 03:36:37 +0000497 assert(Worklist.size() > 1 && "We have to have at least two nodes to have an "
498 "edge between them that is within the SCC.");
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000499
Chandler Carrutha4499e92016-02-02 03:57:13 +0000500 // The child can already reach every node in this SCC (by definition). It is
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000501 // the only node we know will stay inside this SCC. Everything which
Chandler Carrutha4499e92016-02-02 03:57:13 +0000502 // transitively reaches Child will also remain in the SCC. To model this we
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000503 // incrementally add any chain of nodes which reaches something in the new
504 // node set to the new node set. This short circuits one side of the Tarjan's
505 // walk.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000506 insert(ChildN);
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000507
Chandler Carruthaca48d02014-04-26 09:06:53 +0000508 // We're going to do a full mini-Tarjan's walk using a local stack here.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000509 SmallVector<std::pair<Node *, Node::edge_iterator>, 4> DFSStack;
Chandler Carruthaca48d02014-04-26 09:06:53 +0000510 SmallVector<Node *, 4> PendingSCCStack;
511 do {
512 Node *N = Worklist.pop_back_val();
513 if (N->DFSNumber == 0)
Chandler Carruthaa839b22014-04-27 01:59:50 +0000514 internalDFS(DFSStack, PendingSCCStack, N, ResultSCCs);
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000515
Chandler Carruthaca48d02014-04-26 09:06:53 +0000516 assert(DFSStack.empty() && "Didn't flush the entire DFS stack!");
517 assert(PendingSCCStack.empty() && "Didn't flush all pending SCC nodes!");
518 } while (!Worklist.empty());
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000519
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000520 // Now we need to reconnect the current SCC to the graph.
521 bool IsLeafSCC = true;
Chandler Carruth9ba77622014-04-25 09:52:44 +0000522 for (Node *N : Nodes) {
Chandler Carrutha4499e92016-02-02 03:57:13 +0000523 for (Edge &E : *N) {
524 assert(E.getNode() && "Cannot have a missing node in a visited SCC!");
525 SCC &ChildSCC = *G->SCCMap.lookup(E.getNode());
Chandler Carruth9ba77622014-04-25 09:52:44 +0000526 if (&ChildSCC == this)
527 continue;
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000528 ChildSCC.ParentSCCs.insert(this);
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000529 IsLeafSCC = false;
530 }
531 }
532#ifndef NDEBUG
Chandler Carruth3f5f5fe2014-04-28 10:49:06 +0000533 if (!ResultSCCs.empty())
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000534 assert(!IsLeafSCC && "This SCC cannot be a leaf as we have split out new "
535 "SCCs by removing this edge.");
Chandler Carruthaa839b22014-04-27 01:59:50 +0000536 if (!std::any_of(G->LeafSCCs.begin(), G->LeafSCCs.end(),
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000537 [&](SCC *C) { return C == this; }))
538 assert(!IsLeafSCC && "This SCC cannot be a leaf as it already had child "
539 "SCCs before we removed this edge.");
540#endif
541 // If this SCC stopped being a leaf through this edge removal, remove it from
542 // the leaf SCC list.
Chandler Carruth3f5f5fe2014-04-28 10:49:06 +0000543 if (!IsLeafSCC && !ResultSCCs.empty())
Chandler Carruthaa839b22014-04-27 01:59:50 +0000544 G->LeafSCCs.erase(std::remove(G->LeafSCCs.begin(), G->LeafSCCs.end(), this),
Chandler Carruth91539112015-12-28 01:54:20 +0000545 G->LeafSCCs.end());
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000546
547 // Return the new list of SCCs.
548 return ResultSCCs;
549}
550
Chandler Carrutha4499e92016-02-02 03:57:13 +0000551void LazyCallGraph::insertEdge(Node &ParentN, Function &Child, Edge::Kind EK) {
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000552 assert(SCCMap.empty() && DFSStack.empty() &&
553 "This method cannot be called after SCCs have been formed!");
554
Chandler Carrutha4499e92016-02-02 03:57:13 +0000555 return ParentN.insertEdgeInternal(Child, EK);
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000556}
557
Chandler Carrutha4499e92016-02-02 03:57:13 +0000558void LazyCallGraph::removeEdge(Node &ParentN, Function &Child) {
Chandler Carruthaa839b22014-04-27 01:59:50 +0000559 assert(SCCMap.empty() && DFSStack.empty() &&
560 "This method cannot be called after SCCs have been formed!");
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000561
Chandler Carrutha4499e92016-02-02 03:57:13 +0000562 return ParentN.removeEdgeInternal(Child);
Chandler Carruth9302fbf2014-04-23 11:03:03 +0000563}
564
Chandler Carruth2a898e02014-04-23 23:20:36 +0000565LazyCallGraph::Node &LazyCallGraph::insertInto(Function &F, Node *&MappedN) {
566 return *new (MappedN = BPA.Allocate()) Node(*this, F);
Chandler Carruthd8d865e2014-04-18 11:02:33 +0000567}
568
569void LazyCallGraph::updateGraphPtrs() {
Chandler Carruthb60cb312014-04-17 07:25:59 +0000570 // Process all nodes updating the graph pointers.
Chandler Carruthaa839b22014-04-27 01:59:50 +0000571 {
572 SmallVector<Node *, 16> Worklist;
Chandler Carrutha4499e92016-02-02 03:57:13 +0000573 for (Edge &E : EntryEdges)
574 if (Node *EntryN = E.getNode())
Chandler Carruthaa839b22014-04-27 01:59:50 +0000575 Worklist.push_back(EntryN);
Chandler Carruthb60cb312014-04-17 07:25:59 +0000576
Chandler Carruthaa839b22014-04-27 01:59:50 +0000577 while (!Worklist.empty()) {
578 Node *N = Worklist.pop_back_val();
579 N->G = this;
Chandler Carrutha4499e92016-02-02 03:57:13 +0000580 for (Edge &E : N->Edges)
581 if (Node *ChildN = E.getNode())
582 Worklist.push_back(ChildN);
Chandler Carruthaa839b22014-04-27 01:59:50 +0000583 }
584 }
585
586 // Process all SCCs updating the graph pointers.
587 {
588 SmallVector<SCC *, 16> Worklist(LeafSCCs.begin(), LeafSCCs.end());
589
590 while (!Worklist.empty()) {
591 SCC *C = Worklist.pop_back_val();
592 C->G = this;
593 Worklist.insert(Worklist.end(), C->ParentSCCs.begin(),
594 C->ParentSCCs.end());
595 }
Chandler Carruthb60cb312014-04-17 07:25:59 +0000596 }
Chandler Carruthbf71a342014-02-06 04:37:03 +0000597}
Chandler Carruthbf71a342014-02-06 04:37:03 +0000598
Chandler Carruth24553932014-04-24 11:05:20 +0000599LazyCallGraph::SCC *LazyCallGraph::formSCC(Node *RootN,
600 SmallVectorImpl<Node *> &NodeStack) {
Chandler Carruth3f9869a2014-04-23 06:09:03 +0000601 // The tail of the stack is the new SCC. Allocate the SCC and pop the stack
602 // into it.
Chandler Carruthaa839b22014-04-27 01:59:50 +0000603 SCC *NewSCC = new (SCCBPA.Allocate()) SCC(*this);
Chandler Carruth3f9869a2014-04-23 06:09:03 +0000604
Chandler Carruth24553932014-04-24 11:05:20 +0000605 while (!NodeStack.empty() && NodeStack.back()->DFSNumber > RootN->DFSNumber) {
Chandler Carruth8f92d6d2014-04-26 01:03:46 +0000606 assert(NodeStack.back()->LowLink >= RootN->LowLink &&
Chandler Carruthcace6622014-04-23 10:31:17 +0000607 "We cannot have a low link in an SCC lower than its root on the "
608 "stack!");
Chandler Carruthaa839b22014-04-27 01:59:50 +0000609 NewSCC->insert(*NodeStack.pop_back_val());
Chandler Carruthcace6622014-04-23 10:31:17 +0000610 }
Chandler Carruthaa839b22014-04-27 01:59:50 +0000611 NewSCC->insert(*RootN);
Chandler Carruth3f9869a2014-04-23 06:09:03 +0000612
613 // A final pass over all edges in the SCC (this remains linear as we only
614 // do this once when we build the SCC) to connect it to the parent sets of
615 // its children.
616 bool IsLeafSCC = true;
617 for (Node *SCCN : NewSCC->Nodes)
Chandler Carrutha4499e92016-02-02 03:57:13 +0000618 for (Edge &E : *SCCN) {
619 assert(E.getNode() && "Cannot have a missing node in a visited SCC!");
620 SCC &ChildSCC = *SCCMap.lookup(E.getNode());
Chandler Carruth034d0d62014-05-01 12:16:31 +0000621 if (&ChildSCC == NewSCC)
622 continue;
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000623 ChildSCC.ParentSCCs.insert(NewSCC);
Chandler Carruth3f9869a2014-04-23 06:09:03 +0000624 IsLeafSCC = false;
625 }
626
627 // For the SCCs where we fine no child SCCs, add them to the leaf list.
628 if (IsLeafSCC)
629 LeafSCCs.push_back(NewSCC);
630
631 return NewSCC;
632}
633
Chandler Carruth18eadd922014-04-18 10:50:32 +0000634LazyCallGraph::SCC *LazyCallGraph::getNextSCCInPostOrder() {
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000635 Node *N;
Chandler Carrutha4499e92016-02-02 03:57:13 +0000636 Node::edge_iterator I;
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000637 if (!DFSStack.empty()) {
638 N = DFSStack.back().first;
639 I = DFSStack.back().second;
640 DFSStack.pop_back();
641 } else {
Chandler Carruth18eadd922014-04-18 10:50:32 +0000642 // If we've handled all candidate entry nodes to the SCC forest, we're done.
Chandler Carruth90821c22014-04-26 09:45:55 +0000643 do {
644 if (SCCEntryNodes.empty())
645 return nullptr;
Chandler Carruth18eadd922014-04-18 10:50:32 +0000646
Chandler Carruth90821c22014-04-26 09:45:55 +0000647 N = &get(*SCCEntryNodes.pop_back_val());
648 } while (N->DFSNumber != 0);
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000649 I = N->begin();
650 N->LowLink = N->DFSNumber = 1;
Chandler Carruth09751bf2014-04-24 09:59:59 +0000651 NextDFSNumber = 2;
Chandler Carruth18eadd922014-04-18 10:50:32 +0000652 }
653
Chandler Carruth91dcf0f2014-04-24 21:19:30 +0000654 for (;;) {
Chandler Carruth24553932014-04-24 11:05:20 +0000655 assert(N->DFSNumber != 0 && "We should always assign a DFS number "
656 "before placing a node onto the stack.");
657
Chandler Carrutha4499e92016-02-02 03:57:13 +0000658 auto E = N->end();
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000659 while (I != E) {
Chandler Carrutha4499e92016-02-02 03:57:13 +0000660 Node &ChildN = I->getNode(*this);
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000661 if (ChildN.DFSNumber == 0) {
Chandler Carruthcace6622014-04-23 10:31:17 +0000662 // Mark that we should start at this child when next this node is the
663 // top of the stack. We don't start at the next child to ensure this
664 // child's lowlink is reflected.
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000665 DFSStack.push_back(std::make_pair(N, N->begin()));
Chandler Carruth18eadd922014-04-18 10:50:32 +0000666
Chandler Carruthcace6622014-04-23 10:31:17 +0000667 // Recurse onto this node via a tail call.
Chandler Carruth09751bf2014-04-24 09:59:59 +0000668 assert(!SCCMap.count(&ChildN) &&
669 "Found a node with 0 DFS number but already in an SCC!");
670 ChildN.LowLink = ChildN.DFSNumber = NextDFSNumber++;
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000671 N = &ChildN;
672 I = ChildN.begin();
673 E = ChildN.end();
674 continue;
Chandler Carruthcace6622014-04-23 10:31:17 +0000675 }
676
Alp Tokerbeaca192014-05-15 01:52:21 +0000677 // Track the lowest link of the children, if any are still in the stack.
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000678 assert(ChildN.LowLink != 0 &&
Chandler Carruthb4a04da2014-04-23 22:28:13 +0000679 "Low-link must not be zero with a non-zero DFS number.");
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000680 if (ChildN.LowLink >= 0 && ChildN.LowLink < N->LowLink)
681 N->LowLink = ChildN.LowLink;
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000682 ++I;
Chandler Carruth18eadd922014-04-18 10:50:32 +0000683 }
684
Chandler Carruthcace6622014-04-23 10:31:17 +0000685 if (N->LowLink == N->DFSNumber)
686 // Form the new SCC out of the top of the DFS stack.
Chandler Carruth24553932014-04-24 11:05:20 +0000687 return formSCC(N, PendingSCCStack);
Chandler Carruth18eadd922014-04-18 10:50:32 +0000688
Chandler Carruth24553932014-04-24 11:05:20 +0000689 // At this point we know that N cannot ever be an SCC root. Its low-link
690 // is not its dfs-number, and we've processed all of its children. It is
691 // just sitting here waiting until some node further down the stack gets
692 // low-link == dfs-number and pops it off as well. Move it to the pending
693 // stack which is pulled into the next SCC to be formed.
694 PendingSCCStack.push_back(N);
Chandler Carruth5e2d70b2014-04-26 09:28:00 +0000695
696 assert(!DFSStack.empty() && "We never found a viable root!");
697 N = DFSStack.back().first;
698 I = DFSStack.back().second;
699 DFSStack.pop_back();
Chandler Carruth91dcf0f2014-04-24 21:19:30 +0000700 }
Chandler Carruth18eadd922014-04-18 10:50:32 +0000701}
702
Chandler Carruthbf71a342014-02-06 04:37:03 +0000703char LazyCallGraphAnalysis::PassID;
704
705LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {}
706
Chandler Carruth11f50322015-01-14 00:27:45 +0000707static void printNodes(raw_ostream &OS, LazyCallGraph::Node &N,
708 SmallPtrSetImpl<LazyCallGraph::Node *> &Printed) {
Chandler Carrutha4499e92016-02-02 03:57:13 +0000709 LazyCallGraph &G = N.getGraph();
710
Chandler Carruth11f50322015-01-14 00:27:45 +0000711 // Recurse depth first through the nodes.
Chandler Carrutha4499e92016-02-02 03:57:13 +0000712 for (LazyCallGraph::Edge &E : N) {
713 LazyCallGraph::Node &ChildN = E.getNode(G);
Chandler Carruth11f50322015-01-14 00:27:45 +0000714 if (Printed.insert(&ChildN).second)
715 printNodes(OS, ChildN, Printed);
Chandler Carrutha4499e92016-02-02 03:57:13 +0000716 }
Chandler Carruth11f50322015-01-14 00:27:45 +0000717
Chandler Carrutha4499e92016-02-02 03:57:13 +0000718 OS << " Edges in function: " << N.getFunction().getName() << "\n";
719 for (const LazyCallGraph::Edge &E : N)
720 OS << " " << (E.isCall() ? "call" : "ref ") << " -> "
721 << E.getFunction().getName() << "\n";
Chandler Carruth11f50322015-01-14 00:27:45 +0000722
723 OS << "\n";
724}
725
726static void printSCC(raw_ostream &OS, LazyCallGraph::SCC &SCC) {
727 ptrdiff_t SCCSize = std::distance(SCC.begin(), SCC.end());
728 OS << " SCC with " << SCCSize << " functions:\n";
729
730 for (LazyCallGraph::Node *N : SCC)
731 OS << " " << N->getFunction().getName() << "\n";
732
733 OS << "\n";
734}
735
Chandler Carruthd174ce42015-01-05 02:47:05 +0000736PreservedAnalyses LazyCallGraphPrinterPass::run(Module &M,
Chandler Carruthe9b50612014-03-10 02:14:14 +0000737 ModuleAnalysisManager *AM) {
Chandler Carruth11f50322015-01-14 00:27:45 +0000738 LazyCallGraph &G = AM->getResult<LazyCallGraphAnalysis>(M);
739
740 OS << "Printing the call graph for module: " << M.getModuleIdentifier()
741 << "\n\n";
742
743 SmallPtrSet<LazyCallGraph::Node *, 16> Printed;
Chandler Carrutha4499e92016-02-02 03:57:13 +0000744 for (LazyCallGraph::Edge &E : G) {
745 LazyCallGraph::Node &N = E.getNode(G);
Chandler Carruth11f50322015-01-14 00:27:45 +0000746 if (Printed.insert(&N).second)
747 printNodes(OS, N, Printed);
Chandler Carrutha4499e92016-02-02 03:57:13 +0000748 }
Chandler Carruth11f50322015-01-14 00:27:45 +0000749
750 for (LazyCallGraph::SCC &SCC : G.postorder_sccs())
751 printSCC(OS, SCC);
Chandler Carruth18eadd922014-04-18 10:50:32 +0000752
Chandler Carruthbf71a342014-02-06 04:37:03 +0000753 return PreservedAnalyses::all();
Chandler Carruthbf71a342014-02-06 04:37:03 +0000754}