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/ScopeExit.h" 12 #include "llvm/ADT/Sequence.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/IR/CallSite.h" 15 #include "llvm/IR/InstVisitor.h" 16 #include "llvm/IR/Instructions.h" 17 #include "llvm/IR/PassManager.h" 18 #include "llvm/Support/Debug.h" 19 #include "llvm/Support/GraphWriter.h" 20 21 using namespace llvm; 22 23 #define DEBUG_TYPE "lcg" 24 25 static void addEdge(SmallVectorImpl<LazyCallGraph::Edge> &Edges, 26 DenseMap<Function *, int> &EdgeIndexMap, Function &F, 27 LazyCallGraph::Edge::Kind EK) { 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() && 39 EdgeIndexMap.insert({&F, Edges.size()}).second) { 40 DEBUG(dbgs() << " Added callable function: " << F.getName() << "\n"); 41 Edges.emplace_back(LazyCallGraph::Edge(F, EK)); 42 } 43 } 44 45 LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F) 46 : G(&G), F(F), DFSNumber(0), LowLink(0) { 47 DEBUG(dbgs() << " Adding functions called by '" << F.getName() 48 << "' to the graph.\n"); 49 50 SmallVector<Constant *, 16> Worklist; 51 SmallPtrSet<Function *, 4> Callees; 52 SmallPtrSet<Constant *, 16> Visited; 53 54 // Find all the potential call graph edges in this function. We track both 55 // actual call edges and indirect references to functions. The direct calls 56 // are trivially added, but to accumulate the latter we walk the instructions 57 // and add every operand which is a constant to the worklist to process 58 // afterward. 59 for (BasicBlock &BB : F) 60 for (Instruction &I : BB) { 61 if (auto CS = CallSite(&I)) 62 if (Function *Callee = CS.getCalledFunction()) 63 if (Callees.insert(Callee).second) { 64 Visited.insert(Callee); 65 addEdge(Edges, EdgeIndexMap, *Callee, LazyCallGraph::Edge::Call); 66 } 67 68 for (Value *Op : I.operand_values()) 69 if (Constant *C = dyn_cast<Constant>(Op)) 70 if (Visited.insert(C).second) 71 Worklist.push_back(C); 72 } 73 74 // We've collected all the constant (and thus potentially function or 75 // function containing) operands to all of the instructions in the function. 76 // Process them (recursively) collecting every function found. 77 visitReferences(Worklist, Visited, [&](Function &F) { 78 addEdge(Edges, EdgeIndexMap, F, LazyCallGraph::Edge::Ref); 79 }); 80 } 81 82 void LazyCallGraph::Node::insertEdgeInternal(Function &Target, Edge::Kind EK) { 83 if (Node *N = G->lookup(Target)) 84 return insertEdgeInternal(*N, EK); 85 86 EdgeIndexMap.insert({&Target, Edges.size()}); 87 Edges.emplace_back(Target, EK); 88 } 89 90 void LazyCallGraph::Node::insertEdgeInternal(Node &TargetN, Edge::Kind EK) { 91 EdgeIndexMap.insert({&TargetN.getFunction(), Edges.size()}); 92 Edges.emplace_back(TargetN, EK); 93 } 94 95 void LazyCallGraph::Node::setEdgeKind(Function &TargetF, Edge::Kind EK) { 96 Edges[EdgeIndexMap.find(&TargetF)->second].setKind(EK); 97 } 98 99 void LazyCallGraph::Node::removeEdgeInternal(Function &Target) { 100 auto IndexMapI = EdgeIndexMap.find(&Target); 101 assert(IndexMapI != EdgeIndexMap.end() && 102 "Target not in the edge set for this caller?"); 103 104 Edges[IndexMapI->second] = Edge(); 105 EdgeIndexMap.erase(IndexMapI); 106 } 107 108 void LazyCallGraph::Node::dump() const { 109 dbgs() << *this << '\n'; 110 } 111 112 LazyCallGraph::LazyCallGraph(Module &M) : NextDFSNumber(0) { 113 DEBUG(dbgs() << "Building CG for module: " << M.getModuleIdentifier() 114 << "\n"); 115 for (Function &F : M) 116 if (!F.isDeclaration() && !F.hasLocalLinkage()) 117 if (EntryIndexMap.insert({&F, EntryEdges.size()}).second) { 118 DEBUG(dbgs() << " Adding '" << F.getName() 119 << "' to entry set of the graph.\n"); 120 EntryEdges.emplace_back(F, Edge::Ref); 121 } 122 123 // Now add entry nodes for functions reachable via initializers to globals. 124 SmallVector<Constant *, 16> Worklist; 125 SmallPtrSet<Constant *, 16> Visited; 126 for (GlobalVariable &GV : M.globals()) 127 if (GV.hasInitializer()) 128 if (Visited.insert(GV.getInitializer()).second) 129 Worklist.push_back(GV.getInitializer()); 130 131 DEBUG(dbgs() << " Adding functions referenced by global initializers to the " 132 "entry set.\n"); 133 visitReferences(Worklist, Visited, [&](Function &F) { 134 addEdge(EntryEdges, EntryIndexMap, F, LazyCallGraph::Edge::Ref); 135 }); 136 137 for (const Edge &E : EntryEdges) 138 RefSCCEntryNodes.push_back(&E.getFunction()); 139 } 140 141 LazyCallGraph::LazyCallGraph(LazyCallGraph &&G) 142 : BPA(std::move(G.BPA)), NodeMap(std::move(G.NodeMap)), 143 EntryEdges(std::move(G.EntryEdges)), 144 EntryIndexMap(std::move(G.EntryIndexMap)), SCCBPA(std::move(G.SCCBPA)), 145 SCCMap(std::move(G.SCCMap)), LeafRefSCCs(std::move(G.LeafRefSCCs)), 146 DFSStack(std::move(G.DFSStack)), 147 RefSCCEntryNodes(std::move(G.RefSCCEntryNodes)), 148 NextDFSNumber(G.NextDFSNumber) { 149 updateGraphPtrs(); 150 } 151 152 LazyCallGraph &LazyCallGraph::operator=(LazyCallGraph &&G) { 153 BPA = std::move(G.BPA); 154 NodeMap = std::move(G.NodeMap); 155 EntryEdges = std::move(G.EntryEdges); 156 EntryIndexMap = std::move(G.EntryIndexMap); 157 SCCBPA = std::move(G.SCCBPA); 158 SCCMap = std::move(G.SCCMap); 159 LeafRefSCCs = std::move(G.LeafRefSCCs); 160 DFSStack = std::move(G.DFSStack); 161 RefSCCEntryNodes = std::move(G.RefSCCEntryNodes); 162 NextDFSNumber = G.NextDFSNumber; 163 updateGraphPtrs(); 164 return *this; 165 } 166 167 void LazyCallGraph::SCC::dump() const { 168 dbgs() << *this << '\n'; 169 } 170 171 #ifndef NDEBUG 172 void LazyCallGraph::SCC::verify() { 173 assert(OuterRefSCC && "Can't have a null RefSCC!"); 174 assert(!Nodes.empty() && "Can't have an empty SCC!"); 175 176 for (Node *N : Nodes) { 177 assert(N && "Can't have a null node!"); 178 assert(OuterRefSCC->G->lookupSCC(*N) == this && 179 "Node does not map to this SCC!"); 180 assert(N->DFSNumber == -1 && 181 "Must set DFS numbers to -1 when adding a node to an SCC!"); 182 assert(N->LowLink == -1 && 183 "Must set low link to -1 when adding a node to an SCC!"); 184 for (Edge &E : *N) 185 assert(E.getNode() && "Can't have an edge to a raw function!"); 186 } 187 } 188 #endif 189 190 LazyCallGraph::RefSCC::RefSCC(LazyCallGraph &G) : G(&G) {} 191 192 void LazyCallGraph::RefSCC::dump() const { 193 dbgs() << *this << '\n'; 194 } 195 196 #ifndef NDEBUG 197 void LazyCallGraph::RefSCC::verify() { 198 assert(G && "Can't have a null graph!"); 199 assert(!SCCs.empty() && "Can't have an empty SCC!"); 200 201 // Verify basic properties of the SCCs. 202 SmallPtrSet<SCC *, 4> SCCSet; 203 for (SCC *C : SCCs) { 204 assert(C && "Can't have a null SCC!"); 205 C->verify(); 206 assert(&C->getOuterRefSCC() == this && 207 "SCC doesn't think it is inside this RefSCC!"); 208 bool Inserted = SCCSet.insert(C).second; 209 assert(Inserted && "Found a duplicate SCC!"); 210 } 211 212 // Check that our indices map correctly. 213 for (auto &SCCIndexPair : SCCIndices) { 214 SCC *C = SCCIndexPair.first; 215 int i = SCCIndexPair.second; 216 assert(C && "Can't have a null SCC in the indices!"); 217 assert(SCCSet.count(C) && "Found an index for an SCC not in the RefSCC!"); 218 assert(SCCs[i] == C && "Index doesn't point to SCC!"); 219 } 220 221 // Check that the SCCs are in fact in post-order. 222 for (int i = 0, Size = SCCs.size(); i < Size; ++i) { 223 SCC &SourceSCC = *SCCs[i]; 224 for (Node &N : SourceSCC) 225 for (Edge &E : N) { 226 if (!E.isCall()) 227 continue; 228 SCC &TargetSCC = *G->lookupSCC(*E.getNode()); 229 if (&TargetSCC.getOuterRefSCC() == this) { 230 assert(SCCIndices.find(&TargetSCC)->second <= i && 231 "Edge between SCCs violates post-order relationship."); 232 continue; 233 } 234 assert(TargetSCC.getOuterRefSCC().Parents.count(this) && 235 "Edge to a RefSCC missing us in its parent set."); 236 } 237 } 238 } 239 #endif 240 241 bool LazyCallGraph::RefSCC::isDescendantOf(const RefSCC &C) const { 242 // Walk up the parents of this SCC and verify that we eventually find C. 243 SmallVector<const RefSCC *, 4> AncestorWorklist; 244 AncestorWorklist.push_back(this); 245 do { 246 const RefSCC *AncestorC = AncestorWorklist.pop_back_val(); 247 if (AncestorC->isChildOf(C)) 248 return true; 249 for (const RefSCC *ParentC : AncestorC->Parents) 250 AncestorWorklist.push_back(ParentC); 251 } while (!AncestorWorklist.empty()); 252 253 return false; 254 } 255 256 /// Generic helper that updates a postorder sequence of SCCs for a potentially 257 /// cycle-introducing edge insertion. 258 /// 259 /// A postorder sequence of SCCs of a directed graph has one fundamental 260 /// property: all deges in the DAG of SCCs point "up" the sequence. That is, 261 /// all edges in the SCC DAG point to prior SCCs in the sequence. 262 /// 263 /// This routine both updates a postorder sequence and uses that sequence to 264 /// compute the set of SCCs connected into a cycle. It should only be called to 265 /// insert a "downward" edge which will require changing the sequence to 266 /// restore it to a postorder. 267 /// 268 /// When inserting an edge from an earlier SCC to a later SCC in some postorder 269 /// sequence, all of the SCCs which may be impacted are in the closed range of 270 /// those two within the postorder sequence. The algorithm used here to restore 271 /// the state is as follows: 272 /// 273 /// 1) Starting from the source SCC, construct a set of SCCs which reach the 274 /// source SCC consisting of just the source SCC. Then scan toward the 275 /// target SCC in postorder and for each SCC, if it has an edge to an SCC 276 /// in the set, add it to the set. Otherwise, the source SCC is not 277 /// a successor, move it in the postorder sequence to immediately before 278 /// the source SCC, shifting the source SCC and all SCCs in the set one 279 /// position toward the target SCC. Stop scanning after processing the 280 /// target SCC. 281 /// 2) If the source SCC is now past the target SCC in the postorder sequence, 282 /// and thus the new edge will flow toward the start, we are done. 283 /// 3) Otherwise, starting from the target SCC, walk all edges which reach an 284 /// SCC between the source and the target, and add them to the set of 285 /// connected SCCs, then recurse through them. Once a complete set of the 286 /// SCCs the target connects to is known, hoist the remaining SCCs between 287 /// the source and the target to be above the target. Note that there is no 288 /// need to process the source SCC, it is already known to connect. 289 /// 4) At this point, all of the SCCs in the closed range between the source 290 /// SCC and the target SCC in the postorder sequence are connected, 291 /// including the target SCC and the source SCC. Inserting the edge from 292 /// the source SCC to the target SCC will form a cycle out of precisely 293 /// these SCCs. Thus we can merge all of the SCCs in this closed range into 294 /// a single SCC. 295 /// 296 /// This process has various important properties: 297 /// - Only mutates the SCCs when adding the edge actually changes the SCC 298 /// structure. 299 /// - Never mutates SCCs which are unaffected by the change. 300 /// - Updates the postorder sequence to correctly satisfy the postorder 301 /// constraint after the edge is inserted. 302 /// - Only reorders SCCs in the closed postorder sequence from the source to 303 /// the target, so easy to bound how much has changed even in the ordering. 304 /// - Big-O is the number of edges in the closed postorder range of SCCs from 305 /// source to target. 306 /// 307 /// This helper routine, in addition to updating the postorder sequence itself 308 /// will also update a map from SCCs to indices within that sequecne. 309 /// 310 /// The sequence and the map must operate on pointers to the SCC type. 311 /// 312 /// Two callbacks must be provided. The first computes the subset of SCCs in 313 /// the postorder closed range from the source to the target which connect to 314 /// the source SCC via some (transitive) set of edges. The second computes the 315 /// subset of the same range which the target SCC connects to via some 316 /// (transitive) set of edges. Both callbacks should populate the set argument 317 /// provided. 318 template <typename SCCT, typename PostorderSequenceT, typename SCCIndexMapT, 319 typename ComputeSourceConnectedSetCallableT, 320 typename ComputeTargetConnectedSetCallableT> 321 static iterator_range<typename PostorderSequenceT::iterator> 322 updatePostorderSequenceForEdgeInsertion( 323 SCCT &SourceSCC, SCCT &TargetSCC, PostorderSequenceT &SCCs, 324 SCCIndexMapT &SCCIndices, 325 ComputeSourceConnectedSetCallableT ComputeSourceConnectedSet, 326 ComputeTargetConnectedSetCallableT ComputeTargetConnectedSet) { 327 int SourceIdx = SCCIndices[&SourceSCC]; 328 int TargetIdx = SCCIndices[&TargetSCC]; 329 assert(SourceIdx < TargetIdx && "Cannot have equal indices here!"); 330 331 SmallPtrSet<SCCT *, 4> ConnectedSet; 332 333 // Compute the SCCs which (transitively) reach the source. 334 ComputeSourceConnectedSet(ConnectedSet); 335 336 // Partition the SCCs in this part of the port-order sequence so only SCCs 337 // connecting to the source remain between it and the target. This is 338 // a benign partition as it preserves postorder. 339 auto SourceI = std::stable_partition( 340 SCCs.begin() + SourceIdx, SCCs.begin() + TargetIdx + 1, 341 [&ConnectedSet](SCCT *C) { return !ConnectedSet.count(C); }); 342 for (int i = SourceIdx, e = TargetIdx + 1; i < e; ++i) 343 SCCIndices.find(SCCs[i])->second = i; 344 345 // If the target doesn't connect to the source, then we've corrected the 346 // post-order and there are no cycles formed. 347 if (!ConnectedSet.count(&TargetSCC)) { 348 assert(SourceI > (SCCs.begin() + SourceIdx) && 349 "Must have moved the source to fix the post-order."); 350 assert(*std::prev(SourceI) == &TargetSCC && 351 "Last SCC to move should have bene the target."); 352 353 // Return an empty range at the target SCC indicating there is nothing to 354 // merge. 355 return make_range(std::prev(SourceI), std::prev(SourceI)); 356 } 357 358 assert(SCCs[TargetIdx] == &TargetSCC && 359 "Should not have moved target if connected!"); 360 SourceIdx = SourceI - SCCs.begin(); 361 assert(SCCs[SourceIdx] == &SourceSCC && 362 "Bad updated index computation for the source SCC!"); 363 364 365 // See whether there are any remaining intervening SCCs between the source 366 // and target. If so we need to make sure they all are reachable form the 367 // target. 368 if (SourceIdx + 1 < TargetIdx) { 369 ConnectedSet.clear(); 370 ComputeTargetConnectedSet(ConnectedSet); 371 372 // Partition SCCs so that only SCCs reached from the target remain between 373 // the source and the target. This preserves postorder. 374 auto TargetI = std::stable_partition( 375 SCCs.begin() + SourceIdx + 1, SCCs.begin() + TargetIdx + 1, 376 [&ConnectedSet](SCCT *C) { return ConnectedSet.count(C); }); 377 for (int i = SourceIdx + 1, e = TargetIdx + 1; i < e; ++i) 378 SCCIndices.find(SCCs[i])->second = i; 379 TargetIdx = std::prev(TargetI) - SCCs.begin(); 380 assert(SCCs[TargetIdx] == &TargetSCC && 381 "Should always end with the target!"); 382 } 383 384 // At this point, we know that connecting source to target forms a cycle 385 // because target connects back to source, and we know that all of the SCCs 386 // between the source and target in the postorder sequence participate in that 387 // cycle. 388 return make_range(SCCs.begin() + SourceIdx, SCCs.begin() + TargetIdx); 389 } 390 391 SmallVector<LazyCallGraph::SCC *, 1> 392 LazyCallGraph::RefSCC::switchInternalEdgeToCall(Node &SourceN, Node &TargetN) { 393 assert(!SourceN[TargetN].isCall() && "Must start with a ref edge!"); 394 SmallVector<SCC *, 1> DeletedSCCs; 395 396 #ifndef NDEBUG 397 // In a debug build, verify the RefSCC is valid to start with and when this 398 // routine finishes. 399 verify(); 400 auto VerifyOnExit = make_scope_exit([&]() { verify(); }); 401 #endif 402 403 SCC &SourceSCC = *G->lookupSCC(SourceN); 404 SCC &TargetSCC = *G->lookupSCC(TargetN); 405 406 // If the two nodes are already part of the same SCC, we're also done as 407 // we've just added more connectivity. 408 if (&SourceSCC == &TargetSCC) { 409 SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); 410 return DeletedSCCs; 411 } 412 413 // At this point we leverage the postorder list of SCCs to detect when the 414 // insertion of an edge changes the SCC structure in any way. 415 // 416 // First and foremost, we can eliminate the need for any changes when the 417 // edge is toward the beginning of the postorder sequence because all edges 418 // flow in that direction already. Thus adding a new one cannot form a cycle. 419 int SourceIdx = SCCIndices[&SourceSCC]; 420 int TargetIdx = SCCIndices[&TargetSCC]; 421 if (TargetIdx < SourceIdx) { 422 SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); 423 return DeletedSCCs; 424 } 425 426 // Compute the SCCs which (transitively) reach the source. 427 auto ComputeSourceConnectedSet = [&](SmallPtrSetImpl<SCC *> &ConnectedSet) { 428 #ifndef NDEBUG 429 // Check that the RefSCC is still valid before computing this as the 430 // results will be nonsensical of we've broken its invariants. 431 verify(); 432 #endif 433 ConnectedSet.insert(&SourceSCC); 434 auto IsConnected = [&](SCC &C) { 435 for (Node &N : C) 436 for (Edge &E : N.calls()) { 437 assert(E.getNode() && "Must have formed a node within an SCC!"); 438 if (ConnectedSet.count(G->lookupSCC(*E.getNode()))) 439 return true; 440 } 441 442 return false; 443 }; 444 445 for (SCC *C : 446 make_range(SCCs.begin() + SourceIdx + 1, SCCs.begin() + TargetIdx + 1)) 447 if (IsConnected(*C)) 448 ConnectedSet.insert(C); 449 }; 450 451 // Use a normal worklist to find which SCCs the target connects to. We still 452 // bound the search based on the range in the postorder list we care about, 453 // but because this is forward connectivity we just "recurse" through the 454 // edges. 455 auto ComputeTargetConnectedSet = [&](SmallPtrSetImpl<SCC *> &ConnectedSet) { 456 #ifndef NDEBUG 457 // Check that the RefSCC is still valid before computing this as the 458 // results will be nonsensical of we've broken its invariants. 459 verify(); 460 #endif 461 ConnectedSet.insert(&TargetSCC); 462 SmallVector<SCC *, 4> Worklist; 463 Worklist.push_back(&TargetSCC); 464 do { 465 SCC &C = *Worklist.pop_back_val(); 466 for (Node &N : C) 467 for (Edge &E : N) { 468 assert(E.getNode() && "Must have formed a node within an SCC!"); 469 if (!E.isCall()) 470 continue; 471 SCC &EdgeC = *G->lookupSCC(*E.getNode()); 472 if (&EdgeC.getOuterRefSCC() != this) 473 // Not in this RefSCC... 474 continue; 475 if (SCCIndices.find(&EdgeC)->second <= SourceIdx) 476 // Not in the postorder sequence between source and target. 477 continue; 478 479 if (ConnectedSet.insert(&EdgeC).second) 480 Worklist.push_back(&EdgeC); 481 } 482 } while (!Worklist.empty()); 483 }; 484 485 // Use a generic helper to update the postorder sequence of SCCs and return 486 // a range of any SCCs connected into a cycle by inserting this edge. This 487 // routine will also take care of updating the indices into the postorder 488 // sequence. 489 auto MergeRange = updatePostorderSequenceForEdgeInsertion( 490 SourceSCC, TargetSCC, SCCs, SCCIndices, ComputeSourceConnectedSet, 491 ComputeTargetConnectedSet); 492 493 // If the merge range is empty, then adding the edge didn't actually form any 494 // new cycles. We're done. 495 if (MergeRange.begin() == MergeRange.end()) { 496 // Now that the SCC structure is finalized, flip the kind to call. 497 SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); 498 return DeletedSCCs; 499 } 500 501 #ifndef NDEBUG 502 // Before merging, check that the RefSCC remains valid after all the 503 // postorder updates. 504 verify(); 505 #endif 506 507 // Otherwise we need to merge all of the SCCs in the cycle into a single 508 // result SCC. 509 // 510 // NB: We merge into the target because all of these functions were already 511 // reachable from the target, meaning any SCC-wide properties deduced about it 512 // other than the set of functions within it will not have changed. 513 for (SCC *C : MergeRange) { 514 assert(C != &TargetSCC && 515 "We merge *into* the target and shouldn't process it here!"); 516 SCCIndices.erase(C); 517 TargetSCC.Nodes.append(C->Nodes.begin(), C->Nodes.end()); 518 for (Node *N : C->Nodes) 519 G->SCCMap[N] = &TargetSCC; 520 C->clear(); 521 DeletedSCCs.push_back(C); 522 } 523 524 // Erase the merged SCCs from the list and update the indices of the 525 // remaining SCCs. 526 int IndexOffset = MergeRange.end() - MergeRange.begin(); 527 auto EraseEnd = SCCs.erase(MergeRange.begin(), MergeRange.end()); 528 for (SCC *C : make_range(EraseEnd, SCCs.end())) 529 SCCIndices[C] -= IndexOffset; 530 531 // Now that the SCC structure is finalized, flip the kind to call. 532 SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); 533 534 // And we're done! 535 return DeletedSCCs; 536 } 537 538 iterator_range<LazyCallGraph::RefSCC::iterator> 539 LazyCallGraph::RefSCC::switchInternalEdgeToRef(Node &SourceN, Node &TargetN) { 540 assert(SourceN[TargetN].isCall() && "Must start with a call edge!"); 541 542 #ifndef NDEBUG 543 // In a debug build, verify the RefSCC is valid to start with and when this 544 // routine finishes. 545 verify(); 546 auto VerifyOnExit = make_scope_exit([&]() { verify(); }); 547 #endif 548 549 SCC &SourceSCC = *G->lookupSCC(SourceN); 550 SCC &TargetSCC = *G->lookupSCC(TargetN); 551 552 assert(&SourceSCC.getOuterRefSCC() == this && 553 "Source must be in this RefSCC."); 554 assert(&TargetSCC.getOuterRefSCC() == this && 555 "Target must be in this RefSCC."); 556 557 // Set the edge kind. 558 SourceN.setEdgeKind(TargetN.getFunction(), Edge::Ref); 559 560 // If this call edge is just connecting two separate SCCs within this RefSCC, 561 // there is nothing to do. 562 if (&SourceSCC != &TargetSCC) 563 return make_range(SCCs.end(), SCCs.end()); 564 565 // Otherwise we are removing a call edge from a single SCC. This may break 566 // the cycle. In order to compute the new set of SCCs, we need to do a small 567 // DFS over the nodes within the SCC to form any sub-cycles that remain as 568 // distinct SCCs and compute a postorder over the resulting SCCs. 569 // 570 // However, we specially handle the target node. The target node is known to 571 // reach all other nodes in the original SCC by definition. This means that 572 // we want the old SCC to be replaced with an SCC contaning that node as it 573 // will be the root of whatever SCC DAG results from the DFS. Assumptions 574 // about an SCC such as the set of functions called will continue to hold, 575 // etc. 576 577 SCC &OldSCC = TargetSCC; 578 SmallVector<std::pair<Node *, call_edge_iterator>, 16> DFSStack; 579 SmallVector<Node *, 16> PendingSCCStack; 580 SmallVector<SCC *, 4> NewSCCs; 581 582 // Prepare the nodes for a fresh DFS. 583 SmallVector<Node *, 16> Worklist; 584 Worklist.swap(OldSCC.Nodes); 585 for (Node *N : Worklist) { 586 N->DFSNumber = N->LowLink = 0; 587 G->SCCMap.erase(N); 588 } 589 590 // Force the target node to be in the old SCC. This also enables us to take 591 // a very significant short-cut in the standard Tarjan walk to re-form SCCs 592 // below: whenever we build an edge that reaches the target node, we know 593 // that the target node eventually connects back to all other nodes in our 594 // walk. As a consequence, we can detect and handle participants in that 595 // cycle without walking all the edges that form this connection, and instead 596 // by relying on the fundamental guarantee coming into this operation (all 597 // nodes are reachable from the target due to previously forming an SCC). 598 TargetN.DFSNumber = TargetN.LowLink = -1; 599 OldSCC.Nodes.push_back(&TargetN); 600 G->SCCMap[&TargetN] = &OldSCC; 601 602 // Scan down the stack and DFS across the call edges. 603 for (Node *RootN : Worklist) { 604 assert(DFSStack.empty() && 605 "Cannot begin a new root with a non-empty DFS stack!"); 606 assert(PendingSCCStack.empty() && 607 "Cannot begin a new root with pending nodes for an SCC!"); 608 609 // Skip any nodes we've already reached in the DFS. 610 if (RootN->DFSNumber != 0) { 611 assert(RootN->DFSNumber == -1 && 612 "Shouldn't have any mid-DFS root nodes!"); 613 continue; 614 } 615 616 RootN->DFSNumber = RootN->LowLink = 1; 617 int NextDFSNumber = 2; 618 619 DFSStack.push_back({RootN, RootN->call_begin()}); 620 do { 621 Node *N; 622 call_edge_iterator I; 623 std::tie(N, I) = DFSStack.pop_back_val(); 624 auto E = N->call_end(); 625 while (I != E) { 626 Node &ChildN = *I->getNode(); 627 if (ChildN.DFSNumber == 0) { 628 // We haven't yet visited this child, so descend, pushing the current 629 // node onto the stack. 630 DFSStack.push_back({N, I}); 631 632 assert(!G->SCCMap.count(&ChildN) && 633 "Found a node with 0 DFS number but already in an SCC!"); 634 ChildN.DFSNumber = ChildN.LowLink = NextDFSNumber++; 635 N = &ChildN; 636 I = N->call_begin(); 637 E = N->call_end(); 638 continue; 639 } 640 641 // Check for the child already being part of some component. 642 if (ChildN.DFSNumber == -1) { 643 if (G->lookupSCC(ChildN) == &OldSCC) { 644 // If the child is part of the old SCC, we know that it can reach 645 // every other node, so we have formed a cycle. Pull the entire DFS 646 // and pending stacks into it. See the comment above about setting 647 // up the old SCC for why we do this. 648 int OldSize = OldSCC.size(); 649 OldSCC.Nodes.push_back(N); 650 OldSCC.Nodes.append(PendingSCCStack.begin(), PendingSCCStack.end()); 651 PendingSCCStack.clear(); 652 while (!DFSStack.empty()) 653 OldSCC.Nodes.push_back(DFSStack.pop_back_val().first); 654 for (Node &N : make_range(OldSCC.begin() + OldSize, OldSCC.end())) { 655 N.DFSNumber = N.LowLink = -1; 656 G->SCCMap[&N] = &OldSCC; 657 } 658 N = nullptr; 659 break; 660 } 661 662 // If the child has already been added to some child component, it 663 // couldn't impact the low-link of this parent because it isn't 664 // connected, and thus its low-link isn't relevant so skip it. 665 ++I; 666 continue; 667 } 668 669 // Track the lowest linked child as the lowest link for this node. 670 assert(ChildN.LowLink > 0 && "Must have a positive low-link number!"); 671 if (ChildN.LowLink < N->LowLink) 672 N->LowLink = ChildN.LowLink; 673 674 // Move to the next edge. 675 ++I; 676 } 677 if (!N) 678 // Cleared the DFS early, start another round. 679 break; 680 681 // We've finished processing N and its descendents, put it on our pending 682 // SCC stack to eventually get merged into an SCC of nodes. 683 PendingSCCStack.push_back(N); 684 685 // If this node is linked to some lower entry, continue walking up the 686 // stack. 687 if (N->LowLink != N->DFSNumber) 688 continue; 689 690 // Otherwise, we've completed an SCC. Append it to our post order list of 691 // SCCs. 692 int RootDFSNumber = N->DFSNumber; 693 // Find the range of the node stack by walking down until we pass the 694 // root DFS number. 695 auto SCCNodes = make_range( 696 PendingSCCStack.rbegin(), 697 find_if(reverse(PendingSCCStack), [RootDFSNumber](const Node *N) { 698 return N->DFSNumber < RootDFSNumber; 699 })); 700 701 // Form a new SCC out of these nodes and then clear them off our pending 702 // stack. 703 NewSCCs.push_back(G->createSCC(*this, SCCNodes)); 704 for (Node &N : *NewSCCs.back()) { 705 N.DFSNumber = N.LowLink = -1; 706 G->SCCMap[&N] = NewSCCs.back(); 707 } 708 PendingSCCStack.erase(SCCNodes.end().base(), PendingSCCStack.end()); 709 } while (!DFSStack.empty()); 710 } 711 712 // Insert the remaining SCCs before the old one. The old SCC can reach all 713 // other SCCs we form because it contains the target node of the removed edge 714 // of the old SCC. This means that we will have edges into all of the new 715 // SCCs, which means the old one must come last for postorder. 716 int OldIdx = SCCIndices[&OldSCC]; 717 SCCs.insert(SCCs.begin() + OldIdx, NewSCCs.begin(), NewSCCs.end()); 718 719 // Update the mapping from SCC* to index to use the new SCC*s, and remove the 720 // old SCC from the mapping. 721 for (int Idx = OldIdx, Size = SCCs.size(); Idx < Size; ++Idx) 722 SCCIndices[SCCs[Idx]] = Idx; 723 724 return make_range(SCCs.begin() + OldIdx, 725 SCCs.begin() + OldIdx + NewSCCs.size()); 726 } 727 728 void LazyCallGraph::RefSCC::switchOutgoingEdgeToCall(Node &SourceN, 729 Node &TargetN) { 730 assert(!SourceN[TargetN].isCall() && "Must start with a ref edge!"); 731 732 assert(G->lookupRefSCC(SourceN) == this && "Source must be in this RefSCC."); 733 assert(G->lookupRefSCC(TargetN) != this && 734 "Target must not be in this RefSCC."); 735 assert(G->lookupRefSCC(TargetN)->isDescendantOf(*this) && 736 "Target must be a descendant of the Source."); 737 738 // Edges between RefSCCs are the same regardless of call or ref, so we can 739 // just flip the edge here. 740 SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); 741 742 #ifndef NDEBUG 743 // Check that the RefSCC is still valid. 744 verify(); 745 #endif 746 } 747 748 void LazyCallGraph::RefSCC::switchOutgoingEdgeToRef(Node &SourceN, 749 Node &TargetN) { 750 assert(SourceN[TargetN].isCall() && "Must start with a call edge!"); 751 752 assert(G->lookupRefSCC(SourceN) == this && "Source must be in this RefSCC."); 753 assert(G->lookupRefSCC(TargetN) != this && 754 "Target must not be in this RefSCC."); 755 assert(G->lookupRefSCC(TargetN)->isDescendantOf(*this) && 756 "Target must be a descendant of the Source."); 757 758 // Edges between RefSCCs are the same regardless of call or ref, so we can 759 // just flip the edge here. 760 SourceN.setEdgeKind(TargetN.getFunction(), Edge::Ref); 761 762 #ifndef NDEBUG 763 // Check that the RefSCC is still valid. 764 verify(); 765 #endif 766 } 767 768 void LazyCallGraph::RefSCC::insertInternalRefEdge(Node &SourceN, 769 Node &TargetN) { 770 assert(G->lookupRefSCC(SourceN) == this && "Source must be in this RefSCC."); 771 assert(G->lookupRefSCC(TargetN) == this && "Target must be in this RefSCC."); 772 773 SourceN.insertEdgeInternal(TargetN, Edge::Ref); 774 775 #ifndef NDEBUG 776 // Check that the RefSCC is still valid. 777 verify(); 778 #endif 779 } 780 781 void LazyCallGraph::RefSCC::insertOutgoingEdge(Node &SourceN, Node &TargetN, 782 Edge::Kind EK) { 783 // First insert it into the caller. 784 SourceN.insertEdgeInternal(TargetN, EK); 785 786 assert(G->lookupRefSCC(SourceN) == this && "Source must be in this RefSCC."); 787 788 RefSCC &TargetC = *G->lookupRefSCC(TargetN); 789 assert(&TargetC != this && "Target must not be in this RefSCC."); 790 assert(TargetC.isDescendantOf(*this) && 791 "Target must be a descendant of the Source."); 792 793 // The only change required is to add this SCC to the parent set of the 794 // callee. 795 TargetC.Parents.insert(this); 796 797 #ifndef NDEBUG 798 // Check that the RefSCC is still valid. 799 verify(); 800 #endif 801 } 802 803 SmallVector<LazyCallGraph::RefSCC *, 1> 804 LazyCallGraph::RefSCC::insertIncomingRefEdge(Node &SourceN, Node &TargetN) { 805 assert(G->lookupRefSCC(TargetN) == this && "Target must be in this RefSCC."); 806 RefSCC &SourceC = *G->lookupRefSCC(SourceN); 807 assert(&SourceC != this && "Source must not be in this RefSCC."); 808 assert(SourceC.isDescendantOf(*this) && 809 "Source must be a descendant of the Target."); 810 811 SmallVector<RefSCC *, 1> DeletedRefSCCs; 812 813 #ifndef NDEBUG 814 // In a debug build, verify the RefSCC is valid to start with and when this 815 // routine finishes. 816 verify(); 817 auto VerifyOnExit = make_scope_exit([&]() { verify(); }); 818 #endif 819 820 int SourceIdx = G->RefSCCIndices[&SourceC]; 821 int TargetIdx = G->RefSCCIndices[this]; 822 assert(SourceIdx < TargetIdx && 823 "Postorder list doesn't see edge as incoming!"); 824 825 // Compute the RefSCCs which (transitively) reach the source. We do this by 826 // working backwards from the source using the parent set in each RefSCC, 827 // skipping any RefSCCs that don't fall in the postorder range. This has the 828 // advantage of walking the sparser parent edge (in high fan-out graphs) but 829 // more importantly this removes examining all forward edges in all RefSCCs 830 // within the postorder range which aren't in fact connected. Only connected 831 // RefSCCs (and their edges) are visited here. 832 auto ComputeSourceConnectedSet = [&](SmallPtrSetImpl<RefSCC *> &Set) { 833 Set.insert(&SourceC); 834 SmallVector<RefSCC *, 4> Worklist; 835 Worklist.push_back(&SourceC); 836 do { 837 RefSCC &RC = *Worklist.pop_back_val(); 838 for (RefSCC &ParentRC : RC.parents()) { 839 // Skip any RefSCCs outside the range of source to target in the 840 // postorder sequence. 841 int ParentIdx = G->getRefSCCIndex(ParentRC); 842 assert(ParentIdx > SourceIdx && "Parent cannot precede source in postorder!"); 843 if (ParentIdx > TargetIdx) 844 continue; 845 if (Set.insert(&ParentRC).second) 846 // First edge connecting to this parent, add it to our worklist. 847 Worklist.push_back(&ParentRC); 848 } 849 } while (!Worklist.empty()); 850 }; 851 852 // Use a normal worklist to find which SCCs the target connects to. We still 853 // bound the search based on the range in the postorder list we care about, 854 // but because this is forward connectivity we just "recurse" through the 855 // edges. 856 auto ComputeTargetConnectedSet = [&](SmallPtrSetImpl<RefSCC *> &Set) { 857 Set.insert(this); 858 SmallVector<RefSCC *, 4> Worklist; 859 Worklist.push_back(this); 860 do { 861 RefSCC &RC = *Worklist.pop_back_val(); 862 for (SCC &C : RC) 863 for (Node &N : C) 864 for (Edge &E : N) { 865 assert(E.getNode() && "Must have formed a node!"); 866 RefSCC &EdgeRC = *G->lookupRefSCC(*E.getNode()); 867 if (G->getRefSCCIndex(EdgeRC) <= SourceIdx) 868 // Not in the postorder sequence between source and target. 869 continue; 870 871 if (Set.insert(&EdgeRC).second) 872 Worklist.push_back(&EdgeRC); 873 } 874 } while (!Worklist.empty()); 875 }; 876 877 // Use a generic helper to update the postorder sequence of RefSCCs and return 878 // a range of any RefSCCs connected into a cycle by inserting this edge. This 879 // routine will also take care of updating the indices into the postorder 880 // sequence. 881 iterator_range<SmallVectorImpl<RefSCC *>::iterator> MergeRange = 882 updatePostorderSequenceForEdgeInsertion( 883 SourceC, *this, G->PostOrderRefSCCs, G->RefSCCIndices, 884 ComputeSourceConnectedSet, ComputeTargetConnectedSet); 885 886 // Build a set so we can do fast tests for whether a merge is occuring. 887 SmallPtrSet<RefSCC *, 16> MergeSet(MergeRange.begin(), MergeRange.end()); 888 889 // Now that we have identified all of the SCCs which need to be merged into 890 // a connected set with the inserted edge, merge all of them into this SCC. 891 SmallVector<SCC *, 16> MergedSCCs; 892 int SCCIndex = 0; 893 for (RefSCC *RC : MergeRange) { 894 assert(RC != this && "We're merging into the target RefSCC, so it " 895 "shouldn't be in the range."); 896 897 // Merge the parents which aren't part of the merge into the our parents. 898 for (RefSCC *ParentRC : RC->Parents) 899 if (!MergeSet.count(ParentRC)) 900 Parents.insert(ParentRC); 901 RC->Parents.clear(); 902 903 // Walk the inner SCCs to update their up-pointer and walk all the edges to 904 // update any parent sets. 905 // FIXME: We should try to find a way to avoid this (rather expensive) edge 906 // walk by updating the parent sets in some other manner. 907 for (SCC &InnerC : *RC) { 908 InnerC.OuterRefSCC = this; 909 SCCIndices[&InnerC] = SCCIndex++; 910 for (Node &N : InnerC) { 911 G->SCCMap[&N] = &InnerC; 912 for (Edge &E : N) { 913 assert(E.getNode() && 914 "Cannot have a null node within a visited SCC!"); 915 RefSCC &ChildRC = *G->lookupRefSCC(*E.getNode()); 916 if (MergeSet.count(&ChildRC)) 917 continue; 918 ChildRC.Parents.erase(RC); 919 ChildRC.Parents.insert(this); 920 } 921 } 922 } 923 924 // Now merge in the SCCs. We can actually move here so try to reuse storage 925 // the first time through. 926 if (MergedSCCs.empty()) 927 MergedSCCs = std::move(RC->SCCs); 928 else 929 MergedSCCs.append(RC->SCCs.begin(), RC->SCCs.end()); 930 RC->SCCs.clear(); 931 DeletedRefSCCs.push_back(RC); 932 } 933 934 // Append our original SCCs to the merged list and move it into place. 935 for (SCC &InnerC : *this) 936 SCCIndices[&InnerC] = SCCIndex++; 937 MergedSCCs.append(SCCs.begin(), SCCs.end()); 938 SCCs = std::move(MergedSCCs); 939 940 // Remove the merged away RefSCCs from the post order sequence. 941 for (RefSCC *RC : MergeRange) 942 G->RefSCCIndices.erase(RC); 943 int IndexOffset = MergeRange.end() - MergeRange.begin(); 944 auto EraseEnd = 945 G->PostOrderRefSCCs.erase(MergeRange.begin(), MergeRange.end()); 946 for (RefSCC *RC : make_range(EraseEnd, G->PostOrderRefSCCs.end())) 947 G->RefSCCIndices[RC] -= IndexOffset; 948 949 // At this point we have a merged RefSCC with a post-order SCCs list, just 950 // connect the nodes to form the new edge. 951 SourceN.insertEdgeInternal(TargetN, Edge::Ref); 952 953 // We return the list of SCCs which were merged so that callers can 954 // invalidate any data they have associated with those SCCs. Note that these 955 // SCCs are no longer in an interesting state (they are totally empty) but 956 // the pointers will remain stable for the life of the graph itself. 957 return DeletedRefSCCs; 958 } 959 960 void LazyCallGraph::RefSCC::removeOutgoingEdge(Node &SourceN, Node &TargetN) { 961 assert(G->lookupRefSCC(SourceN) == this && 962 "The source must be a member of this RefSCC."); 963 964 RefSCC &TargetRC = *G->lookupRefSCC(TargetN); 965 assert(&TargetRC != this && "The target must not be a member of this RefSCC"); 966 967 assert(!is_contained(G->LeafRefSCCs, this) && 968 "Cannot have a leaf RefSCC source."); 969 970 #ifndef NDEBUG 971 // In a debug build, verify the RefSCC is valid to start with and when this 972 // routine finishes. 973 verify(); 974 auto VerifyOnExit = make_scope_exit([&]() { verify(); }); 975 #endif 976 977 // First remove it from the node. 978 SourceN.removeEdgeInternal(TargetN.getFunction()); 979 980 bool HasOtherEdgeToChildRC = false; 981 bool HasOtherChildRC = false; 982 for (SCC *InnerC : SCCs) { 983 for (Node &N : *InnerC) { 984 for (Edge &E : N) { 985 assert(E.getNode() && "Cannot have a missing node in a visited SCC!"); 986 RefSCC &OtherChildRC = *G->lookupRefSCC(*E.getNode()); 987 if (&OtherChildRC == &TargetRC) { 988 HasOtherEdgeToChildRC = true; 989 break; 990 } 991 if (&OtherChildRC != this) 992 HasOtherChildRC = true; 993 } 994 if (HasOtherEdgeToChildRC) 995 break; 996 } 997 if (HasOtherEdgeToChildRC) 998 break; 999 } 1000 // Because the SCCs form a DAG, deleting such an edge cannot change the set 1001 // of SCCs in the graph. However, it may cut an edge of the SCC DAG, making 1002 // the source SCC no longer connected to the target SCC. If so, we need to 1003 // update the target SCC's map of its parents. 1004 if (!HasOtherEdgeToChildRC) { 1005 bool Removed = TargetRC.Parents.erase(this); 1006 (void)Removed; 1007 assert(Removed && 1008 "Did not find the source SCC in the target SCC's parent list!"); 1009 1010 // It may orphan an SCC if it is the last edge reaching it, but that does 1011 // not violate any invariants of the graph. 1012 if (TargetRC.Parents.empty()) 1013 DEBUG(dbgs() << "LCG: Update removing " << SourceN.getFunction().getName() 1014 << " -> " << TargetN.getFunction().getName() 1015 << " edge orphaned the callee's SCC!\n"); 1016 1017 // It may make the Source SCC a leaf SCC. 1018 if (!HasOtherChildRC) 1019 G->LeafRefSCCs.push_back(this); 1020 } 1021 } 1022 1023 SmallVector<LazyCallGraph::RefSCC *, 1> 1024 LazyCallGraph::RefSCC::removeInternalRefEdge(Node &SourceN, Node &TargetN) { 1025 assert(!SourceN[TargetN].isCall() && 1026 "Cannot remove a call edge, it must first be made a ref edge"); 1027 1028 #ifndef NDEBUG 1029 // In a debug build, verify the RefSCC is valid to start with and when this 1030 // routine finishes. 1031 verify(); 1032 auto VerifyOnExit = make_scope_exit([&]() { verify(); }); 1033 #endif 1034 1035 // First remove the actual edge. 1036 SourceN.removeEdgeInternal(TargetN.getFunction()); 1037 1038 // We return a list of the resulting *new* RefSCCs in post-order. 1039 SmallVector<RefSCC *, 1> Result; 1040 1041 // Direct recursion doesn't impact the SCC graph at all. 1042 if (&SourceN == &TargetN) 1043 return Result; 1044 1045 // We build somewhat synthetic new RefSCCs by providing a postorder mapping 1046 // for each inner SCC. We also store these associated with *nodes* rather 1047 // than SCCs because this saves a round-trip through the node->SCC map and in 1048 // the common case, SCCs are small. We will verify that we always give the 1049 // same number to every node in the SCC such that these are equivalent. 1050 const int RootPostOrderNumber = 0; 1051 int PostOrderNumber = RootPostOrderNumber + 1; 1052 SmallDenseMap<Node *, int> PostOrderMapping; 1053 1054 // Every node in the target SCC can already reach every node in this RefSCC 1055 // (by definition). It is the only node we know will stay inside this RefSCC. 1056 // Everything which transitively reaches Target will also remain in the 1057 // RefSCC. We handle this by pre-marking that the nodes in the target SCC map 1058 // back to the root post order number. 1059 // 1060 // This also enables us to take a very significant short-cut in the standard 1061 // Tarjan walk to re-form RefSCCs below: whenever we build an edge that 1062 // references the target node, we know that the target node eventually 1063 // references all other nodes in our walk. As a consequence, we can detect 1064 // and handle participants in that cycle without walking all the edges that 1065 // form the connections, and instead by relying on the fundamental guarantee 1066 // coming into this operation. 1067 SCC &TargetC = *G->lookupSCC(TargetN); 1068 for (Node &N : TargetC) 1069 PostOrderMapping[&N] = RootPostOrderNumber; 1070 1071 // Reset all the other nodes to prepare for a DFS over them, and add them to 1072 // our worklist. 1073 SmallVector<Node *, 8> Worklist; 1074 for (SCC *C : SCCs) { 1075 if (C == &TargetC) 1076 continue; 1077 1078 for (Node &N : *C) 1079 N.DFSNumber = N.LowLink = 0; 1080 1081 Worklist.append(C->Nodes.begin(), C->Nodes.end()); 1082 } 1083 1084 auto MarkNodeForSCCNumber = [&PostOrderMapping](Node &N, int Number) { 1085 N.DFSNumber = N.LowLink = -1; 1086 PostOrderMapping[&N] = Number; 1087 }; 1088 1089 SmallVector<std::pair<Node *, edge_iterator>, 4> DFSStack; 1090 SmallVector<Node *, 4> PendingRefSCCStack; 1091 do { 1092 assert(DFSStack.empty() && 1093 "Cannot begin a new root with a non-empty DFS stack!"); 1094 assert(PendingRefSCCStack.empty() && 1095 "Cannot begin a new root with pending nodes for an SCC!"); 1096 1097 Node *RootN = Worklist.pop_back_val(); 1098 // Skip any nodes we've already reached in the DFS. 1099 if (RootN->DFSNumber != 0) { 1100 assert(RootN->DFSNumber == -1 && 1101 "Shouldn't have any mid-DFS root nodes!"); 1102 continue; 1103 } 1104 1105 RootN->DFSNumber = RootN->LowLink = 1; 1106 int NextDFSNumber = 2; 1107 1108 DFSStack.push_back({RootN, RootN->begin()}); 1109 do { 1110 Node *N; 1111 edge_iterator I; 1112 std::tie(N, I) = DFSStack.pop_back_val(); 1113 auto E = N->end(); 1114 1115 assert(N->DFSNumber != 0 && "We should always assign a DFS number " 1116 "before processing a node."); 1117 1118 while (I != E) { 1119 Node &ChildN = I->getNode(*G); 1120 if (ChildN.DFSNumber == 0) { 1121 // Mark that we should start at this child when next this node is the 1122 // top of the stack. We don't start at the next child to ensure this 1123 // child's lowlink is reflected. 1124 DFSStack.push_back({N, I}); 1125 1126 // Continue, resetting to the child node. 1127 ChildN.LowLink = ChildN.DFSNumber = NextDFSNumber++; 1128 N = &ChildN; 1129 I = ChildN.begin(); 1130 E = ChildN.end(); 1131 continue; 1132 } 1133 if (ChildN.DFSNumber == -1) { 1134 // Check if this edge's target node connects to the deleted edge's 1135 // target node. If so, we know that every node connected will end up 1136 // in this RefSCC, so collapse the entire current stack into the root 1137 // slot in our SCC numbering. See above for the motivation of 1138 // optimizing the target connected nodes in this way. 1139 auto PostOrderI = PostOrderMapping.find(&ChildN); 1140 if (PostOrderI != PostOrderMapping.end() && 1141 PostOrderI->second == RootPostOrderNumber) { 1142 MarkNodeForSCCNumber(*N, RootPostOrderNumber); 1143 while (!PendingRefSCCStack.empty()) 1144 MarkNodeForSCCNumber(*PendingRefSCCStack.pop_back_val(), 1145 RootPostOrderNumber); 1146 while (!DFSStack.empty()) 1147 MarkNodeForSCCNumber(*DFSStack.pop_back_val().first, 1148 RootPostOrderNumber); 1149 // Ensure we break all the way out of the enclosing loop. 1150 N = nullptr; 1151 break; 1152 } 1153 1154 // If this child isn't currently in this RefSCC, no need to process 1155 // it. 1156 // However, we do need to remove this RefSCC from its RefSCC's parent 1157 // set. 1158 RefSCC &ChildRC = *G->lookupRefSCC(ChildN); 1159 ChildRC.Parents.erase(this); 1160 ++I; 1161 continue; 1162 } 1163 1164 // Track the lowest link of the children, if any are still in the stack. 1165 // Any child not on the stack will have a LowLink of -1. 1166 assert(ChildN.LowLink != 0 && 1167 "Low-link must not be zero with a non-zero DFS number."); 1168 if (ChildN.LowLink >= 0 && ChildN.LowLink < N->LowLink) 1169 N->LowLink = ChildN.LowLink; 1170 ++I; 1171 } 1172 if (!N) 1173 // We short-circuited this node. 1174 break; 1175 1176 // We've finished processing N and its descendents, put it on our pending 1177 // stack to eventually get merged into a RefSCC. 1178 PendingRefSCCStack.push_back(N); 1179 1180 // If this node is linked to some lower entry, continue walking up the 1181 // stack. 1182 if (N->LowLink != N->DFSNumber) { 1183 assert(!DFSStack.empty() && 1184 "We never found a viable root for a RefSCC to pop off!"); 1185 continue; 1186 } 1187 1188 // Otherwise, form a new RefSCC from the top of the pending node stack. 1189 int RootDFSNumber = N->DFSNumber; 1190 // Find the range of the node stack by walking down until we pass the 1191 // root DFS number. 1192 auto RefSCCNodes = make_range( 1193 PendingRefSCCStack.rbegin(), 1194 find_if(reverse(PendingRefSCCStack), [RootDFSNumber](const Node *N) { 1195 return N->DFSNumber < RootDFSNumber; 1196 })); 1197 1198 // Mark the postorder number for these nodes and clear them off the 1199 // stack. We'll use the postorder number to pull them into RefSCCs at the 1200 // end. FIXME: Fuse with the loop above. 1201 int RefSCCNumber = PostOrderNumber++; 1202 for (Node *N : RefSCCNodes) 1203 MarkNodeForSCCNumber(*N, RefSCCNumber); 1204 1205 PendingRefSCCStack.erase(RefSCCNodes.end().base(), 1206 PendingRefSCCStack.end()); 1207 } while (!DFSStack.empty()); 1208 1209 assert(DFSStack.empty() && "Didn't flush the entire DFS stack!"); 1210 assert(PendingRefSCCStack.empty() && "Didn't flush all pending nodes!"); 1211 } while (!Worklist.empty()); 1212 1213 // We now have a post-order numbering for RefSCCs and a mapping from each 1214 // node in this RefSCC to its final RefSCC. We create each new RefSCC node 1215 // (re-using this RefSCC node for the root) and build a radix-sort style map 1216 // from postorder number to the RefSCC. We then append SCCs to each of these 1217 // RefSCCs in the order they occured in the original SCCs container. 1218 for (int i = 1; i < PostOrderNumber; ++i) 1219 Result.push_back(G->createRefSCC(*G)); 1220 1221 // Insert the resulting postorder sequence into the global graph postorder 1222 // sequence before the current RefSCC in that sequence. The idea being that 1223 // this RefSCC is the target of the reference edge removed, and thus has 1224 // a direct or indirect edge to every other RefSCC formed and so must be at 1225 // the end of any postorder traversal. 1226 // 1227 // FIXME: It'd be nice to change the APIs so that we returned an iterator 1228 // range over the global postorder sequence and generally use that sequence 1229 // rather than building a separate result vector here. 1230 if (!Result.empty()) { 1231 int Idx = G->getRefSCCIndex(*this); 1232 G->PostOrderRefSCCs.insert(G->PostOrderRefSCCs.begin() + Idx, 1233 Result.begin(), Result.end()); 1234 for (int i : seq<int>(Idx, G->PostOrderRefSCCs.size())) 1235 G->RefSCCIndices[G->PostOrderRefSCCs[i]] = i; 1236 assert(G->PostOrderRefSCCs[G->getRefSCCIndex(*this)] == this && 1237 "Failed to update this RefSCC's index after insertion!"); 1238 } 1239 1240 for (SCC *C : SCCs) { 1241 auto PostOrderI = PostOrderMapping.find(&*C->begin()); 1242 assert(PostOrderI != PostOrderMapping.end() && 1243 "Cannot have missing mappings for nodes!"); 1244 int SCCNumber = PostOrderI->second; 1245 #ifndef NDEBUG 1246 for (Node &N : *C) 1247 assert(PostOrderMapping.find(&N)->second == SCCNumber && 1248 "Cannot have different numbers for nodes in the same SCC!"); 1249 #endif 1250 if (SCCNumber == 0) 1251 // The root node is handled separately by removing the SCCs. 1252 continue; 1253 1254 RefSCC &RC = *Result[SCCNumber - 1]; 1255 int SCCIndex = RC.SCCs.size(); 1256 RC.SCCs.push_back(C); 1257 SCCIndices[C] = SCCIndex; 1258 C->OuterRefSCC = &RC; 1259 } 1260 1261 // FIXME: We re-walk the edges in each RefSCC to establish whether it is 1262 // a leaf and connect it to the rest of the graph's parents lists. This is 1263 // really wasteful. We should instead do this during the DFS to avoid yet 1264 // another edge walk. 1265 for (RefSCC *RC : Result) 1266 G->connectRefSCC(*RC); 1267 1268 // Now erase all but the root's SCCs. 1269 SCCs.erase(remove_if(SCCs, 1270 [&](SCC *C) { 1271 return PostOrderMapping.lookup(&*C->begin()) != 1272 RootPostOrderNumber; 1273 }), 1274 SCCs.end()); 1275 SCCIndices.clear(); 1276 for (int i = 0, Size = SCCs.size(); i < Size; ++i) 1277 SCCIndices[SCCs[i]] = i; 1278 1279 #ifndef NDEBUG 1280 // Now we need to reconnect the current (root) SCC to the graph. We do this 1281 // manually because we can special case our leaf handling and detect errors. 1282 bool IsLeaf = true; 1283 #endif 1284 for (SCC *C : SCCs) 1285 for (Node &N : *C) { 1286 for (Edge &E : N) { 1287 assert(E.getNode() && "Cannot have a missing node in a visited SCC!"); 1288 RefSCC &ChildRC = *G->lookupRefSCC(*E.getNode()); 1289 if (&ChildRC == this) 1290 continue; 1291 ChildRC.Parents.insert(this); 1292 #ifndef NDEBUG 1293 IsLeaf = false; 1294 #endif 1295 } 1296 } 1297 #ifndef NDEBUG 1298 if (!Result.empty()) 1299 assert(!IsLeaf && "This SCC cannot be a leaf as we have split out new " 1300 "SCCs by removing this edge."); 1301 if (none_of(G->LeafRefSCCs, [&](RefSCC *C) { return C == this; })) 1302 assert(!IsLeaf && "This SCC cannot be a leaf as it already had child " 1303 "SCCs before we removed this edge."); 1304 #endif 1305 // And connect both this RefSCC and all the new ones to the correct parents. 1306 // The easiest way to do this is just to re-analyze the old parent set. 1307 SmallVector<RefSCC *, 4> OldParents(Parents.begin(), Parents.end()); 1308 Parents.clear(); 1309 for (RefSCC *ParentRC : OldParents) 1310 for (SCC *ParentC : ParentRC->SCCs) 1311 for (Node &ParentN : *ParentC) 1312 for (Edge &E : ParentN) { 1313 assert(E.getNode() && "Cannot have a missing node in a visited SCC!"); 1314 RefSCC &RC = *G->lookupRefSCC(*E.getNode()); 1315 RC.Parents.insert(ParentRC); 1316 } 1317 1318 // If this SCC stopped being a leaf through this edge removal, remove it from 1319 // the leaf SCC list. Note that this DTRT in the case where this was never 1320 // a leaf. 1321 // FIXME: As LeafRefSCCs could be very large, we might want to not walk the 1322 // entire list if this RefSCC wasn't a leaf before the edge removal. 1323 if (!Result.empty()) 1324 G->LeafRefSCCs.erase( 1325 std::remove(G->LeafRefSCCs.begin(), G->LeafRefSCCs.end(), this), 1326 G->LeafRefSCCs.end()); 1327 1328 // Return the new list of SCCs. 1329 return Result; 1330 } 1331 1332 void LazyCallGraph::RefSCC::handleTrivialEdgeInsertion(Node &SourceN, 1333 Node &TargetN) { 1334 // The only trivial case that requires any graph updates is when we add new 1335 // ref edge and may connect different RefSCCs along that path. This is only 1336 // because of the parents set. Every other part of the graph remains constant 1337 // after this edge insertion. 1338 assert(G->lookupRefSCC(SourceN) == this && "Source must be in this RefSCC."); 1339 RefSCC &TargetRC = *G->lookupRefSCC(TargetN); 1340 if (&TargetRC == this) { 1341 1342 return; 1343 } 1344 1345 assert(TargetRC.isDescendantOf(*this) && 1346 "Target must be a descendant of the Source."); 1347 // The only change required is to add this RefSCC to the parent set of the 1348 // target. This is a set and so idempotent if the edge already existed. 1349 TargetRC.Parents.insert(this); 1350 } 1351 1352 void LazyCallGraph::RefSCC::insertTrivialCallEdge(Node &SourceN, 1353 Node &TargetN) { 1354 #ifndef NDEBUG 1355 // Check that the RefSCC is still valid when we finish. 1356 auto ExitVerifier = make_scope_exit([this] { verify(); }); 1357 #endif 1358 // First insert it into the source or find the existing edge. 1359 auto InsertResult = SourceN.EdgeIndexMap.insert( 1360 {&TargetN.getFunction(), SourceN.Edges.size()}); 1361 if (!InsertResult.second) { 1362 // Already an edge, just update it. 1363 Edge &E = SourceN.Edges[InsertResult.first->second]; 1364 if (E.isCall()) 1365 return; // Nothing to do! 1366 E.setKind(Edge::Call); 1367 } else { 1368 // Create the new edge. 1369 SourceN.Edges.emplace_back(TargetN, Edge::Call); 1370 } 1371 1372 // Now that we have the edge, handle the graph fallout. 1373 handleTrivialEdgeInsertion(SourceN, TargetN); 1374 } 1375 1376 void LazyCallGraph::RefSCC::insertTrivialRefEdge(Node &SourceN, Node &TargetN) { 1377 #ifndef NDEBUG 1378 // Check that the RefSCC is still valid when we finish. 1379 auto ExitVerifier = make_scope_exit([this] { verify(); }); 1380 #endif 1381 // First insert it into the source or find the existing edge. 1382 auto InsertResult = SourceN.EdgeIndexMap.insert( 1383 {&TargetN.getFunction(), SourceN.Edges.size()}); 1384 if (!InsertResult.second) 1385 // Already an edge, we're done. 1386 return; 1387 1388 // Create the new edge. 1389 SourceN.Edges.emplace_back(TargetN, Edge::Ref); 1390 1391 // Now that we have the edge, handle the graph fallout. 1392 handleTrivialEdgeInsertion(SourceN, TargetN); 1393 } 1394 1395 void LazyCallGraph::insertEdge(Node &SourceN, Function &Target, Edge::Kind EK) { 1396 assert(SCCMap.empty() && DFSStack.empty() && 1397 "This method cannot be called after SCCs have been formed!"); 1398 1399 return SourceN.insertEdgeInternal(Target, EK); 1400 } 1401 1402 void LazyCallGraph::removeEdge(Node &SourceN, Function &Target) { 1403 assert(SCCMap.empty() && DFSStack.empty() && 1404 "This method cannot be called after SCCs have been formed!"); 1405 1406 return SourceN.removeEdgeInternal(Target); 1407 } 1408 1409 void LazyCallGraph::removeDeadFunction(Function &F) { 1410 // FIXME: This is unnecessarily restrictive. We should be able to remove 1411 // functions which recursively call themselves. 1412 assert(F.use_empty() && 1413 "This routine should only be called on trivially dead functions!"); 1414 1415 auto EII = EntryIndexMap.find(&F); 1416 if (EII != EntryIndexMap.end()) { 1417 EntryEdges[EII->second] = Edge(); 1418 EntryIndexMap.erase(EII); 1419 } 1420 1421 // It's safe to just remove un-visited functions from the RefSCC entry list. 1422 // FIXME: This is a linear operation which could become hot and benefit from 1423 // an index map. 1424 auto RENI = find(RefSCCEntryNodes, &F); 1425 if (RENI != RefSCCEntryNodes.end()) 1426 RefSCCEntryNodes.erase(RENI); 1427 1428 auto NI = NodeMap.find(&F); 1429 if (NI == NodeMap.end()) 1430 // Not in the graph at all! 1431 return; 1432 1433 Node &N = *NI->second; 1434 NodeMap.erase(NI); 1435 1436 if (SCCMap.empty() && DFSStack.empty()) { 1437 // No SCC walk has begun, so removing this is fine and there is nothing 1438 // else necessary at this point but clearing out the node. 1439 N.clear(); 1440 return; 1441 } 1442 1443 // Check that we aren't going to break the DFS walk. 1444 assert(all_of(DFSStack, 1445 [&N](const std::pair<Node *, edge_iterator> &Element) { 1446 return Element.first != &N; 1447 }) && 1448 "Tried to remove a function currently in the DFS stack!"); 1449 assert(find(PendingRefSCCStack, &N) == PendingRefSCCStack.end() && 1450 "Tried to remove a function currently pending to add to a RefSCC!"); 1451 1452 // Cannot remove a function which has yet to be visited in the DFS walk, so 1453 // if we have a node at all then we must have an SCC and RefSCC. 1454 auto CI = SCCMap.find(&N); 1455 assert(CI != SCCMap.end() && 1456 "Tried to remove a node without an SCC after DFS walk started!"); 1457 SCC &C = *CI->second; 1458 SCCMap.erase(CI); 1459 RefSCC &RC = C.getOuterRefSCC(); 1460 1461 // This node must be the only member of its SCC as it has no callers, and 1462 // that SCC must be the only member of a RefSCC as it has no references. 1463 // Validate these properties first. 1464 assert(C.size() == 1 && "Dead functions must be in a singular SCC"); 1465 assert(RC.size() == 1 && "Dead functions must be in a singular RefSCC"); 1466 assert(RC.Parents.empty() && "Cannot have parents of a dead RefSCC!"); 1467 1468 // Now remove this RefSCC from any parents sets and the leaf list. 1469 for (Edge &E : N) 1470 if (Node *TargetN = E.getNode()) 1471 if (RefSCC *TargetRC = lookupRefSCC(*TargetN)) 1472 TargetRC->Parents.erase(&RC); 1473 // FIXME: This is a linear operation which could become hot and benefit from 1474 // an index map. 1475 auto LRI = find(LeafRefSCCs, &RC); 1476 if (LRI != LeafRefSCCs.end()) 1477 LeafRefSCCs.erase(LRI); 1478 1479 auto RCIndexI = RefSCCIndices.find(&RC); 1480 int RCIndex = RCIndexI->second; 1481 PostOrderRefSCCs.erase(PostOrderRefSCCs.begin() + RCIndex); 1482 RefSCCIndices.erase(RCIndexI); 1483 for (int i = RCIndex, Size = PostOrderRefSCCs.size(); i < Size; ++i) 1484 RefSCCIndices[PostOrderRefSCCs[i]] = i; 1485 1486 // Finally clear out all the data structures from the node down through the 1487 // components. 1488 N.clear(); 1489 C.clear(); 1490 RC.clear(); 1491 1492 // Nothing to delete as all the objects are allocated in stable bump pointer 1493 // allocators. 1494 } 1495 1496 LazyCallGraph::Node &LazyCallGraph::insertInto(Function &F, Node *&MappedN) { 1497 return *new (MappedN = BPA.Allocate()) Node(*this, F); 1498 } 1499 1500 void LazyCallGraph::updateGraphPtrs() { 1501 // Process all nodes updating the graph pointers. 1502 { 1503 SmallVector<Node *, 16> Worklist; 1504 for (Edge &E : EntryEdges) 1505 if (Node *EntryN = E.getNode()) 1506 Worklist.push_back(EntryN); 1507 1508 while (!Worklist.empty()) { 1509 Node *N = Worklist.pop_back_val(); 1510 N->G = this; 1511 for (Edge &E : N->Edges) 1512 if (Node *TargetN = E.getNode()) 1513 Worklist.push_back(TargetN); 1514 } 1515 } 1516 1517 // Process all SCCs updating the graph pointers. 1518 { 1519 SmallVector<RefSCC *, 16> Worklist(LeafRefSCCs.begin(), LeafRefSCCs.end()); 1520 1521 while (!Worklist.empty()) { 1522 RefSCC &C = *Worklist.pop_back_val(); 1523 C.G = this; 1524 for (RefSCC &ParentC : C.parents()) 1525 Worklist.push_back(&ParentC); 1526 } 1527 } 1528 } 1529 1530 /// Build the internal SCCs for a RefSCC from a sequence of nodes. 1531 /// 1532 /// Appends the SCCs to the provided vector and updates the map with their 1533 /// indices. Both the vector and map must be empty when passed into this 1534 /// routine. 1535 void LazyCallGraph::buildSCCs(RefSCC &RC, node_stack_range Nodes) { 1536 assert(RC.SCCs.empty() && "Already built SCCs!"); 1537 assert(RC.SCCIndices.empty() && "Already mapped SCC indices!"); 1538 1539 for (Node *N : Nodes) { 1540 assert(N->LowLink >= (*Nodes.begin())->LowLink && 1541 "We cannot have a low link in an SCC lower than its root on the " 1542 "stack!"); 1543 1544 // This node will go into the next RefSCC, clear out its DFS and low link 1545 // as we scan. 1546 N->DFSNumber = N->LowLink = 0; 1547 } 1548 1549 // Each RefSCC contains a DAG of the call SCCs. To build these, we do 1550 // a direct walk of the call edges using Tarjan's algorithm. We reuse the 1551 // internal storage as we won't need it for the outer graph's DFS any longer. 1552 1553 SmallVector<std::pair<Node *, call_edge_iterator>, 16> DFSStack; 1554 SmallVector<Node *, 16> PendingSCCStack; 1555 1556 // Scan down the stack and DFS across the call edges. 1557 for (Node *RootN : Nodes) { 1558 assert(DFSStack.empty() && 1559 "Cannot begin a new root with a non-empty DFS stack!"); 1560 assert(PendingSCCStack.empty() && 1561 "Cannot begin a new root with pending nodes for an SCC!"); 1562 1563 // Skip any nodes we've already reached in the DFS. 1564 if (RootN->DFSNumber != 0) { 1565 assert(RootN->DFSNumber == -1 && 1566 "Shouldn't have any mid-DFS root nodes!"); 1567 continue; 1568 } 1569 1570 RootN->DFSNumber = RootN->LowLink = 1; 1571 int NextDFSNumber = 2; 1572 1573 DFSStack.push_back({RootN, RootN->call_begin()}); 1574 do { 1575 Node *N; 1576 call_edge_iterator I; 1577 std::tie(N, I) = DFSStack.pop_back_val(); 1578 auto E = N->call_end(); 1579 while (I != E) { 1580 Node &ChildN = *I->getNode(); 1581 if (ChildN.DFSNumber == 0) { 1582 // We haven't yet visited this child, so descend, pushing the current 1583 // node onto the stack. 1584 DFSStack.push_back({N, I}); 1585 1586 assert(!lookupSCC(ChildN) && 1587 "Found a node with 0 DFS number but already in an SCC!"); 1588 ChildN.DFSNumber = ChildN.LowLink = NextDFSNumber++; 1589 N = &ChildN; 1590 I = N->call_begin(); 1591 E = N->call_end(); 1592 continue; 1593 } 1594 1595 // If the child has already been added to some child component, it 1596 // couldn't impact the low-link of this parent because it isn't 1597 // connected, and thus its low-link isn't relevant so skip it. 1598 if (ChildN.DFSNumber == -1) { 1599 ++I; 1600 continue; 1601 } 1602 1603 // Track the lowest linked child as the lowest link for this node. 1604 assert(ChildN.LowLink > 0 && "Must have a positive low-link number!"); 1605 if (ChildN.LowLink < N->LowLink) 1606 N->LowLink = ChildN.LowLink; 1607 1608 // Move to the next edge. 1609 ++I; 1610 } 1611 1612 // We've finished processing N and its descendents, put it on our pending 1613 // SCC stack to eventually get merged into an SCC of nodes. 1614 PendingSCCStack.push_back(N); 1615 1616 // If this node is linked to some lower entry, continue walking up the 1617 // stack. 1618 if (N->LowLink != N->DFSNumber) 1619 continue; 1620 1621 // Otherwise, we've completed an SCC. Append it to our post order list of 1622 // SCCs. 1623 int RootDFSNumber = N->DFSNumber; 1624 // Find the range of the node stack by walking down until we pass the 1625 // root DFS number. 1626 auto SCCNodes = make_range( 1627 PendingSCCStack.rbegin(), 1628 find_if(reverse(PendingSCCStack), [RootDFSNumber](const Node *N) { 1629 return N->DFSNumber < RootDFSNumber; 1630 })); 1631 // Form a new SCC out of these nodes and then clear them off our pending 1632 // stack. 1633 RC.SCCs.push_back(createSCC(RC, SCCNodes)); 1634 for (Node &N : *RC.SCCs.back()) { 1635 N.DFSNumber = N.LowLink = -1; 1636 SCCMap[&N] = RC.SCCs.back(); 1637 } 1638 PendingSCCStack.erase(SCCNodes.end().base(), PendingSCCStack.end()); 1639 } while (!DFSStack.empty()); 1640 } 1641 1642 // Wire up the SCC indices. 1643 for (int i = 0, Size = RC.SCCs.size(); i < Size; ++i) 1644 RC.SCCIndices[RC.SCCs[i]] = i; 1645 } 1646 1647 // FIXME: We should move callers of this to embed the parent linking and leaf 1648 // tracking into their DFS in order to remove a full walk of all edges. 1649 void LazyCallGraph::connectRefSCC(RefSCC &RC) { 1650 // Walk all edges in the RefSCC (this remains linear as we only do this once 1651 // when we build the RefSCC) to connect it to the parent sets of its 1652 // children. 1653 bool IsLeaf = true; 1654 for (SCC &C : RC) 1655 for (Node &N : C) 1656 for (Edge &E : N) { 1657 assert(E.getNode() && 1658 "Cannot have a missing node in a visited part of the graph!"); 1659 RefSCC &ChildRC = *lookupRefSCC(*E.getNode()); 1660 if (&ChildRC == &RC) 1661 continue; 1662 ChildRC.Parents.insert(&RC); 1663 IsLeaf = false; 1664 } 1665 1666 // For the SCCs where we find no child SCCs, add them to the leaf list. 1667 if (IsLeaf) 1668 LeafRefSCCs.push_back(&RC); 1669 } 1670 1671 bool LazyCallGraph::buildNextRefSCCInPostOrder() { 1672 if (DFSStack.empty()) { 1673 Node *N; 1674 do { 1675 // If we've handled all candidate entry nodes to the SCC forest, we're 1676 // done. 1677 if (RefSCCEntryNodes.empty()) 1678 return false; 1679 1680 N = &get(*RefSCCEntryNodes.pop_back_val()); 1681 } while (N->DFSNumber != 0); 1682 1683 // Found a new root, begin the DFS here. 1684 N->LowLink = N->DFSNumber = 1; 1685 NextDFSNumber = 2; 1686 DFSStack.push_back({N, N->begin()}); 1687 } 1688 1689 for (;;) { 1690 Node *N; 1691 edge_iterator I; 1692 std::tie(N, I) = DFSStack.pop_back_val(); 1693 1694 assert(N->DFSNumber > 0 && "We should always assign a DFS number " 1695 "before placing a node onto the stack."); 1696 1697 auto E = N->end(); 1698 while (I != E) { 1699 Node &ChildN = I->getNode(*this); 1700 if (ChildN.DFSNumber == 0) { 1701 // We haven't yet visited this child, so descend, pushing the current 1702 // node onto the stack. 1703 DFSStack.push_back({N, N->begin()}); 1704 1705 assert(!SCCMap.count(&ChildN) && 1706 "Found a node with 0 DFS number but already in an SCC!"); 1707 ChildN.LowLink = ChildN.DFSNumber = NextDFSNumber++; 1708 N = &ChildN; 1709 I = N->begin(); 1710 E = N->end(); 1711 continue; 1712 } 1713 1714 // If the child has already been added to some child component, it 1715 // couldn't impact the low-link of this parent because it isn't 1716 // connected, and thus its low-link isn't relevant so skip it. 1717 if (ChildN.DFSNumber == -1) { 1718 ++I; 1719 continue; 1720 } 1721 1722 // Track the lowest linked child as the lowest link for this node. 1723 assert(ChildN.LowLink > 0 && "Must have a positive low-link number!"); 1724 if (ChildN.LowLink < N->LowLink) 1725 N->LowLink = ChildN.LowLink; 1726 1727 // Move to the next edge. 1728 ++I; 1729 } 1730 1731 // We've finished processing N and its descendents, put it on our pending 1732 // SCC stack to eventually get merged into an SCC of nodes. 1733 PendingRefSCCStack.push_back(N); 1734 1735 // If this node is linked to some lower entry, continue walking up the 1736 // stack. 1737 if (N->LowLink != N->DFSNumber) { 1738 assert(!DFSStack.empty() && 1739 "We never found a viable root for an SCC to pop off!"); 1740 continue; 1741 } 1742 1743 // Otherwise, form a new RefSCC from the top of the pending node stack. 1744 int RootDFSNumber = N->DFSNumber; 1745 // Find the range of the node stack by walking down until we pass the 1746 // root DFS number. 1747 auto RefSCCNodes = node_stack_range( 1748 PendingRefSCCStack.rbegin(), 1749 find_if(reverse(PendingRefSCCStack), [RootDFSNumber](const Node *N) { 1750 return N->DFSNumber < RootDFSNumber; 1751 })); 1752 // Form a new RefSCC out of these nodes and then clear them off our pending 1753 // stack. 1754 RefSCC *NewRC = createRefSCC(*this); 1755 buildSCCs(*NewRC, RefSCCNodes); 1756 connectRefSCC(*NewRC); 1757 PendingRefSCCStack.erase(RefSCCNodes.end().base(), 1758 PendingRefSCCStack.end()); 1759 1760 // Push the new node into the postorder list and return true indicating we 1761 // successfully grew the postorder sequence by one. 1762 bool Inserted = 1763 RefSCCIndices.insert({NewRC, PostOrderRefSCCs.size()}).second; 1764 (void)Inserted; 1765 assert(Inserted && "Cannot already have this RefSCC in the index map!"); 1766 PostOrderRefSCCs.push_back(NewRC); 1767 return true; 1768 } 1769 } 1770 1771 char LazyCallGraphAnalysis::PassID; 1772 1773 LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {} 1774 1775 static void printNode(raw_ostream &OS, LazyCallGraph::Node &N) { 1776 OS << " Edges in function: " << N.getFunction().getName() << "\n"; 1777 for (const LazyCallGraph::Edge &E : N) 1778 OS << " " << (E.isCall() ? "call" : "ref ") << " -> " 1779 << E.getFunction().getName() << "\n"; 1780 1781 OS << "\n"; 1782 } 1783 1784 static void printSCC(raw_ostream &OS, LazyCallGraph::SCC &C) { 1785 ptrdiff_t Size = std::distance(C.begin(), C.end()); 1786 OS << " SCC with " << Size << " functions:\n"; 1787 1788 for (LazyCallGraph::Node &N : C) 1789 OS << " " << N.getFunction().getName() << "\n"; 1790 } 1791 1792 static void printRefSCC(raw_ostream &OS, LazyCallGraph::RefSCC &C) { 1793 ptrdiff_t Size = std::distance(C.begin(), C.end()); 1794 OS << " RefSCC with " << Size << " call SCCs:\n"; 1795 1796 for (LazyCallGraph::SCC &InnerC : C) 1797 printSCC(OS, InnerC); 1798 1799 OS << "\n"; 1800 } 1801 1802 PreservedAnalyses LazyCallGraphPrinterPass::run(Module &M, 1803 ModuleAnalysisManager &AM) { 1804 LazyCallGraph &G = AM.getResult<LazyCallGraphAnalysis>(M); 1805 1806 OS << "Printing the call graph for module: " << M.getModuleIdentifier() 1807 << "\n\n"; 1808 1809 for (Function &F : M) 1810 printNode(OS, G.get(F)); 1811 1812 for (LazyCallGraph::RefSCC &C : G.postorder_ref_sccs()) 1813 printRefSCC(OS, C); 1814 1815 return PreservedAnalyses::all(); 1816 } 1817 1818 LazyCallGraphDOTPrinterPass::LazyCallGraphDOTPrinterPass(raw_ostream &OS) 1819 : OS(OS) {} 1820 1821 static void printNodeDOT(raw_ostream &OS, LazyCallGraph::Node &N) { 1822 std::string Name = "\"" + DOT::EscapeString(N.getFunction().getName()) + "\""; 1823 1824 for (const LazyCallGraph::Edge &E : N) { 1825 OS << " " << Name << " -> \"" 1826 << DOT::EscapeString(E.getFunction().getName()) << "\""; 1827 if (!E.isCall()) // It is a ref edge. 1828 OS << " [style=dashed,label=\"ref\"]"; 1829 OS << ";\n"; 1830 } 1831 1832 OS << "\n"; 1833 } 1834 1835 PreservedAnalyses LazyCallGraphDOTPrinterPass::run(Module &M, 1836 ModuleAnalysisManager &AM) { 1837 LazyCallGraph &G = AM.getResult<LazyCallGraphAnalysis>(M); 1838 1839 OS << "digraph \"" << DOT::EscapeString(M.getModuleIdentifier()) << "\" {\n"; 1840 1841 for (Function &F : M) 1842 printNodeDOT(OS, G.get(F)); 1843 1844 OS << "}\n"; 1845 1846 return PreservedAnalyses::all(); 1847 } 1848