Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 1 | //===- LazyCallGraph.h - Analysis of a Module's call graph ------*- C++ -*-===// | 
| 2 | // | ||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| 4 | // See https://llvm.org/LICENSE.txt for license information. | ||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| 6 | // | ||
| 7 | //===----------------------------------------------------------------------===// | ||
| 8 | /// \file | ||
| 9 | /// | ||
| 10 | /// Implements a lazy call graph analysis and related passes for the new pass | ||
| 11 | /// manager. | ||
| 12 | /// | ||
| 13 | /// NB: This is *not* a traditional call graph! It is a graph which models both | ||
| 14 | /// the current calls and potential calls. As a consequence there are many | ||
| 15 | /// edges in this call graph that do not correspond to a 'call' or 'invoke' | ||
| 16 | /// instruction. | ||
| 17 | /// | ||
| 18 | /// The primary use cases of this graph analysis is to facilitate iterating | ||
| 19 | /// across the functions of a module in ways that ensure all callees are | ||
| 20 | /// visited prior to a caller (given any SCC constraints), or vice versa. As | ||
| 21 | /// such is it particularly well suited to organizing CGSCC optimizations such | ||
| 22 | /// as inlining, outlining, argument promotion, etc. That is its primary use | ||
| 23 | /// case and motivates the design. It may not be appropriate for other | ||
| 24 | /// purposes. The use graph of functions or some other conservative analysis of | ||
| 25 | /// call instructions may be interesting for optimizations and subsequent | ||
| 26 | /// analyses which don't work in the context of an overly specified | ||
| 27 | /// potential-call-edge graph. | ||
| 28 | /// | ||
| 29 | /// To understand the specific rules and nature of this call graph analysis, | ||
| 30 | /// see the documentation of the \c LazyCallGraph below. | ||
| 31 | /// | ||
| 32 | //===----------------------------------------------------------------------===// | ||
| 33 | |||
| 34 | #ifndef LLVM_ANALYSIS_LAZYCALLGRAPH_H | ||
| 35 | #define LLVM_ANALYSIS_LAZYCALLGRAPH_H | ||
| 36 | |||
| 37 | #include "llvm/ADT/ArrayRef.h" | ||
| 38 | #include "llvm/ADT/DenseMap.h" | ||
| 39 | #include "llvm/ADT/PointerIntPair.h" | ||
| 40 | #include "llvm/ADT/SetVector.h" | ||
| 41 | #include "llvm/ADT/SmallVector.h" | ||
| 42 | #include "llvm/ADT/StringRef.h" | ||
| 43 | #include "llvm/ADT/iterator.h" | ||
| 44 | #include "llvm/ADT/iterator_range.h" | ||
| 45 | #include "llvm/Analysis/TargetLibraryInfo.h" | ||
| 46 | #include "llvm/IR/PassManager.h" | ||
| 47 | #include "llvm/Support/Allocator.h" | ||
| 48 | #include "llvm/Support/raw_ostream.h" | ||
| 49 | #include <cassert> | ||
| 50 | #include <iterator> | ||
| 51 | #include <optional> | ||
| 52 | #include <string> | ||
| 53 | #include <utility> | ||
| 54 | |||
| 55 | namespace llvm { | ||
| 56 | |||
| 57 | class Constant; | ||
| 58 | class Function; | ||
| 59 | template <class GraphType> struct GraphTraits; | ||
| 60 | class Module; | ||
| 61 | class TargetLibraryInfo; | ||
| 62 | class Value; | ||
| 63 | |||
| 64 | /// A lazily constructed view of the call graph of a module. | ||
| 65 | /// | ||
| 66 | /// With the edges of this graph, the motivating constraint that we are | ||
| 67 | /// attempting to maintain is that function-local optimization, CGSCC-local | ||
| 68 | /// optimizations, and optimizations transforming a pair of functions connected | ||
| 69 | /// by an edge in the graph, do not invalidate a bottom-up traversal of the SCC | ||
| 70 | /// DAG. That is, no optimizations will delete, remove, or add an edge such | ||
| 71 | /// that functions already visited in a bottom-up order of the SCC DAG are no | ||
| 72 | /// longer valid to have visited, or such that functions not yet visited in | ||
| 73 | /// a bottom-up order of the SCC DAG are not required to have already been | ||
| 74 | /// visited. | ||
| 75 | /// | ||
| 76 | /// Within this constraint, the desire is to minimize the merge points of the | ||
| 77 | /// SCC DAG. The greater the fanout of the SCC DAG and the fewer merge points | ||
| 78 | /// in the SCC DAG, the more independence there is in optimizing within it. | ||
| 79 | /// There is a strong desire to enable parallelization of optimizations over | ||
| 80 | /// the call graph, and both limited fanout and merge points will (artificially | ||
| 81 | /// in some cases) limit the scaling of such an effort. | ||
| 82 | /// | ||
| 83 | /// To this end, graph represents both direct and any potential resolution to | ||
| 84 | /// an indirect call edge. Another way to think about it is that it represents | ||
| 85 | /// both the direct call edges and any direct call edges that might be formed | ||
| 86 | /// through static optimizations. Specifically, it considers taking the address | ||
| 87 | /// of a function to be an edge in the call graph because this might be | ||
| 88 | /// forwarded to become a direct call by some subsequent function-local | ||
| 89 | /// optimization. The result is that the graph closely follows the use-def | ||
| 90 | /// edges for functions. Walking "up" the graph can be done by looking at all | ||
| 91 | /// of the uses of a function. | ||
| 92 | /// | ||
| 93 | /// The roots of the call graph are the external functions and functions | ||
| 94 | /// escaped into global variables. Those functions can be called from outside | ||
| 95 | /// of the module or via unknowable means in the IR -- we may not be able to | ||
| 96 | /// form even a potential call edge from a function body which may dynamically | ||
| 97 | /// load the function and call it. | ||
| 98 | /// | ||
| 99 | /// This analysis still requires updates to remain valid after optimizations | ||
| 100 | /// which could potentially change the set of potential callees. The | ||
| 101 | /// constraints it operates under only make the traversal order remain valid. | ||
| 102 | /// | ||
| 103 | /// The entire analysis must be re-computed if full interprocedural | ||
| 104 | /// optimizations run at any point. For example, globalopt completely | ||
| 105 | /// invalidates the information in this analysis. | ||
| 106 | /// | ||
| 107 | /// FIXME: This class is named LazyCallGraph in a lame attempt to distinguish | ||
| 108 | /// it from the existing CallGraph. At some point, it is expected that this | ||
| 109 | /// will be the only call graph and it will be renamed accordingly. | ||
| 110 | class LazyCallGraph { | ||
| 111 | public: | ||
| 112 | class Node; | ||
| 113 | class EdgeSequence; | ||
| 114 | class SCC; | ||
| 115 | class RefSCC; | ||
| 116 | |||
| 117 |   /// A class used to represent edges in the call graph. | ||
| 118 |   /// | ||
| 119 |   /// The lazy call graph models both *call* edges and *reference* edges. Call | ||
| 120 |   /// edges are much what you would expect, and exist when there is a 'call' or | ||
| 121 |   /// 'invoke' instruction of some function. Reference edges are also tracked | ||
| 122 |   /// along side these, and exist whenever any instruction (transitively | ||
| 123 |   /// through its operands) references a function. All call edges are | ||
| 124 |   /// inherently reference edges, and so the reference graph forms a superset | ||
| 125 |   /// of the formal call graph. | ||
| 126 |   /// | ||
| 127 |   /// All of these forms of edges are fundamentally represented as outgoing | ||
| 128 |   /// edges. The edges are stored in the source node and point at the target | ||
| 129 |   /// node. This allows the edge structure itself to be a very compact data | ||
| 130 |   /// structure: essentially a tagged pointer. | ||
| 131 | class Edge { | ||
| 132 | public: | ||
| 133 |     /// The kind of edge in the graph. | ||
| 134 | enum Kind : bool { Ref = false, Call = true }; | ||
| 135 | |||
| 136 | Edge(); | ||
| 137 | explicit Edge(Node &N, Kind K); | ||
| 138 | |||
| 139 |     /// Test whether the edge is null. | ||
| 140 |     /// | ||
| 141 |     /// This happens when an edge has been deleted. We leave the edge objects | ||
| 142 |     /// around but clear them. | ||
| 143 | explicit operator bool() const; | ||
| 144 | |||
| 145 |     /// Returns the \c Kind of the edge. | ||
| 146 | Kind getKind() const; | ||
| 147 | |||
| 148 |     /// Test whether the edge represents a direct call to a function. | ||
| 149 |     /// | ||
| 150 |     /// This requires that the edge is not null. | ||
| 151 | bool isCall() const; | ||
| 152 | |||
| 153 |     /// Get the call graph node referenced by this edge. | ||
| 154 |     /// | ||
| 155 |     /// This requires that the edge is not null. | ||
| 156 | Node &getNode() const; | ||
| 157 | |||
| 158 |     /// Get the function referenced by this edge. | ||
| 159 |     /// | ||
| 160 |     /// This requires that the edge is not null. | ||
| 161 | Function &getFunction() const; | ||
| 162 | |||
| 163 | private: | ||
| 164 | friend class LazyCallGraph::EdgeSequence; | ||
| 165 | friend class LazyCallGraph::RefSCC; | ||
| 166 | |||
| 167 | PointerIntPair<Node *, 1, Kind> Value; | ||
| 168 | |||
| 169 | void setKind(Kind K) { Value.setInt(K); } | ||
| 170 | }; | ||
| 171 | |||
| 172 |   /// The edge sequence object. | ||
| 173 |   /// | ||
| 174 |   /// This typically exists entirely within the node but is exposed as | ||
| 175 |   /// a separate type because a node doesn't initially have edges. An explicit | ||
| 176 |   /// population step is required to produce this sequence at first and it is | ||
| 177 |   /// then cached in the node. It is also used to represent edges entering the | ||
| 178 |   /// graph from outside the module to model the graph's roots. | ||
| 179 |   /// | ||
| 180 |   /// The sequence itself both iterable and indexable. The indexes remain | ||
| 181 |   /// stable even as the sequence mutates (including removal). | ||
| 182 | class EdgeSequence { | ||
| 183 | friend class LazyCallGraph; | ||
| 184 | friend class LazyCallGraph::Node; | ||
| 185 | friend class LazyCallGraph::RefSCC; | ||
| 186 | |||
| 187 | using VectorT = SmallVector<Edge, 4>; | ||
| 188 | using VectorImplT = SmallVectorImpl<Edge>; | ||
| 189 | |||
| 190 | public: | ||
| 191 |     /// An iterator used for the edges to both entry nodes and child nodes. | ||
| 192 |     class iterator | ||
| 193 | : public iterator_adaptor_base<iterator, VectorImplT::iterator, | ||
| 194 | std::forward_iterator_tag> { | ||
| 195 | friend class LazyCallGraph; | ||
| 196 | friend class LazyCallGraph::Node; | ||
| 197 | |||
| 198 | VectorImplT::iterator E; | ||
| 199 | |||
| 200 |       // Build the iterator for a specific position in the edge list. | ||
| 201 | iterator(VectorImplT::iterator BaseI, VectorImplT::iterator E) | ||
| 202 | : iterator_adaptor_base(BaseI), E(E) { | ||
| 203 | while (I != E && !*I) | ||
| 204 | ++I; | ||
| 205 |       } | ||
| 206 | |||
| 207 | public: | ||
| 208 | iterator() = default; | ||
| 209 | |||
| 210 | using iterator_adaptor_base::operator++; | ||
| 211 | iterator &operator++() { | ||
| 212 | do { | ||
| 213 | ++I; | ||
| 214 | } while (I != E && !*I); | ||
| 215 | return *this; | ||
| 216 |       } | ||
| 217 | }; | ||
| 218 | |||
| 219 |     /// An iterator over specifically call edges. | ||
| 220 |     /// | ||
| 221 |     /// This has the same iteration properties as the \c iterator, but | ||
| 222 |     /// restricts itself to edges which represent actual calls. | ||
| 223 |     class call_iterator | ||
| 224 | : public iterator_adaptor_base<call_iterator, VectorImplT::iterator, | ||
| 225 | std::forward_iterator_tag> { | ||
| 226 | friend class LazyCallGraph; | ||
| 227 | friend class LazyCallGraph::Node; | ||
| 228 | |||
| 229 | VectorImplT::iterator E; | ||
| 230 | |||
| 231 |       /// Advance the iterator to the next valid, call edge. | ||
| 232 | void advanceToNextEdge() { | ||
| 233 | while (I != E && (!*I || !I->isCall())) | ||
| 234 | ++I; | ||
| 235 |       } | ||
| 236 | |||
| 237 |       // Build the iterator for a specific position in the edge list. | ||
| 238 | call_iterator(VectorImplT::iterator BaseI, VectorImplT::iterator E) | ||
| 239 | : iterator_adaptor_base(BaseI), E(E) { | ||
| 240 | advanceToNextEdge(); | ||
| 241 |       } | ||
| 242 | |||
| 243 | public: | ||
| 244 | call_iterator() = default; | ||
| 245 | |||
| 246 | using iterator_adaptor_base::operator++; | ||
| 247 | call_iterator &operator++() { | ||
| 248 | ++I; | ||
| 249 | advanceToNextEdge(); | ||
| 250 | return *this; | ||
| 251 |       } | ||
| 252 | }; | ||
| 253 | |||
| 254 | iterator begin() { return iterator(Edges.begin(), Edges.end()); } | ||
| 255 | iterator end() { return iterator(Edges.end(), Edges.end()); } | ||
| 256 | |||
| 257 | Edge &operator[](Node &N) { | ||
| 258 | assert(EdgeIndexMap.find(&N) != EdgeIndexMap.end() && "No such edge!"); | ||
| 259 | auto &E = Edges[EdgeIndexMap.find(&N)->second]; | ||
| 260 | assert(E && "Dead or null edge!"); | ||
| 261 | return E; | ||
| 262 |     } | ||
| 263 | |||
| 264 | Edge *lookup(Node &N) { | ||
| 265 | auto EI = EdgeIndexMap.find(&N); | ||
| 266 | if (EI == EdgeIndexMap.end()) | ||
| 267 | return nullptr; | ||
| 268 | auto &E = Edges[EI->second]; | ||
| 269 | return E ? &E : nullptr; | ||
| 270 |     } | ||
| 271 | |||
| 272 | call_iterator call_begin() { | ||
| 273 | return call_iterator(Edges.begin(), Edges.end()); | ||
| 274 |     } | ||
| 275 | call_iterator call_end() { return call_iterator(Edges.end(), Edges.end()); } | ||
| 276 | |||
| 277 | iterator_range<call_iterator> calls() { | ||
| 278 | return make_range(call_begin(), call_end()); | ||
| 279 |     } | ||
| 280 | |||
| 281 | bool empty() { | ||
| 282 | for (auto &E : Edges) | ||
| 283 | if (E) | ||
| 284 | return false; | ||
| 285 | |||
| 286 | return true; | ||
| 287 |     } | ||
| 288 | |||
| 289 | private: | ||
| 290 |     VectorT Edges; | ||
| 291 | DenseMap<Node *, int> EdgeIndexMap; | ||
| 292 | |||
| 293 | EdgeSequence() = default; | ||
| 294 | |||
| 295 |     /// Internal helper to insert an edge to a node. | ||
| 296 | void insertEdgeInternal(Node &ChildN, Edge::Kind EK); | ||
| 297 | |||
| 298 |     /// Internal helper to change an edge kind. | ||
| 299 | void setEdgeKind(Node &ChildN, Edge::Kind EK); | ||
| 300 | |||
| 301 |     /// Internal helper to remove the edge to the given function. | ||
| 302 | bool removeEdgeInternal(Node &ChildN); | ||
| 303 | }; | ||
| 304 | |||
| 305 |   /// A node in the call graph. | ||
| 306 |   /// | ||
| 307 |   /// This represents a single node. Its primary roles are to cache the list of | ||
| 308 |   /// callees, de-duplicate and provide fast testing of whether a function is a | ||
| 309 |   /// callee, and facilitate iteration of child nodes in the graph. | ||
| 310 |   /// | ||
| 311 |   /// The node works much like an optional in order to lazily populate the | ||
| 312 |   /// edges of each node. Until populated, there are no edges. Once populated, | ||
| 313 |   /// you can access the edges by dereferencing the node or using the `->` | ||
| 314 |   /// operator as if the node was an `std::optional<EdgeSequence>`. | ||
| 315 | class Node { | ||
| 316 | friend class LazyCallGraph; | ||
| 317 | friend class LazyCallGraph::RefSCC; | ||
| 318 | |||
| 319 | public: | ||
| 320 | LazyCallGraph &getGraph() const { return *G; } | ||
| 321 | |||
| 322 | Function &getFunction() const { return *F; } | ||
| 323 | |||
| 324 | StringRef getName() const { return F->getName(); } | ||
| 325 | |||
| 326 |     /// Equality is defined as address equality. | ||
| 327 | bool operator==(const Node &N) const { return this == &N; } | ||
| 328 | bool operator!=(const Node &N) const { return !operator==(N); } | ||
| 329 | |||
| 330 |     /// Tests whether the node has been populated with edges. | ||
| 331 | bool isPopulated() const { return Edges.has_value(); } | ||
| 332 | |||
| 333 |     /// Tests whether this is actually a dead node and no longer valid. | ||
| 334 |     /// | ||
| 335 |     /// Users rarely interact with nodes in this state and other methods are | ||
| 336 |     /// invalid. This is used to model a node in an edge list where the | ||
| 337 |     /// function has been completely removed. | ||
| 338 | bool isDead() const { | ||
| 339 | assert(!G == !F && | ||
| 340 | "Both graph and function pointers should be null or non-null."); | ||
| 341 | return !G; | ||
| 342 |     } | ||
| 343 | |||
| 344 |     // We allow accessing the edges by dereferencing or using the arrow | ||
| 345 |     // operator, essentially wrapping the internal optional. | ||
| 346 | EdgeSequence &operator*() const { | ||
| 347 |       // Rip const off because the node itself isn't changing here. | ||
| 348 | return const_cast<EdgeSequence &>(*Edges); | ||
| 349 |     } | ||
| 350 | EdgeSequence *operator->() const { return &**this; } | ||
| 351 | |||
| 352 |     /// Populate the edges of this node if necessary. | ||
| 353 |     /// | ||
| 354 |     /// The first time this is called it will populate the edges for this node | ||
| 355 |     /// in the graph. It does this by scanning the underlying function, so once | ||
| 356 |     /// this is done, any changes to that function must be explicitly reflected | ||
| 357 |     /// in updates to the graph. | ||
| 358 |     /// | ||
| 359 |     /// \returns the populated \c EdgeSequence to simplify walking it. | ||
| 360 |     /// | ||
| 361 |     /// This will not update or re-scan anything if called repeatedly. Instead, | ||
| 362 |     /// the edge sequence is cached and returned immediately on subsequent | ||
| 363 |     /// calls. | ||
| 364 | EdgeSequence &populate() { | ||
| 365 | if (Edges) | ||
| 366 | return *Edges; | ||
| 367 | |||
| 368 | return populateSlow(); | ||
| 369 |     } | ||
| 370 | |||
| 371 | private: | ||
| 372 | LazyCallGraph *G; | ||
| 373 | Function *F; | ||
| 374 | |||
| 375 |     // We provide for the DFS numbering and Tarjan walk lowlink numbers to be | ||
| 376 |     // stored directly within the node. These are both '-1' when nodes are part | ||
| 377 |     // of an SCC (or RefSCC), or '0' when not yet reached in a DFS walk. | ||
| 378 | int DFSNumber = 0; | ||
| 379 | int LowLink = 0; | ||
| 380 | |||
| 381 | std::optional<EdgeSequence> Edges; | ||
| 382 | |||
| 383 |     /// Basic constructor implements the scanning of F into Edges and | ||
| 384 |     /// EdgeIndexMap. | ||
| 385 | Node(LazyCallGraph &G, Function &F) : G(&G), F(&F) {} | ||
| 386 | |||
| 387 |     /// Implementation of the scan when populating. | ||
| 388 | EdgeSequence &populateSlow(); | ||
| 389 | |||
| 390 |     /// Internal helper to directly replace the function with a new one. | ||
| 391 |     /// | ||
| 392 |     /// This is used to facilitate transformations which need to replace the | ||
| 393 |     /// formal Function object but directly move the body and users from one to | ||
| 394 |     /// the other. | ||
| 395 | void replaceFunction(Function &NewF); | ||
| 396 | |||
| 397 | void clear() { Edges.reset(); } | ||
| 398 | |||
| 399 |     /// Print the name of this node's function. | ||
| 400 | friend raw_ostream &operator<<(raw_ostream &OS, const Node &N) { | ||
| 401 | return OS << N.F->getName(); | ||
| 402 |     } | ||
| 403 | |||
| 404 |     /// Dump the name of this node's function to stderr. | ||
| 405 | void dump() const; | ||
| 406 | }; | ||
| 407 | |||
| 408 |   /// An SCC of the call graph. | ||
| 409 |   /// | ||
| 410 |   /// This represents a Strongly Connected Component of the direct call graph | ||
| 411 |   /// -- ignoring indirect calls and function references. It stores this as | ||
| 412 |   /// a collection of call graph nodes. While the order of nodes in the SCC is | ||
| 413 |   /// stable, it is not any particular order. | ||
| 414 |   /// | ||
| 415 |   /// The SCCs are nested within a \c RefSCC, see below for details about that | ||
| 416 |   /// outer structure. SCCs do not support mutation of the call graph, that | ||
| 417 |   /// must be done through the containing \c RefSCC in order to fully reason | ||
| 418 |   /// about the ordering and connections of the graph. | ||
| 419 | class LLVM_EXTERNAL_VISIBILITY SCC { | ||
| 420 | friend class LazyCallGraph; | ||
| 421 | friend class LazyCallGraph::Node; | ||
| 422 | |||
| 423 | RefSCC *OuterRefSCC; | ||
| 424 | SmallVector<Node *, 1> Nodes; | ||
| 425 | |||
| 426 | template <typename NodeRangeT> | ||
| 427 | SCC(RefSCC &OuterRefSCC, NodeRangeT &&Nodes) | ||
| 428 | : OuterRefSCC(&OuterRefSCC), Nodes(std::forward<NodeRangeT>(Nodes)) {} | ||
| 429 | |||
| 430 | void clear() { | ||
| 431 | OuterRefSCC = nullptr; | ||
| 432 | Nodes.clear(); | ||
| 433 |     } | ||
| 434 | |||
| 435 |     /// Print a short description useful for debugging or logging. | ||
| 436 |     /// | ||
| 437 |     /// We print the function names in the SCC wrapped in '()'s and skipping | ||
| 438 |     /// the middle functions if there are a large number. | ||
| 439 |     // | ||
| 440 |     // Note: this is defined inline to dodge issues with GCC's interpretation | ||
| 441 |     // of enclosing namespaces for friend function declarations. | ||
| 442 | friend raw_ostream &operator<<(raw_ostream &OS, const SCC &C) { | ||
| 443 | OS << '('; | ||
| 444 | int I = 0; | ||
| 445 | for (LazyCallGraph::Node &N : C) { | ||
| 446 | if (I > 0) | ||
| 447 | OS << ", "; | ||
| 448 |         // Elide the inner elements if there are too many. | ||
| 449 | if (I > 8) { | ||
| 450 | OS << "..., " << *C.Nodes.back(); | ||
| 451 | break; | ||
| 452 |         } | ||
| 453 | OS << N; | ||
| 454 | ++I; | ||
| 455 |       } | ||
| 456 | OS << ')'; | ||
| 457 | return OS; | ||
| 458 |     } | ||
| 459 | |||
| 460 |     /// Dump a short description of this SCC to stderr. | ||
| 461 | void dump() const; | ||
| 462 | |||
| 463 | #if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS) | ||
| 464 |     /// Verify invariants about the SCC. | ||
| 465 |     /// | ||
| 466 |     /// This will attempt to validate all of the basic invariants within an | ||
| 467 |     /// SCC, but not that it is a strongly connected component per se. | ||
| 468 |     /// Primarily useful while building and updating the graph to check that | ||
| 469 |     /// basic properties are in place rather than having inexplicable crashes | ||
| 470 |     /// later. | ||
| 471 | void verify(); | ||
| 472 | #endif | ||
| 473 | |||
| 474 | public: | ||
| 475 | using iterator = pointee_iterator<SmallVectorImpl<Node *>::const_iterator>; | ||
| 476 | |||
| 477 | iterator begin() const { return Nodes.begin(); } | ||
| 478 | iterator end() const { return Nodes.end(); } | ||
| 479 | |||
| 480 | int size() const { return Nodes.size(); } | ||
| 481 | |||
| 482 | RefSCC &getOuterRefSCC() const { return *OuterRefSCC; } | ||
| 483 | |||
| 484 |     /// Test if this SCC is a parent of \a C. | ||
| 485 |     /// | ||
| 486 |     /// Note that this is linear in the number of edges departing the current | ||
| 487 |     /// SCC. | ||
| 488 | bool isParentOf(const SCC &C) const; | ||
| 489 | |||
| 490 |     /// Test if this SCC is an ancestor of \a C. | ||
| 491 |     /// | ||
| 492 |     /// Note that in the worst case this is linear in the number of edges | ||
| 493 |     /// departing the current SCC and every SCC in the entire graph reachable | ||
| 494 |     /// from this SCC. Thus this very well may walk every edge in the entire | ||
| 495 |     /// call graph! Do not call this in a tight loop! | ||
| 496 | bool isAncestorOf(const SCC &C) const; | ||
| 497 | |||
| 498 |     /// Test if this SCC is a child of \a C. | ||
| 499 |     /// | ||
| 500 |     /// See the comments for \c isParentOf for detailed notes about the | ||
| 501 |     /// complexity of this routine. | ||
| 502 | bool isChildOf(const SCC &C) const { return C.isParentOf(*this); } | ||
| 503 | |||
| 504 |     /// Test if this SCC is a descendant of \a C. | ||
| 505 |     /// | ||
| 506 |     /// See the comments for \c isParentOf for detailed notes about the | ||
| 507 |     /// complexity of this routine. | ||
| 508 | bool isDescendantOf(const SCC &C) const { return C.isAncestorOf(*this); } | ||
| 509 | |||
| 510 |     /// Provide a short name by printing this SCC to a std::string. | ||
| 511 |     /// | ||
| 512 |     /// This copes with the fact that we don't have a name per se for an SCC | ||
| 513 |     /// while still making the use of this in debugging and logging useful. | ||
| 514 | std::string getName() const { | ||
| 515 | std::string Name; | ||
| 516 | raw_string_ostream OS(Name); | ||
| 517 | OS << *this; | ||
| 518 | OS.flush(); | ||
| 519 | return Name; | ||
| 520 |     } | ||
| 521 | }; | ||
| 522 | |||
| 523 |   /// A RefSCC of the call graph. | ||
| 524 |   /// | ||
| 525 |   /// This models a Strongly Connected Component of function reference edges in | ||
| 526 |   /// the call graph. As opposed to actual SCCs, these can be used to scope | ||
| 527 |   /// subgraphs of the module which are independent from other subgraphs of the | ||
| 528 |   /// module because they do not reference it in any way. This is also the unit | ||
| 529 |   /// where we do mutation of the graph in order to restrict mutations to those | ||
| 530 |   /// which don't violate this independence. | ||
| 531 |   /// | ||
| 532 |   /// A RefSCC contains a DAG of actual SCCs. All the nodes within the RefSCC | ||
| 533 |   /// are necessarily within some actual SCC that nests within it. Since | ||
| 534 |   /// a direct call *is* a reference, there will always be at least one RefSCC | ||
| 535 |   /// around any SCC. | ||
| 536 |   /// | ||
| 537 |   /// Spurious ref edges, meaning ref edges that still exist in the call graph | ||
| 538 |   /// even though the corresponding IR reference no longer exists, are allowed. | ||
| 539 |   /// This is mostly to support argument promotion, which can modify a caller to | ||
| 540 |   /// no longer pass a function. The only place that needs to specially handle | ||
| 541 |   /// this is deleting a dead function/node, otherwise the dead ref edges are | ||
| 542 |   /// automatically removed when visiting the function/node no longer containing | ||
| 543 |   /// the ref edge. | ||
| 544 | class RefSCC { | ||
| 545 | friend class LazyCallGraph; | ||
| 546 | friend class LazyCallGraph::Node; | ||
| 547 | |||
| 548 | LazyCallGraph *G; | ||
| 549 | |||
| 550 |     /// A postorder list of the inner SCCs. | ||
| 551 | SmallVector<SCC *, 4> SCCs; | ||
| 552 | |||
| 553 |     /// A map from SCC to index in the postorder list. | ||
| 554 | SmallDenseMap<SCC *, int, 4> SCCIndices; | ||
| 555 | |||
| 556 |     /// Fast-path constructor. RefSCCs should instead be constructed by calling | ||
| 557 |     /// formRefSCCFast on the graph itself. | ||
| 558 | RefSCC(LazyCallGraph &G); | ||
| 559 | |||
| 560 | void clear() { | ||
| 561 | SCCs.clear(); | ||
| 562 | SCCIndices.clear(); | ||
| 563 |     } | ||
| 564 | |||
| 565 |     /// Print a short description useful for debugging or logging. | ||
| 566 |     /// | ||
| 567 |     /// We print the SCCs wrapped in '[]'s and skipping the middle SCCs if | ||
| 568 |     /// there are a large number. | ||
| 569 |     // | ||
| 570 |     // Note: this is defined inline to dodge issues with GCC's interpretation | ||
| 571 |     // of enclosing namespaces for friend function declarations. | ||
| 572 | friend raw_ostream &operator<<(raw_ostream &OS, const RefSCC &RC) { | ||
| 573 | OS << '['; | ||
| 574 | int I = 0; | ||
| 575 | for (LazyCallGraph::SCC &C : RC) { | ||
| 576 | if (I > 0) | ||
| 577 | OS << ", "; | ||
| 578 |         // Elide the inner elements if there are too many. | ||
| 579 | if (I > 4) { | ||
| 580 | OS << "..., " << *RC.SCCs.back(); | ||
| 581 | break; | ||
| 582 |         } | ||
| 583 | OS << C; | ||
| 584 | ++I; | ||
| 585 |       } | ||
| 586 | OS << ']'; | ||
| 587 | return OS; | ||
| 588 |     } | ||
| 589 | |||
| 590 |     /// Dump a short description of this RefSCC to stderr. | ||
| 591 | void dump() const; | ||
| 592 | |||
| 593 | #if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS) | ||
| 594 |     /// Verify invariants about the RefSCC and all its SCCs. | ||
| 595 |     /// | ||
| 596 |     /// This will attempt to validate all of the invariants *within* the | ||
| 597 |     /// RefSCC, but not that it is a strongly connected component of the larger | ||
| 598 |     /// graph. This makes it useful even when partially through an update. | ||
| 599 |     /// | ||
| 600 |     /// Invariants checked: | ||
| 601 |     /// - SCCs and their indices match. | ||
| 602 |     /// - The SCCs list is in fact in post-order. | ||
| 603 | void verify(); | ||
| 604 | #endif | ||
| 605 | |||
| 606 | public: | ||
| 607 | using iterator = pointee_iterator<SmallVectorImpl<SCC *>::const_iterator>; | ||
| 608 | using range = iterator_range<iterator>; | ||
| 609 | using parent_iterator = | ||
| 610 | pointee_iterator<SmallPtrSetImpl<RefSCC *>::const_iterator>; | ||
| 611 | |||
| 612 | iterator begin() const { return SCCs.begin(); } | ||
| 613 | iterator end() const { return SCCs.end(); } | ||
| 614 | |||
| 615 | ssize_t size() const { return SCCs.size(); } | ||
| 616 | |||
| 617 | SCC &operator[](int Idx) { return *SCCs[Idx]; } | ||
| 618 | |||
| 619 | iterator find(SCC &C) const { | ||
| 620 | return SCCs.begin() + SCCIndices.find(&C)->second; | ||
| 621 |     } | ||
| 622 | |||
| 623 |     /// Test if this RefSCC is a parent of \a RC. | ||
| 624 |     /// | ||
| 625 |     /// CAUTION: This method walks every edge in the \c RefSCC, it can be very | ||
| 626 |     /// expensive. | ||
| 627 | bool isParentOf(const RefSCC &RC) const; | ||
| 628 | |||
| 629 |     /// Test if this RefSCC is an ancestor of \a RC. | ||
| 630 |     /// | ||
| 631 |     /// CAUTION: This method walks the directed graph of edges as far as | ||
| 632 |     /// necessary to find a possible path to the argument. In the worst case | ||
| 633 |     /// this may walk the entire graph and can be extremely expensive. | ||
| 634 | bool isAncestorOf(const RefSCC &RC) const; | ||
| 635 | |||
| 636 |     /// Test if this RefSCC is a child of \a RC. | ||
| 637 |     /// | ||
| 638 |     /// CAUTION: This method walks every edge in the argument \c RefSCC, it can | ||
| 639 |     /// be very expensive. | ||
| 640 | bool isChildOf(const RefSCC &RC) const { return RC.isParentOf(*this); } | ||
| 641 | |||
| 642 |     /// Test if this RefSCC is a descendant of \a RC. | ||
| 643 |     /// | ||
| 644 |     /// CAUTION: This method walks the directed graph of edges as far as | ||
| 645 |     /// necessary to find a possible path from the argument. In the worst case | ||
| 646 |     /// this may walk the entire graph and can be extremely expensive. | ||
| 647 | bool isDescendantOf(const RefSCC &RC) const { | ||
| 648 | return RC.isAncestorOf(*this); | ||
| 649 |     } | ||
| 650 | |||
| 651 |     /// Provide a short name by printing this RefSCC to a std::string. | ||
| 652 |     /// | ||
| 653 |     /// This copes with the fact that we don't have a name per se for an RefSCC | ||
| 654 |     /// while still making the use of this in debugging and logging useful. | ||
| 655 | std::string getName() const { | ||
| 656 | std::string Name; | ||
| 657 | raw_string_ostream OS(Name); | ||
| 658 | OS << *this; | ||
| 659 | OS.flush(); | ||
| 660 | return Name; | ||
| 661 |     } | ||
| 662 | |||
| 663 |     ///@{ | ||
| 664 |     /// \name Mutation API | ||
| 665 |     /// | ||
| 666 |     /// These methods provide the core API for updating the call graph in the | ||
| 667 |     /// presence of (potentially still in-flight) DFS-found RefSCCs and SCCs. | ||
| 668 |     /// | ||
| 669 |     /// Note that these methods sometimes have complex runtimes, so be careful | ||
| 670 |     /// how you call them. | ||
| 671 | |||
| 672 |     /// Make an existing internal ref edge into a call edge. | ||
| 673 |     /// | ||
| 674 |     /// This may form a larger cycle and thus collapse SCCs into TargetN's SCC. | ||
| 675 |     /// If that happens, the optional callback \p MergedCB will be invoked (if | ||
| 676 |     /// provided) on the SCCs being merged away prior to actually performing | ||
| 677 |     /// the merge. Note that this will never include the target SCC as that | ||
| 678 |     /// will be the SCC functions are merged into to resolve the cycle. Once | ||
| 679 |     /// this function returns, these merged SCCs are not in a valid state but | ||
| 680 |     /// the pointers will remain valid until destruction of the parent graph | ||
| 681 |     /// instance for the purpose of clearing cached information. This function | ||
| 682 |     /// also returns 'true' if a cycle was formed and some SCCs merged away as | ||
| 683 |     /// a convenience. | ||
| 684 |     /// | ||
| 685 |     /// After this operation, both SourceN's SCC and TargetN's SCC may move | ||
| 686 |     /// position within this RefSCC's postorder list. Any SCCs merged are | ||
| 687 |     /// merged into the TargetN's SCC in order to preserve reachability analyses | ||
| 688 |     /// which took place on that SCC. | ||
| 689 | bool switchInternalEdgeToCall( | ||
| 690 | Node &SourceN, Node &TargetN, | ||
| 691 | function_ref<void(ArrayRef<SCC *> MergedSCCs)> MergeCB = {}); | ||
| 692 | |||
| 693 |     /// Make an existing internal call edge between separate SCCs into a ref | ||
| 694 |     /// edge. | ||
| 695 |     /// | ||
| 696 |     /// If SourceN and TargetN in separate SCCs within this RefSCC, changing | ||
| 697 |     /// the call edge between them to a ref edge is a trivial operation that | ||
| 698 |     /// does not require any structural changes to the call graph. | ||
| 699 | void switchTrivialInternalEdgeToRef(Node &SourceN, Node &TargetN); | ||
| 700 | |||
| 701 |     /// Make an existing internal call edge within a single SCC into a ref | ||
| 702 |     /// edge. | ||
| 703 |     /// | ||
| 704 |     /// Since SourceN and TargetN are part of a single SCC, this SCC may be | ||
| 705 |     /// split up due to breaking a cycle in the call edges that formed it. If | ||
| 706 |     /// that happens, then this routine will insert new SCCs into the postorder | ||
| 707 |     /// list *before* the SCC of TargetN (previously the SCC of both). This | ||
| 708 |     /// preserves postorder as the TargetN can reach all of the other nodes by | ||
| 709 |     /// definition of previously being in a single SCC formed by the cycle from | ||
| 710 |     /// SourceN to TargetN. | ||
| 711 |     /// | ||
| 712 |     /// The newly added SCCs are added *immediately* and contiguously | ||
| 713 |     /// prior to the TargetN SCC and return the range covering the new SCCs in | ||
| 714 |     /// the RefSCC's postorder sequence. You can directly iterate the returned | ||
| 715 |     /// range to observe all of the new SCCs in postorder. | ||
| 716 |     /// | ||
| 717 |     /// Note that if SourceN and TargetN are in separate SCCs, the simpler | ||
| 718 |     /// routine `switchTrivialInternalEdgeToRef` should be used instead. | ||
| 719 | iterator_range<iterator> switchInternalEdgeToRef(Node &SourceN, | ||
| 720 | Node &TargetN); | ||
| 721 | |||
| 722 |     /// Make an existing outgoing ref edge into a call edge. | ||
| 723 |     /// | ||
| 724 |     /// Note that this is trivial as there are no cyclic impacts and there | ||
| 725 |     /// remains a reference edge. | ||
| 726 | void switchOutgoingEdgeToCall(Node &SourceN, Node &TargetN); | ||
| 727 | |||
| 728 |     /// Make an existing outgoing call edge into a ref edge. | ||
| 729 |     /// | ||
| 730 |     /// This is trivial as there are no cyclic impacts and there remains | ||
| 731 |     /// a reference edge. | ||
| 732 | void switchOutgoingEdgeToRef(Node &SourceN, Node &TargetN); | ||
| 733 | |||
| 734 |     /// Insert a ref edge from one node in this RefSCC to another in this | ||
| 735 |     /// RefSCC. | ||
| 736 |     /// | ||
| 737 |     /// This is always a trivial operation as it doesn't change any part of the | ||
| 738 |     /// graph structure besides connecting the two nodes. | ||
| 739 |     /// | ||
| 740 |     /// Note that we don't support directly inserting internal *call* edges | ||
| 741 |     /// because that could change the graph structure and requires returning | ||
| 742 |     /// information about what became invalid. As a consequence, the pattern | ||
| 743 |     /// should be to first insert the necessary ref edge, and then to switch it | ||
| 744 |     /// to a call edge if needed and handle any invalidation that results. See | ||
| 745 |     /// the \c switchInternalEdgeToCall routine for details. | ||
| 746 | void insertInternalRefEdge(Node &SourceN, Node &TargetN); | ||
| 747 | |||
| 748 |     /// Insert an edge whose parent is in this RefSCC and child is in some | ||
| 749 |     /// child RefSCC. | ||
| 750 |     /// | ||
| 751 |     /// There must be an existing path from the \p SourceN to the \p TargetN. | ||
| 752 |     /// This operation is inexpensive and does not change the set of SCCs and | ||
| 753 |     /// RefSCCs in the graph. | ||
| 754 | void insertOutgoingEdge(Node &SourceN, Node &TargetN, Edge::Kind EK); | ||
| 755 | |||
| 756 |     /// Insert an edge whose source is in a descendant RefSCC and target is in | ||
| 757 |     /// this RefSCC. | ||
| 758 |     /// | ||
| 759 |     /// There must be an existing path from the target to the source in this | ||
| 760 |     /// case. | ||
| 761 |     /// | ||
| 762 |     /// NB! This is has the potential to be a very expensive function. It | ||
| 763 |     /// inherently forms a cycle in the prior RefSCC DAG and we have to merge | ||
| 764 |     /// RefSCCs to resolve that cycle. But finding all of the RefSCCs which | ||
| 765 |     /// participate in the cycle can in the worst case require traversing every | ||
| 766 |     /// RefSCC in the graph. Every attempt is made to avoid that, but passes | ||
| 767 |     /// must still exercise caution calling this routine repeatedly. | ||
| 768 |     /// | ||
| 769 |     /// Also note that this can only insert ref edges. In order to insert | ||
| 770 |     /// a call edge, first insert a ref edge and then switch it to a call edge. | ||
| 771 |     /// These are intentionally kept as separate interfaces because each step | ||
| 772 |     /// of the operation invalidates a different set of data structures. | ||
| 773 |     /// | ||
| 774 |     /// This returns all the RefSCCs which were merged into the this RefSCC | ||
| 775 |     /// (the target's). This allows callers to invalidate any cached | ||
| 776 |     /// information. | ||
| 777 |     /// | ||
| 778 |     /// FIXME: We could possibly optimize this quite a bit for cases where the | ||
| 779 |     /// caller and callee are very nearby in the graph. See comments in the | ||
| 780 |     /// implementation for details, but that use case might impact users. | ||
| 781 | SmallVector<RefSCC *, 1> insertIncomingRefEdge(Node &SourceN, | ||
| 782 | Node &TargetN); | ||
| 783 | |||
| 784 |     /// Remove an edge whose source is in this RefSCC and target is *not*. | ||
| 785 |     /// | ||
| 786 |     /// This removes an inter-RefSCC edge. All inter-RefSCC edges originating | ||
| 787 |     /// from this SCC have been fully explored by any in-flight DFS graph | ||
| 788 |     /// formation, so this is always safe to call once you have the source | ||
| 789 |     /// RefSCC. | ||
| 790 |     /// | ||
| 791 |     /// This operation does not change the cyclic structure of the graph and so | ||
| 792 |     /// is very inexpensive. It may change the connectivity graph of the SCCs | ||
| 793 |     /// though, so be careful calling this while iterating over them. | ||
| 794 | void removeOutgoingEdge(Node &SourceN, Node &TargetN); | ||
| 795 | |||
| 796 |     /// Remove a list of ref edges which are entirely within this RefSCC. | ||
| 797 |     /// | ||
| 798 |     /// Both the \a SourceN and all of the \a TargetNs must be within this | ||
| 799 |     /// RefSCC. Removing these edges may break cycles that form this RefSCC and | ||
| 800 |     /// thus this operation may change the RefSCC graph significantly. In | ||
| 801 |     /// particular, this operation will re-form new RefSCCs based on the | ||
| 802 |     /// remaining connectivity of the graph. The following invariants are | ||
| 803 |     /// guaranteed to hold after calling this method: | ||
| 804 |     /// | ||
| 805 |     /// 1) If a ref-cycle remains after removal, it leaves this RefSCC intact | ||
| 806 |     ///    and in the graph. No new RefSCCs are built. | ||
| 807 |     /// 2) Otherwise, this RefSCC will be dead after this call and no longer in | ||
| 808 |     ///    the graph or the postorder traversal of the call graph. Any iterator | ||
| 809 |     ///    pointing at this RefSCC will become invalid. | ||
| 810 |     /// 3) All newly formed RefSCCs will be returned and the order of the | ||
| 811 |     ///    RefSCCs returned will be a valid postorder traversal of the new | ||
| 812 |     ///    RefSCCs. | ||
| 813 |     /// 4) No RefSCC other than this RefSCC has its member set changed (this is | ||
| 814 |     ///    inherent in the definition of removing such an edge). | ||
| 815 |     /// | ||
| 816 |     /// These invariants are very important to ensure that we can build | ||
| 817 |     /// optimization pipelines on top of the CGSCC pass manager which | ||
| 818 |     /// intelligently update the RefSCC graph without invalidating other parts | ||
| 819 |     /// of the RefSCC graph. | ||
| 820 |     /// | ||
| 821 |     /// Note that we provide no routine to remove a *call* edge. Instead, you | ||
| 822 |     /// must first switch it to a ref edge using \c switchInternalEdgeToRef. | ||
| 823 |     /// This split API is intentional as each of these two steps can invalidate | ||
| 824 |     /// a different aspect of the graph structure and needs to have the | ||
| 825 |     /// invalidation handled independently. | ||
| 826 |     /// | ||
| 827 |     /// The runtime complexity of this method is, in the worst case, O(V+E) | ||
| 828 |     /// where V is the number of nodes in this RefSCC and E is the number of | ||
| 829 |     /// edges leaving the nodes in this RefSCC. Note that E includes both edges | ||
| 830 |     /// within this RefSCC and edges from this RefSCC to child RefSCCs. Some | ||
| 831 |     /// effort has been made to minimize the overhead of common cases such as | ||
| 832 |     /// self-edges and edge removals which result in a spanning tree with no | ||
| 833 |     /// more cycles. | ||
| 834 | [[nodiscard]] SmallVector<RefSCC *, 1> | ||
| 835 | removeInternalRefEdge(Node &SourceN, ArrayRef<Node *> TargetNs); | ||
| 836 | |||
| 837 |     /// A convenience wrapper around the above to handle trivial cases of | ||
| 838 |     /// inserting a new call edge. | ||
| 839 |     /// | ||
| 840 |     /// This is trivial whenever the target is in the same SCC as the source or | ||
| 841 |     /// the edge is an outgoing edge to some descendant SCC. In these cases | ||
| 842 |     /// there is no change to the cyclic structure of SCCs or RefSCCs. | ||
| 843 |     /// | ||
| 844 |     /// To further make calling this convenient, it also handles inserting | ||
| 845 |     /// already existing edges. | ||
| 846 | void insertTrivialCallEdge(Node &SourceN, Node &TargetN); | ||
| 847 | |||
| 848 |     /// A convenience wrapper around the above to handle trivial cases of | ||
| 849 |     /// inserting a new ref edge. | ||
| 850 |     /// | ||
| 851 |     /// This is trivial whenever the target is in the same RefSCC as the source | ||
| 852 |     /// or the edge is an outgoing edge to some descendant RefSCC. In these | ||
| 853 |     /// cases there is no change to the cyclic structure of the RefSCCs. | ||
| 854 |     /// | ||
| 855 |     /// To further make calling this convenient, it also handles inserting | ||
| 856 |     /// already existing edges. | ||
| 857 | void insertTrivialRefEdge(Node &SourceN, Node &TargetN); | ||
| 858 | |||
| 859 |     /// Directly replace a node's function with a new function. | ||
| 860 |     /// | ||
| 861 |     /// This should be used when moving the body and users of a function to | ||
| 862 |     /// a new formal function object but not otherwise changing the call graph | ||
| 863 |     /// structure in any way. | ||
| 864 |     /// | ||
| 865 |     /// It requires that the old function in the provided node have zero uses | ||
| 866 |     /// and the new function must have calls and references to it establishing | ||
| 867 |     /// an equivalent graph. | ||
| 868 | void replaceNodeFunction(Node &N, Function &NewF); | ||
| 869 | |||
| 870 |     ///@} | ||
| 871 | }; | ||
| 872 | |||
| 873 |   /// A post-order depth-first RefSCC iterator over the call graph. | ||
| 874 |   /// | ||
| 875 |   /// This iterator walks the cached post-order sequence of RefSCCs. However, | ||
| 876 |   /// it trades stability for flexibility. It is restricted to a forward | ||
| 877 |   /// iterator but will survive mutations which insert new RefSCCs and continue | ||
| 878 |   /// to point to the same RefSCC even if it moves in the post-order sequence. | ||
| 879 |   class postorder_ref_scc_iterator | ||
| 880 | : public iterator_facade_base<postorder_ref_scc_iterator, | ||
| 881 | std::forward_iterator_tag, RefSCC> { | ||
| 882 | friend class LazyCallGraph; | ||
| 883 | friend class LazyCallGraph::Node; | ||
| 884 | |||
| 885 |     /// Nonce type to select the constructor for the end iterator. | ||
| 886 | struct IsAtEndT {}; | ||
| 887 | |||
| 888 | LazyCallGraph *G; | ||
| 889 | RefSCC *RC = nullptr; | ||
| 890 | |||
| 891 |     /// Build the begin iterator for a node. | ||
| 892 | postorder_ref_scc_iterator(LazyCallGraph &G) : G(&G), RC(getRC(G, 0)) { | ||
| 893 | incrementUntilNonEmptyRefSCC(); | ||
| 894 |     } | ||
| 895 | |||
| 896 |     /// Build the end iterator for a node. This is selected purely by overload. | ||
| 897 | postorder_ref_scc_iterator(LazyCallGraph &G, IsAtEndT /*Nonce*/) : G(&G) {} | ||
| 898 | |||
| 899 |     /// Get the post-order RefSCC at the given index of the postorder walk, | ||
| 900 |     /// populating it if necessary. | ||
| 901 | static RefSCC *getRC(LazyCallGraph &G, int Index) { | ||
| 902 | if (Index == (int)G.PostOrderRefSCCs.size()) | ||
| 903 |         // We're at the end. | ||
| 904 | return nullptr; | ||
| 905 | |||
| 906 | return G.PostOrderRefSCCs[Index]; | ||
| 907 |     } | ||
| 908 | |||
| 909 |     // Keep incrementing until RC is non-empty (or null). | ||
| 910 | void incrementUntilNonEmptyRefSCC() { | ||
| 911 | while (RC && RC->size() == 0) | ||
| 912 | increment(); | ||
| 913 |     } | ||
| 914 | |||
| 915 | void increment() { | ||
| 916 | assert(RC && "Cannot increment the end iterator!"); | ||
| 917 | RC = getRC(*G, G->RefSCCIndices.find(RC)->second + 1); | ||
| 918 |     } | ||
| 919 | |||
| 920 | public: | ||
| 921 | bool operator==(const postorder_ref_scc_iterator &Arg) const { | ||
| 922 | return G == Arg.G && RC == Arg.RC; | ||
| 923 |     } | ||
| 924 | |||
| 925 | reference operator*() const { return *RC; } | ||
| 926 | |||
| 927 | using iterator_facade_base::operator++; | ||
| 928 | postorder_ref_scc_iterator &operator++() { | ||
| 929 | increment(); | ||
| 930 | incrementUntilNonEmptyRefSCC(); | ||
| 931 | return *this; | ||
| 932 |     } | ||
| 933 | }; | ||
| 934 | |||
| 935 |   /// Construct a graph for the given module. | ||
| 936 |   /// | ||
| 937 |   /// This sets up the graph and computes all of the entry points of the graph. | ||
| 938 |   /// No function definitions are scanned until their nodes in the graph are | ||
| 939 |   /// requested during traversal. | ||
| 940 | LazyCallGraph(Module &M, | ||
| 941 | function_ref<TargetLibraryInfo &(Function &)> GetTLI); | ||
| 942 | |||
| 943 | LazyCallGraph(LazyCallGraph &&G); | ||
| 944 | LazyCallGraph &operator=(LazyCallGraph &&RHS); | ||
| 945 | |||
| 946 | bool invalidate(Module &, const PreservedAnalyses &PA, | ||
| 947 | ModuleAnalysisManager::Invalidator &); | ||
| 948 | |||
| 949 | EdgeSequence::iterator begin() { return EntryEdges.begin(); } | ||
| 950 | EdgeSequence::iterator end() { return EntryEdges.end(); } | ||
| 951 | |||
| 952 | void buildRefSCCs(); | ||
| 953 | |||
| 954 | postorder_ref_scc_iterator postorder_ref_scc_begin() { | ||
| 955 | if (!EntryEdges.empty()) | ||
| 956 | assert(!PostOrderRefSCCs.empty() && | ||
| 957 | "Must form RefSCCs before iterating them!"); | ||
| 958 | return postorder_ref_scc_iterator(*this); | ||
| 959 |   } | ||
| 960 | postorder_ref_scc_iterator postorder_ref_scc_end() { | ||
| 961 | if (!EntryEdges.empty()) | ||
| 962 | assert(!PostOrderRefSCCs.empty() && | ||
| 963 | "Must form RefSCCs before iterating them!"); | ||
| 964 | return postorder_ref_scc_iterator(*this, | ||
| 965 | postorder_ref_scc_iterator::IsAtEndT()); | ||
| 966 |   } | ||
| 967 | |||
| 968 | iterator_range<postorder_ref_scc_iterator> postorder_ref_sccs() { | ||
| 969 | return make_range(postorder_ref_scc_begin(), postorder_ref_scc_end()); | ||
| 970 |   } | ||
| 971 | |||
| 972 |   /// Lookup a function in the graph which has already been scanned and added. | ||
| 973 | Node *lookup(const Function &F) const { return NodeMap.lookup(&F); } | ||
| 974 | |||
| 975 |   /// Lookup a function's SCC in the graph. | ||
| 976 |   /// | ||
| 977 |   /// \returns null if the function hasn't been assigned an SCC via the RefSCC | ||
| 978 |   /// iterator walk. | ||
| 979 | SCC *lookupSCC(Node &N) const { return SCCMap.lookup(&N); } | ||
| 980 | |||
| 981 |   /// Lookup a function's RefSCC in the graph. | ||
| 982 |   /// | ||
| 983 |   /// \returns null if the function hasn't been assigned a RefSCC via the | ||
| 984 |   /// RefSCC iterator walk. | ||
| 985 | RefSCC *lookupRefSCC(Node &N) const { | ||
| 986 | if (SCC *C = lookupSCC(N)) | ||
| 987 | return &C->getOuterRefSCC(); | ||
| 988 | |||
| 989 | return nullptr; | ||
| 990 |   } | ||
| 991 | |||
| 992 |   /// Get a graph node for a given function, scanning it to populate the graph | ||
| 993 |   /// data as necessary. | ||
| 994 | Node &get(Function &F) { | ||
| 995 | Node *&N = NodeMap[&F]; | ||
| 996 | if (N) | ||
| 997 | return *N; | ||
| 998 | |||
| 999 | return insertInto(F, N); | ||
| 1000 |   } | ||
| 1001 | |||
| 1002 |   /// Get the sequence of known and defined library functions. | ||
| 1003 |   /// | ||
| 1004 |   /// These functions, because they are known to LLVM, can have calls | ||
| 1005 |   /// introduced out of thin air from arbitrary IR. | ||
| 1006 | ArrayRef<Function *> getLibFunctions() const { | ||
| 1007 | return LibFunctions.getArrayRef(); | ||
| 1008 |   } | ||
| 1009 | |||
| 1010 |   /// Test whether a function is a known and defined library function tracked by | ||
| 1011 |   /// the call graph. | ||
| 1012 |   /// | ||
| 1013 |   /// Because these functions are known to LLVM they are specially modeled in | ||
| 1014 |   /// the call graph and even when all IR-level references have been removed | ||
| 1015 |   /// remain active and reachable. | ||
| 1016 | bool isLibFunction(Function &F) const { return LibFunctions.count(&F); } | ||
| 1017 | |||
| 1018 |   ///@{ | ||
| 1019 |   /// \name Pre-SCC Mutation API | ||
| 1020 |   /// | ||
| 1021 |   /// These methods are only valid to call prior to forming any SCCs for this | ||
| 1022 |   /// call graph. They can be used to update the core node-graph during | ||
| 1023 |   /// a node-based inorder traversal that precedes any SCC-based traversal. | ||
| 1024 |   /// | ||
| 1025 |   /// Once you begin manipulating a call graph's SCCs, most mutation of the | ||
| 1026 |   /// graph must be performed via a RefSCC method. There are some exceptions | ||
| 1027 |   /// below. | ||
| 1028 | |||
| 1029 |   /// Update the call graph after inserting a new edge. | ||
| 1030 | void insertEdge(Node &SourceN, Node &TargetN, Edge::Kind EK); | ||
| 1031 | |||
| 1032 |   /// Update the call graph after inserting a new edge. | ||
| 1033 | void insertEdge(Function &Source, Function &Target, Edge::Kind EK) { | ||
| 1034 | return insertEdge(get(Source), get(Target), EK); | ||
| 1035 |   } | ||
| 1036 | |||
| 1037 |   /// Update the call graph after deleting an edge. | ||
| 1038 | void removeEdge(Node &SourceN, Node &TargetN); | ||
| 1039 | |||
| 1040 |   /// Update the call graph after deleting an edge. | ||
| 1041 | void removeEdge(Function &Source, Function &Target) { | ||
| 1042 | return removeEdge(get(Source), get(Target)); | ||
| 1043 |   } | ||
| 1044 | |||
| 1045 |   ///@} | ||
| 1046 | |||
| 1047 |   ///@{ | ||
| 1048 |   /// \name General Mutation API | ||
| 1049 |   /// | ||
| 1050 |   /// There are a very limited set of mutations allowed on the graph as a whole | ||
| 1051 |   /// once SCCs have started to be formed. These routines have strict contracts | ||
| 1052 |   /// but may be called at any point. | ||
| 1053 | |||
| 1054 |   /// Remove a dead function from the call graph (typically to delete it). | ||
| 1055 |   /// | ||
| 1056 |   /// Note that the function must have an empty use list, and the call graph | ||
| 1057 |   /// must be up-to-date prior to calling this. That means it is by itself in | ||
| 1058 |   /// a maximal SCC which is by itself in a maximal RefSCC, etc. No structural | ||
| 1059 |   /// changes result from calling this routine other than potentially removing | ||
| 1060 |   /// entry points into the call graph. | ||
| 1061 |   /// | ||
| 1062 |   /// If SCC formation has begun, this function must not be part of the current | ||
| 1063 |   /// DFS in order to call this safely. Typically, the function will have been | ||
| 1064 |   /// fully visited by the DFS prior to calling this routine. | ||
| 1065 | void removeDeadFunction(Function &F); | ||
| 1066 | |||
| 1067 |   /// Add a new function split/outlined from an existing function. | ||
| 1068 |   /// | ||
| 1069 |   /// The new function may only reference other functions that the original | ||
| 1070 |   /// function did. | ||
| 1071 |   /// | ||
| 1072 |   /// The original function must reference (either directly or indirectly) the | ||
| 1073 |   /// new function. | ||
| 1074 |   /// | ||
| 1075 |   /// The new function may also reference the original function. | ||
| 1076 |   /// It may end up in a parent SCC in the case that the original function's | ||
| 1077 |   /// edge to the new function is a ref edge, and the edge back is a call edge. | ||
| 1078 | void addSplitFunction(Function &OriginalFunction, Function &NewFunction); | ||
| 1079 | |||
| 1080 |   /// Add new ref-recursive functions split/outlined from an existing function. | ||
| 1081 |   /// | ||
| 1082 |   /// The new functions may only reference other functions that the original | ||
| 1083 |   /// function did. The new functions may reference (not call) the original | ||
| 1084 |   /// function. | ||
| 1085 |   /// | ||
| 1086 |   /// The original function must reference (not call) all new functions. | ||
| 1087 |   /// All new functions must reference (not call) each other. | ||
| 1088 | void addSplitRefRecursiveFunctions(Function &OriginalFunction, | ||
| 1089 | ArrayRef<Function *> NewFunctions); | ||
| 1090 | |||
| 1091 |   ///@} | ||
| 1092 | |||
| 1093 |   ///@{ | ||
| 1094 |   /// \name Static helpers for code doing updates to the call graph. | ||
| 1095 |   /// | ||
| 1096 |   /// These helpers are used to implement parts of the call graph but are also | ||
| 1097 |   /// useful to code doing updates or otherwise wanting to walk the IR in the | ||
| 1098 |   /// same patterns as when we build the call graph. | ||
| 1099 | |||
| 1100 |   /// Recursively visits the defined functions whose address is reachable from | ||
| 1101 |   /// every constant in the \p Worklist. | ||
| 1102 |   /// | ||
| 1103 |   /// Doesn't recurse through any constants already in the \p Visited set, and | ||
| 1104 |   /// updates that set with every constant visited. | ||
| 1105 |   /// | ||
| 1106 |   /// For each defined function, calls \p Callback with that function. | ||
| 1107 | static void visitReferences(SmallVectorImpl<Constant *> &Worklist, | ||
| 1108 | SmallPtrSetImpl<Constant *> &Visited, | ||
| 1109 | function_ref<void(Function &)> Callback); | ||
| 1110 | |||
| 1111 |   ///@} | ||
| 1112 | |||
| 1113 | private: | ||
| 1114 | using node_stack_iterator = SmallVectorImpl<Node *>::reverse_iterator; | ||
| 1115 | using node_stack_range = iterator_range<node_stack_iterator>; | ||
| 1116 | |||
| 1117 |   /// Allocator that holds all the call graph nodes. | ||
| 1118 | SpecificBumpPtrAllocator<Node> BPA; | ||
| 1119 | |||
| 1120 |   /// Maps function->node for fast lookup. | ||
| 1121 | DenseMap<const Function *, Node *> NodeMap; | ||
| 1122 | |||
| 1123 |   /// The entry edges into the graph. | ||
| 1124 |   /// | ||
| 1125 |   /// These edges are from "external" sources. Put another way, they | ||
| 1126 |   /// escape at the module scope. | ||
| 1127 |   EdgeSequence EntryEdges; | ||
| 1128 | |||
| 1129 |   /// Allocator that holds all the call graph SCCs. | ||
| 1130 | SpecificBumpPtrAllocator<SCC> SCCBPA; | ||
| 1131 | |||
| 1132 |   /// Maps Function -> SCC for fast lookup. | ||
| 1133 | DenseMap<Node *, SCC *> SCCMap; | ||
| 1134 | |||
| 1135 |   /// Allocator that holds all the call graph RefSCCs. | ||
| 1136 | SpecificBumpPtrAllocator<RefSCC> RefSCCBPA; | ||
| 1137 | |||
| 1138 |   /// The post-order sequence of RefSCCs. | ||
| 1139 |   /// | ||
| 1140 |   /// This list is lazily formed the first time we walk the graph. | ||
| 1141 | SmallVector<RefSCC *, 16> PostOrderRefSCCs; | ||
| 1142 | |||
| 1143 |   /// A map from RefSCC to the index for it in the postorder sequence of | ||
| 1144 |   /// RefSCCs. | ||
| 1145 | DenseMap<RefSCC *, int> RefSCCIndices; | ||
| 1146 | |||
| 1147 |   /// Defined functions that are also known library functions which the | ||
| 1148 |   /// optimizer can reason about and therefore might introduce calls to out of | ||
| 1149 |   /// thin air. | ||
| 1150 | SmallSetVector<Function *, 4> LibFunctions; | ||
| 1151 | |||
| 1152 |   /// Helper to insert a new function, with an already looked-up entry in | ||
| 1153 |   /// the NodeMap. | ||
| 1154 | Node &insertInto(Function &F, Node *&MappedN); | ||
| 1155 | |||
| 1156 |   /// Helper to initialize a new node created outside of creating SCCs and add | ||
| 1157 |   /// it to the NodeMap if necessary. For example, useful when a function is | ||
| 1158 |   /// split. | ||
| 1159 | Node &initNode(Function &F); | ||
| 1160 | |||
| 1161 |   /// Helper to update pointers back to the graph object during moves. | ||
| 1162 | void updateGraphPtrs(); | ||
| 1163 | |||
| 1164 |   /// Allocates an SCC and constructs it using the graph allocator. | ||
| 1165 |   /// | ||
| 1166 |   /// The arguments are forwarded to the constructor. | ||
| 1167 | template <typename... Ts> SCC *createSCC(Ts &&...Args) { | ||
| 1168 | return new (SCCBPA.Allocate()) SCC(std::forward<Ts>(Args)...); | ||
| 1169 |   } | ||
| 1170 | |||
| 1171 |   /// Allocates a RefSCC and constructs it using the graph allocator. | ||
| 1172 |   /// | ||
| 1173 |   /// The arguments are forwarded to the constructor. | ||
| 1174 | template <typename... Ts> RefSCC *createRefSCC(Ts &&...Args) { | ||
| 1175 | return new (RefSCCBPA.Allocate()) RefSCC(std::forward<Ts>(Args)...); | ||
| 1176 |   } | ||
| 1177 | |||
| 1178 |   /// Common logic for building SCCs from a sequence of roots. | ||
| 1179 |   /// | ||
| 1180 |   /// This is a very generic implementation of the depth-first walk and SCC | ||
| 1181 |   /// formation algorithm. It uses a generic sequence of roots and generic | ||
| 1182 |   /// callbacks for each step. This is designed to be used to implement both | ||
| 1183 |   /// the RefSCC formation and SCC formation with shared logic. | ||
| 1184 |   /// | ||
| 1185 |   /// Currently this is a relatively naive implementation of Tarjan's DFS | ||
| 1186 |   /// algorithm to form the SCCs. | ||
| 1187 |   /// | ||
| 1188 |   /// FIXME: We should consider newer variants such as Nuutila. | ||
| 1189 | template <typename RootsT, typename GetBeginT, typename GetEndT, | ||
| 1190 | typename GetNodeT, typename FormSCCCallbackT> | ||
| 1191 | static void buildGenericSCCs(RootsT &&Roots, GetBeginT &&GetBegin, | ||
| 1192 | GetEndT &&GetEnd, GetNodeT &&GetNode, | ||
| 1193 | FormSCCCallbackT &&FormSCC); | ||
| 1194 | |||
| 1195 |   /// Build the SCCs for a RefSCC out of a list of nodes. | ||
| 1196 | void buildSCCs(RefSCC &RC, node_stack_range Nodes); | ||
| 1197 | |||
| 1198 |   /// Get the index of a RefSCC within the postorder traversal. | ||
| 1199 |   /// | ||
| 1200 |   /// Requires that this RefSCC is a valid one in the (perhaps partial) | ||
| 1201 |   /// postorder traversed part of the graph. | ||
| 1202 | int getRefSCCIndex(RefSCC &RC) { | ||
| 1203 | auto IndexIt = RefSCCIndices.find(&RC); | ||
| 1204 | assert(IndexIt != RefSCCIndices.end() && "RefSCC doesn't have an index!"); | ||
| 1205 | assert(PostOrderRefSCCs[IndexIt->second] == &RC && | ||
| 1206 | "Index does not point back at RC!"); | ||
| 1207 | return IndexIt->second; | ||
| 1208 |   } | ||
| 1209 | }; | ||
| 1210 | |||
| 1211 | inline LazyCallGraph::Edge::Edge() = default; | ||
| 1212 | inline LazyCallGraph::Edge::Edge(Node &N, Kind K) : Value(&N, K) {} | ||
| 1213 | |||
| 1214 | inline LazyCallGraph::Edge::operator bool() const { | ||
| 1215 | return Value.getPointer() && !Value.getPointer()->isDead(); | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | inline LazyCallGraph::Edge::Kind LazyCallGraph::Edge::getKind() const { | ||
| 1219 | assert(*this && "Queried a null edge!"); | ||
| 1220 | return Value.getInt(); | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | inline bool LazyCallGraph::Edge::isCall() const { | ||
| 1224 | assert(*this && "Queried a null edge!"); | ||
| 1225 | return getKind() == Call; | ||
| 1226 | } | ||
| 1227 | |||
| 1228 | inline LazyCallGraph::Node &LazyCallGraph::Edge::getNode() const { | ||
| 1229 | assert(*this && "Queried a null edge!"); | ||
| 1230 | return *Value.getPointer(); | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | inline Function &LazyCallGraph::Edge::getFunction() const { | ||
| 1234 | assert(*this && "Queried a null edge!"); | ||
| 1235 | return getNode().getFunction(); | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | // Provide GraphTraits specializations for call graphs. | ||
| 1239 | template <> struct GraphTraits<LazyCallGraph::Node *> { | ||
| 1240 | using NodeRef = LazyCallGraph::Node *; | ||
| 1241 | using ChildIteratorType = LazyCallGraph::EdgeSequence::iterator; | ||
| 1242 | |||
| 1243 | static NodeRef getEntryNode(NodeRef N) { return N; } | ||
| 1244 | static ChildIteratorType child_begin(NodeRef N) { return (*N)->begin(); } | ||
| 1245 | static ChildIteratorType child_end(NodeRef N) { return (*N)->end(); } | ||
| 1246 | }; | ||
| 1247 | template <> struct GraphTraits<LazyCallGraph *> { | ||
| 1248 | using NodeRef = LazyCallGraph::Node *; | ||
| 1249 | using ChildIteratorType = LazyCallGraph::EdgeSequence::iterator; | ||
| 1250 | |||
| 1251 | static NodeRef getEntryNode(NodeRef N) { return N; } | ||
| 1252 | static ChildIteratorType child_begin(NodeRef N) { return (*N)->begin(); } | ||
| 1253 | static ChildIteratorType child_end(NodeRef N) { return (*N)->end(); } | ||
| 1254 | }; | ||
| 1255 | |||
| 1256 | /// An analysis pass which computes the call graph for a module. | ||
| 1257 | class LazyCallGraphAnalysis : public AnalysisInfoMixin<LazyCallGraphAnalysis> { | ||
| 1258 | friend AnalysisInfoMixin<LazyCallGraphAnalysis>; | ||
| 1259 | |||
| 1260 | static AnalysisKey Key; | ||
| 1261 | |||
| 1262 | public: | ||
| 1263 |   /// Inform generic clients of the result type. | ||
| 1264 | using Result = LazyCallGraph; | ||
| 1265 | |||
| 1266 |   /// Compute the \c LazyCallGraph for the module \c M. | ||
| 1267 |   /// | ||
| 1268 |   /// This just builds the set of entry points to the call graph. The rest is | ||
| 1269 |   /// built lazily as it is walked. | ||
| 1270 | LazyCallGraph run(Module &M, ModuleAnalysisManager &AM) { | ||
| 1271 | FunctionAnalysisManager &FAM = | ||
| 1272 | AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); | ||
| 1273 | auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { | ||
| 1274 | return FAM.getResult<TargetLibraryAnalysis>(F); | ||
| 1275 | }; | ||
| 1276 | return LazyCallGraph(M, GetTLI); | ||
| 1277 |   } | ||
| 1278 | }; | ||
| 1279 | |||
| 1280 | /// A pass which prints the call graph to a \c raw_ostream. | ||
| 1281 | /// | ||
| 1282 | /// This is primarily useful for testing the analysis. | ||
| 1283 | class LazyCallGraphPrinterPass | ||
| 1284 | : public PassInfoMixin<LazyCallGraphPrinterPass> { | ||
| 1285 | raw_ostream &OS; | ||
| 1286 | |||
| 1287 | public: | ||
| 1288 | explicit LazyCallGraphPrinterPass(raw_ostream &OS); | ||
| 1289 | |||
| 1290 | PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); | ||
| 1291 | }; | ||
| 1292 | |||
| 1293 | /// A pass which prints the call graph as a DOT file to a \c raw_ostream. | ||
| 1294 | /// | ||
| 1295 | /// This is primarily useful for visualization purposes. | ||
| 1296 | class LazyCallGraphDOTPrinterPass | ||
| 1297 | : public PassInfoMixin<LazyCallGraphDOTPrinterPass> { | ||
| 1298 | raw_ostream &OS; | ||
| 1299 | |||
| 1300 | public: | ||
| 1301 | explicit LazyCallGraphDOTPrinterPass(raw_ostream &OS); | ||
| 1302 | |||
| 1303 | PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); | ||
| 1304 | }; | ||
| 1305 | |||
| 1306 | } // end namespace llvm | ||
| 1307 | |||
| 1308 | #endif // LLVM_ANALYSIS_LAZYCALLGRAPH_H |