35 #ifndef LLVM_ANALYSIS_LAZYCALLGRAPH_H 36 #define LLVM_ANALYSIS_LAZYCALLGRAPH_H 119 class call_edge_iterator;
147 explicit operator bool()
const;
198 std::forward_iterator_tag> {
207 while (
I != E && !*
I)
214 using iterator_adaptor_base::operator++;
218 }
while (
I != E && !*
I);
229 std::forward_iterator_tag> {
236 void advanceToNextEdge() {
237 while (
I != E && (!*
I || !
I->isCall()))
250 using iterator_adaptor_base::operator++;
263 assert(EdgeIndexMap.find(&N) != EdgeIndexMap.end() &&
"No such edge!");
264 auto &E = Edges[EdgeIndexMap.find(&N)->second];
265 assert(E &&
"Dead or null edge!");
270 auto EI = EdgeIndexMap.find(&N);
271 if (EI == EdgeIndexMap.end())
273 auto &E = Edges[EI->second];
274 return E ? &
E :
nullptr;
287 for (
auto &E : Edges)
307 bool removeEdgeInternal(
Node &ChildN);
352 "Both graph and function pointers should be null or non-null.");
380 return populateSlow();
407 void replaceFunction(
Function &NewF);
438 template <
typename NodeRangeT>
439 SCC(
RefSCC &OuterRefSCC, NodeRangeT &&Nodes)
440 : OuterRefSCC(&OuterRefSCC), Nodes(
std::forward<NodeRangeT>(Nodes)) {}
443 OuterRefSCC =
nullptr;
462 OS <<
"..., " << *C.Nodes.back();
499 bool isParentOf(
const SCC &
C)
const;
507 bool isAncestorOf(
const SCC &C)
const;
583 OS <<
"..., " << *RC.SCCs.back();
611 void handleTrivialEdgeInsertion(
Node &SourceN,
Node &TargetN);
627 return SCCs.
begin() + SCCIndices.
find(&C)->second;
634 bool isParentOf(
const RefSCC &RC)
const;
641 bool isAncestorOf(
const RefSCC &RC)
const;
696 bool switchInternalEdgeToCall(
706 void switchTrivialInternalEdgeToRef(
Node &SourceN,
Node &TargetN);
733 void switchOutgoingEdgeToCall(
Node &SourceN,
Node &TargetN);
739 void switchOutgoingEdgeToRef(
Node &SourceN,
Node &TargetN);
753 void insertInternalRefEdge(
Node &SourceN,
Node &TargetN);
801 void removeOutgoingEdge(
Node &SourceN,
Node &TargetN);
853 void insertTrivialCallEdge(
Node &SourceN,
Node &TargetN);
864 void insertTrivialRefEdge(
Node &SourceN,
Node &TargetN);
888 std::forward_iterator_tag, RefSCC> {
907 if (Index == (
int)G.PostOrderRefSCCs.size())
911 return G.PostOrderRefSCCs[
Index];
916 return G == Arg.G && RC == Arg.RC;
921 using iterator_facade_base::operator++;
923 assert(RC &&
"Cannot increment the end iterator!");
924 RC = getRC(*G, G->RefSCCIndices.find(RC)->second + 1);
945 if (!EntryEdges.empty())
946 assert(!PostOrderRefSCCs.empty() &&
947 "Must form RefSCCs before iterating them!");
951 if (!EntryEdges.empty())
952 assert(!PostOrderRefSCCs.empty() &&
953 "Must form RefSCCs before iterating them!");
955 postorder_ref_scc_iterator::IsAtEndT());
977 return &
C->getOuterRefSCC();
985 Node *&N = NodeMap[&
F];
989 return insertInto(
F, N);
997 return LibFunctions.getArrayRef();
1024 return insertEdge(
get(Source),
get(Target), EK);
1073 template <
typename CallbackT>
1076 CallbackT Callback) {
1077 while (!Worklist.
empty()) {
1080 if (
Function *F = dyn_cast<Function>(C)) {
1096 if (Visited.
insert(cast<Constant>(
Op)).second)
1147 void updateGraphPtrs();
1152 template <
typename... Ts>
SCC *createSCC(Ts &&...
Args) {
1159 template <
typename... Ts>
RefSCC *createRefSCC(Ts &&...
Args) {
1174 template <
typename RootsT,
typename GetBeginT,
typename GetEndT,
1175 typename GetNodeT,
typename FormSCCCallbackT>
1176 static void buildGenericSCCs(RootsT &&Roots, GetBeginT &&GetBegin,
1177 GetEndT &&GetEnd, GetNodeT &&GetNode,
1178 FormSCCCallbackT &&FormSCC);
1187 int getRefSCCIndex(
RefSCC &RC) {
1188 auto IndexIt = RefSCCIndices.
find(&RC);
1189 assert(IndexIt != RefSCCIndices.
end() &&
"RefSCC doesn't have an index!");
1190 assert(PostOrderRefSCCs[IndexIt->second] == &RC &&
1191 "Index does not point back at RC!");
1192 return IndexIt->second;
1199 inline LazyCallGraph::Edge::operator
bool()
const {
1204 assert(*
this &&
"Queried a null edge!");
1209 assert(*
this &&
"Queried a null edge!");
1214 assert(*
this &&
"Queried a null edge!");
1219 assert(*
this &&
"Queried a null edge!");
1288 #endif // LLVM_ANALYSIS_LAZYCALLGRAPH_H
EdgeSequence::iterator end()
void insertEdge(Node &SourceN, Node &TargetN, Edge::Kind EK)
Update the call graph after inserting a new edge.
void setInt(IntType IntVal)
iterator_range< call_iterator > calls()
call_iterator & operator++()
void removeEdge(Node &SourceN, Node &TargetN)
Update the call graph after deleting an edge.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
EdgeSequence & populate()
Populate the edges of this node if necessary.
PointerTy getPointer() const
A Module instance is used to store all the information related to an LLVM module. ...
friend raw_ostream & operator<<(raw_ostream &OS, const RefSCC &RC)
Print a short description useful for debugging or logging.
Kind
The kind of edge in the graph.
static NodeRef getEntryNode(NodeRef N)
void push_back(const T &Elt)
The edge sequence object.
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
SCC * lookupSCC(Node &N) const
Lookup a function's SCC in the graph.
Function & getFunction() const
An efficient, type-erasing, non-owning reference to a callable.
A pass which prints the call graph as a DOT file to a raw_ostream.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
RefSCC * lookupRefSCC(Node &N) const
Lookup a function's RefSCC in the graph.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
friend raw_ostream & operator<<(raw_ostream &OS, const Node &N)
Print the name of this node's function.
The address of a basic block.
RefSCC & getOuterRefSCC() const
bool isAncestorOf(const SCC &C) const
Test if this SCC is an ancestor of C.
StringRef getName() const
amdgpu Simplify well known AMD library false Value Value const Twine & Name
LazyCallGraph(Module &M, TargetLibraryInfo &TLI)
Construct a graph for the given module.
call_iterator call_begin()
bool isLibFunction(Function &F) const
Test whether a function is a known and defined library function tracked by the call graph...
EdgeSequence::iterator begin()
postorder_ref_scc_iterator postorder_ref_scc_begin()
static ChildIteratorType child_begin(NodeRef N)
A RefSCC of the call graph.
A CRTP mix-in to automatically provide informational APIs needed for passes.
A lazily constructed view of the call graph of a module.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Function & getFunction() const
Get the function referenced by this edge.
LazyCallGraph & operator=(LazyCallGraph &&RHS)
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
iterator find(const_arg_type_t< KeyT > Val)
friend raw_ostream & operator<<(raw_ostream &OS, const SCC &C)
Print a short descrtiption useful for debugging or logging.
bool isDead() const
Tests whether this is actually a dead node and no longer valid.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
An iterator used for the edges to both entry nodes and child nodes.
PointerIntPair - This class implements a pair of a pointer and small integer.
CRTP base class for adapting an iterator to a different type.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Node & getNode() const
Get the call graph node referenced by this edge.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::reverse_iterator< iterator > reverse_iterator
A CRTP mix-in that provides informational APIs needed for analysis passes.
bool operator!=(const Node &N) const
A node in the call graph.
SCC & operator[](int Idx)
A class used to represent edges in the call graph.
bool isChildOf(const SCC &C) const
Test if this SCC is a child of C.
Edge & operator[](Node &N)
T * Allocate(size_t num=1)
Allocate space for an array of objects without constructing them.
bool operator==(const postorder_ref_scc_iterator &Arg) const
bool isParentOf(const RefSCC &RC) const
Test if this RefSCC is a parent of RC.
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
A SetVector that performs no allocations if smaller than a certain size.
postorder_ref_scc_iterator & operator++()
void removeDeadFunction(Function &F)
Remove a dead function from the call graph (typically to delete it).
LazyCallGraph run(Module &M, ModuleAnalysisManager &AM)
Compute the LazyCallGraph for the module M.
bool isParentOf(const SCC &C) const
Test if this SCC is a parent of C.
reference operator*() const
std::string getName() const
Provide a short name by printing this RefSCC to a std::string.
Provides information about what library functions are available for the current target.
ArrayRef< Function * > getLibFunctions() const
Get the sequence of known and defined library functions.
An iterator type that allows iterating over the pointees via some other iterator. ...
LLVM_NODISCARD T pop_back_val()
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Node * lookup(const Function &F) const
Lookup a function in the graph which has already been scanned and added.
A range adaptor for a pair of iterators.
Target - Wrapper for Target specific information.
EdgeSequence * operator->() const
An iterator over specifically call edges.
typename SuperClass::iterator iterator
static void clear(coro::Shape &Shape)
bool isDescendantOf(const SCC &C) const
Test if this SCC is a descendant of C.
amdgpu Simplify well known AMD library false Value Value * Arg
LazyCallGraph & getGraph() const
A post-order depth-first RefSCC iterator over the call graph.
bool isAncestorOf(const RefSCC &RC) const
Test if this RefSCC is an ancestor of RC.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
iterator find(SCC &C) const
static NodeRef getEntryNode(NodeRef N)
LLVM_NODISCARD bool empty() const
A pass which prints the call graph to a raw_ostream.
StringRef getName() const
Return a constant reference to the value's name.
iterator_range< value_op_iterator > operand_values()
bool operator==(const Node &N) const
Equality is defined as address equality.
static ChildIteratorType child_end(NodeRef N)
bool isPopulated() const
Tests whether the node has been populated with edges.
An analysis pass which computes the call graph for a module.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Analysis pass providing the TargetLibraryInfo.
void removeEdge(Function &Source, Function &Target)
Update the call graph after deleting an edge.
std::string getName() const
Provide a short name by printing this SCC to a std::string.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
LLVM Value Representation.
An SCC of the call graph.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
bool operator==(uint64_t V1, const APInt &V2)
This header defines various interfaces for pass management in LLVM.
void insertEdge(Function &Source, Function &Target, Edge::Kind EK)
Update the call graph after inserting a new edge.
postorder_ref_scc_iterator postorder_ref_scc_end()
static void visitReferences(SmallVectorImpl< Constant *> &Worklist, SmallPtrSetImpl< Constant *> &Visited, CallbackT Callback)
Recursively visits the defined functions whose address is reachable from every constant in the Workli...
static ChildIteratorType child_begin(NodeRef N)
bool isDescendantOf(const RefSCC &RC) const
Test if this RefSCC is a descendant of RC.
iterator_range< postorder_ref_scc_iterator > postorder_ref_sccs()
A special type used by analysis passes to provide an address that identifies that particular analysis...
bool isCall() const
Test whether the edge represents a direct call to a function.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isChildOf(const RefSCC &RC) const
Test if this RefSCC is a child of RC.
static ChildIteratorType child_end(NodeRef N)
Kind getKind() const
Returnss the Kind of the edge.
EdgeSequence & operator*() const