34#ifndef LLVM_ANALYSIS_LAZYCALLGRAPH_H
35#define LLVM_ANALYSIS_LAZYCALLGRAPH_H
141 explicit operator bool()
const;
192 std::forward_iterator_tag> {
201 while (
I != E && !*
I)
208 using iterator_adaptor_base::operator++;
212 }
while (
I != E && !*
I);
223 std::forward_iterator_tag> {
230 void advanceToNextEdge() {
231 while (
I != E && (!*
I || !
I->isCall()))
244 using iterator_adaptor_base::operator++;
256 assert(EdgeIndexMap.contains(&
N) &&
"No such edge!");
257 auto &
E = Edges[EdgeIndexMap.find(&
N)->second];
258 assert(
E &&
"Dead or null edge!");
263 auto EI = EdgeIndexMap.find(&
N);
264 if (EI == EdgeIndexMap.end())
266 auto &
E = Edges[EI->second];
267 return E ? &
E :
nullptr;
280 for (
auto &
E : Edges)
294 void insertEdgeInternal(
Node &ChildN, Edge::Kind EK);
297 void setEdgeKind(
Node &ChildN, Edge::Kind EK);
300 bool removeEdgeInternal(
Node &ChildN);
338 "Both graph and function pointers should be null or non-null.");
366 return populateSlow();
379 std::optional<EdgeSequence> Edges;
386 LLVM_ABI EdgeSequence &populateSlow();
393 void replaceFunction(
Function &NewF);
395 void clear() { Edges.reset(); }
399 return OS <<
N.F->getName();
424 template <
typename NodeRangeT>
425 SCC(
RefSCC &OuterRefSCC, NodeRangeT &&Nodes)
426 : OuterRefSCC(&OuterRefSCC), Nodes(
std::forward<NodeRangeT>(Nodes)) {}
429 OuterRefSCC =
nullptr;
448 OS <<
"..., " << *
C.Nodes.back();
461#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS)
478 int size()
const {
return Nodes.size(); }
486 bool isParentOf(
const SCC &
C)
const;
494 bool isAncestorOf(
const SCC &
C)
const;
500 bool isChildOf(
const SCC &
C)
const {
return C.isParentOf(*
this); }
578 OS <<
"..., " << *RC.SCCs.back();
591#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS)
613 ssize_t
size()
const {
return SCCs.size(); }
618 return SCCs.begin() + SCCIndices.find(&
C)->second;
878 class postorder_ref_scc_iterator
880 std::forward_iterator_tag, RefSCC> {
892 incrementUntilNonEmptyRefSCC();
901 if (Index == (
int)
G.PostOrderRefSCCs.size())
905 return G.PostOrderRefSCCs[Index];
909 void incrementUntilNonEmptyRefSCC() {
910 while (RC && RC->size() == 0)
915 assert(RC &&
"Cannot increment the end iterator!");
916 RC = getRC(*G, G->RefSCCIndices.find(RC)->second + 1);
920 bool operator==(
const postorder_ref_scc_iterator &Arg)
const {
921 return G == Arg.G && RC == Arg.RC;
926 using iterator_facade_base::operator++;
929 incrementUntilNonEmptyRefSCC();
945#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS)
951 ModuleAnalysisManager::Invalidator &);
959 if (!EntryEdges.empty())
960 assert(!PostOrderRefSCCs.empty() &&
961 "Must form RefSCCs before iterating them!");
965 if (!EntryEdges.empty())
966 assert(!PostOrderRefSCCs.empty() &&
967 "Must form RefSCCs before iterating them!");
969 postorder_ref_scc_iterator::IsAtEndT());
991 return &
C->getOuterRefSCC();
1003 return insertInto(
F,
N);
1011 return LibFunctions.getArrayRef();
1133 EdgeSequence EntryEdges;
1168 void updateGraphPtrs();
1173 template <
typename... Ts> SCC *createSCC(Ts &&...Args) {
1174 return new (SCCBPA.
Allocate()) SCC(std::forward<Ts>(Args)...);
1180 template <
typename... Ts> RefSCC *createRefSCC(Ts &&...Args) {
1181 return new (RefSCCBPA.
Allocate()) RefSCC(std::forward<Ts>(Args)...);
1195 template <
typename RootsT,
typename GetBeginT,
typename GetEndT,
1196 typename GetNodeT,
typename FormSCCCallbackT>
1197 static void buildGenericSCCs(RootsT &&Roots, GetBeginT &&GetBegin,
1198 GetEndT &&GetEnd, GetNodeT &&GetNode,
1199 FormSCCCallbackT &&FormSCC);
1202 void buildSCCs(
RefSCC &RC, node_stack_range Nodes);
1208 int getRefSCCIndex(
RefSCC &RC) {
1209 auto IndexIt = RefSCCIndices.find(&RC);
1210 assert(IndexIt != RefSCCIndices.end() &&
"RefSCC doesn't have an index!");
1211 assert(PostOrderRefSCCs[IndexIt->second] == &RC &&
1212 "Index does not point back at RC!");
1213 return IndexIt->second;
1217inline LazyCallGraph::Edge::Edge() =
default;
1218inline LazyCallGraph::Edge::Edge(
Node &
N,
Kind K) : Value(&
N, K) {}
1220inline LazyCallGraph::Edge::operator
bool()
const {
1221 return Value.getPointer() && !Value.getPointer()->isDead();
1224inline LazyCallGraph::Edge::Kind LazyCallGraph::Edge::getKind()
const {
1225 assert(*
this &&
"Queried a null edge!");
1226 return Value.getInt();
1229inline bool LazyCallGraph::Edge::isCall()
const {
1230 assert(*
this &&
"Queried a null edge!");
1235 assert(*
this &&
"Queried a null edge!");
1236 return *Value.getPointer();
1239inline Function &LazyCallGraph::Edge::getFunction()
const {
1240 assert(*
this &&
"Queried a null edge!");
1241 return getNode().getFunction();
1317 Any::TypeId<const LazyCallGraph::SCC *>;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
This file defines the BumpPtrAllocator interface.
This file provides Any, a non-template class modeled in the spirit of std::any.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_TEMPLATE_ABI
This file defines the DenseMap class.
This header defines various interfaces for pass management in LLVM.
FunctionAnalysisManager FAM
This file defines the PointerIntPair class.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is an important base class in LLVM.
An analysis pass which computes the call graph for a module.
LazyCallGraph run(Module &M, ModuleAnalysisManager &AM)
Compute the LazyCallGraph for the module M.
LazyCallGraph Result
Inform generic clients of the result type.
LLVM_ABI LazyCallGraphDOTPrinterPass(raw_ostream &OS)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI LazyCallGraphPrinterPass(raw_ostream &OS)
An iterator over specifically call edges.
call_iterator & operator++()
friend class LazyCallGraph
An iterator used for the edges to both entry nodes and child nodes.
friend class LazyCallGraph
The edge sequence object.
friend class LazyCallGraph::Node
friend class LazyCallGraph
Edge & operator[](Node &N)
call_iterator call_begin()
iterator_range< call_iterator > calls()
A class used to represent edges in the call graph.
Function & getFunction() const
Get the function referenced by this edge.
bool isCall() const
Test whether the edge represents a direct call to a function.
Kind
The kind of edge in the graph.
Kind getKind() const
Returns the Kind of the edge.
Node & getNode() const
Get the call graph node referenced by this edge.
A node in the call graph.
LazyCallGraph & getGraph() const
EdgeSequence & populate()
Populate the edges of this node if necessary.
bool isDead() const
Tests whether this is actually a dead node and no longer valid.
friend class LazyCallGraph
bool operator!=(const Node &N) const
bool isPopulated() const
Tests whether the node has been populated with edges.
bool operator==(const Node &N) const
Equality is defined as address equality.
friend raw_ostream & operator<<(raw_ostream &OS, const Node &N)
Print the name of this node's function.
EdgeSequence * operator->() const
StringRef getName() const
EdgeSequence & operator*() const
Function & getFunction() const
A RefSCC of the call graph.
LLVM_ABI SmallVector< RefSCC *, 1 > insertIncomingRefEdge(Node &SourceN, Node &TargetN)
Insert an edge whose source is in a descendant RefSCC and target is in this RefSCC.
LLVM_ABI bool switchInternalEdgeToCall(Node &SourceN, Node &TargetN, function_ref< void(ArrayRef< SCC * > MergedSCCs)> MergeCB={})
Make an existing internal ref edge into a call edge.
LLVM_ABI bool isAncestorOf(const RefSCC &RC) const
Test if this RefSCC is an ancestor of RC.
LLVM_ABI void insertTrivialRefEdge(Node &SourceN, Node &TargetN)
A convenience wrapper around the above to handle trivial cases of inserting a new ref edge.
iterator find(SCC &C) const
SCC & operator[](int Idx)
bool isDescendantOf(const RefSCC &RC) const
Test if this RefSCC is a descendant of RC.
bool isChildOf(const RefSCC &RC) const
Test if this RefSCC is a child of RC.
LLVM_ABI void switchOutgoingEdgeToCall(Node &SourceN, Node &TargetN)
Make an existing outgoing ref edge into a call edge.
iterator_range< iterator > range
LLVM_ABI void replaceNodeFunction(Node &N, Function &NewF)
Directly replace a node's function with a new function.
LLVM_ABI void insertOutgoingEdge(Node &SourceN, Node &TargetN, Edge::Kind EK)
Insert an edge whose parent is in this RefSCC and child is in some child RefSCC.
friend class LazyCallGraph
LLVM_ABI SmallVector< RefSCC *, 1 > removeInternalRefEdges(ArrayRef< std::pair< Node *, Node * > > Edges)
Remove a list of ref edges which are entirely within this RefSCC.
LLVM_ABI iterator_range< iterator > switchInternalEdgeToRef(Node &SourceN, Node &TargetN)
Make an existing internal call edge within a single SCC into a ref edge.
LLVM_ABI void insertInternalRefEdge(Node &SourceN, Node &TargetN)
Insert a ref edge from one node in this RefSCC to another in this RefSCC.
LLVM_ABI void insertTrivialCallEdge(Node &SourceN, Node &TargetN)
A convenience wrapper around the above to handle trivial cases of inserting a new call edge.
LLVM_ABI void removeOutgoingEdge(Node &SourceN, Node &TargetN)
Remove an edge whose source is in this RefSCC and target is not.
std::string getName() const
Provide a short name by printing this RefSCC to a std::string.
pointee_iterator< SmallVectorImpl< SCC * >::const_iterator > iterator
pointee_iterator< SmallPtrSetImpl< RefSCC * >::const_iterator > parent_iterator
LLVM_ABI void switchOutgoingEdgeToRef(Node &SourceN, Node &TargetN)
Make an existing outgoing call edge into a ref edge.
friend raw_ostream & operator<<(raw_ostream &OS, const RefSCC &RC)
Print a short description useful for debugging or logging.
LLVM_ABI void switchTrivialInternalEdgeToRef(Node &SourceN, Node &TargetN)
Make an existing internal call edge between separate SCCs into a ref edge.
LLVM_ABI bool isParentOf(const RefSCC &RC) const
Test if this RefSCC is a parent of RC.
An SCC of the call graph.
pointee_iterator< SmallVectorImpl< Node * >::const_iterator > iterator
bool isChildOf(const SCC &C) const
Test if this SCC is a child of C.
friend class LazyCallGraph
friend raw_ostream & operator<<(raw_ostream &OS, const SCC &C)
Print a short description useful for debugging or logging.
bool isDescendantOf(const SCC &C) const
Test if this SCC is a descendant of C.
std::string getName() const
Provide a short name by printing this SCC to a std::string.
RefSCC & getOuterRefSCC() const
A post-order depth-first RefSCC iterator over the call graph.
reference operator*() const
friend class LazyCallGraph
postorder_ref_scc_iterator & operator++()
bool operator==(const postorder_ref_scc_iterator &Arg) const
A lazily constructed view of the call graph of a module.
bool isLibFunction(Function &F) const
Test whether a function is a known and defined library function tracked by the call graph.
EdgeSequence::iterator begin()
RefSCC * lookupRefSCC(Node &N) const
Lookup a function's RefSCC in the graph.
LLVM_ABI void insertEdge(Node &SourceN, Node &TargetN, Edge::Kind EK)
Update the call graph after inserting a new edge.
LLVM_ABI LazyCallGraph(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
Construct a graph for the given module.
LLVM_ABI void buildRefSCCs()
static LLVM_ABI void visitReferences(SmallVectorImpl< Constant * > &Worklist, SmallPtrSetImpl< Constant * > &Visited, function_ref< void(Function &)> Callback)
Recursively visits the defined functions whose address is reachable from every constant in the Workli...
LLVM_ABI void markDeadFunction(Function &F)
Mark a function as dead to be removed later by removeDeadFunctions().
LLVM_ABI void addSplitFunction(Function &OriginalFunction, Function &NewFunction)
Add a new function split/outlined from an existing function.
LLVM_ABI void addSplitRefRecursiveFunctions(Function &OriginalFunction, ArrayRef< Function * > NewFunctions)
Add new ref-recursive functions split/outlined from an existing function.
LLVM_ABI void removeDeadFunctions(ArrayRef< Function * > DeadFs)
Remove dead functions from the call graph.
postorder_ref_scc_iterator postorder_ref_scc_begin()
ArrayRef< Function * > getLibFunctions() const
Get the sequence of known and defined library functions.
postorder_ref_scc_iterator postorder_ref_scc_end()
LLVM_ABI void removeEdge(Node &SourceN, Node &TargetN)
Update the call graph after deleting an edge.
void removeEdge(Function &Source, Function &Target)
Update the call graph after deleting an edge.
void insertEdge(Function &Source, Function &Target, Edge::Kind EK)
Update the call graph after inserting a new edge.
Node & get(Function &F)
Get a graph node for a given function, scanning it to populate the graph data as necessary.
SCC * lookupSCC(Node &N) const
Lookup a function's SCC in the graph.
iterator_range< postorder_ref_scc_iterator > postorder_ref_sccs()
LLVM_ABI LazyCallGraph & operator=(LazyCallGraph &&RHS)
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &)
void verify()
Verify that every RefSCC is valid.
EdgeSequence::iterator end()
Node * lookup(const Function &F) const
Lookup a function in the graph which has already been scanned and added.
A Module instance is used to store all the information related to an LLVM module.
PointerIntPair - This class implements a pair of a pointer and small integer.
void setInt(IntType IntVal) &
A set of analyses that are preserved following a run of a transformation pass.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::iterator iterator
std::reverse_iterator< iterator > reverse_iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
T * Allocate(size_t num=1)
Allocate space for an array of objects without constructing them.
StringRef - Represent a constant reference to a string, i.e.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Target - Wrapper for Target specific information.
An efficient, type-erasing, non-owning reference to a callable.
CRTP base class for adapting an iterator to a different type.
iterator_adaptor_base()=default
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Implement std::hash so that hash_code can be used in STL containers.
A CRTP mix-in that provides informational APIs needed for analysis passes.
A special type used by analysis passes to provide an address that identifies that particular analysis...
static ChildIteratorType child_begin(NodeRef N)
LazyCallGraph::EdgeSequence::iterator ChildIteratorType
LazyCallGraph::Node * NodeRef
static ChildIteratorType child_end(NodeRef N)
static NodeRef getEntryNode(NodeRef N)
static NodeRef getEntryNode(NodeRef N)
static ChildIteratorType child_end(NodeRef N)
LazyCallGraph::EdgeSequence::iterator ChildIteratorType
LazyCallGraph::Node * NodeRef
static ChildIteratorType child_begin(NodeRef N)
A CRTP mix-in to automatically provide informational APIs needed for passes.
An iterator type that allows iterating over the pointees via some other iterator.