12#include <mlir/Analysis/CallGraph.h>
14#include <llvm/ADT/GraphTraits.h>
15#include <llvm/ADT/MapVector.h>
16#include <llvm/ADT/PointerIntPair.h>
17#include <llvm/ADT/SCCIterator.h>
18#include <llvm/ADT/SetVector.h>
24class SymbolTableCollection;
63 bool isAbstract()
const {
return targetAndKind.getInt() == Kind::Abstract; }
66 bool isCall()
const {
return targetAndKind.getInt() == Kind::Call; }
69 bool isChild()
const {
return targetAndKind.getInt() == Kind::Child; }
79 return source == edge.source && targetAndKind == edge.targetAndKind;
83 Edge(CallGraphNode *src, CallGraphNode *target, Kind kind)
84 :
source(src), targetAndKind(target, kind) {}
85 Edge(
CallGraphNode *src, llvm::PointerIntPair<CallGraphNode *, 2, Kind> targetAndKind)
86 :
source(src), targetAndKind(targetAndKind) {}
93 llvm::PointerIntPair<CallGraphNode *, 2, Kind> targetAndKind;
123 using iterator = mlir::SmallVectorImpl<Edge>::const_iterator;
127 llvm::iterator_range<iterator>
edgesOut()
const {
return llvm::make_range(
begin(),
end()); }
135 using SourceInfo = mlir::DenseMapInfo<CallGraphNode *>;
136 using BaseInfo = mlir::DenseMapInfo<llvm::PointerIntPair<CallGraphNode *, 2, Edge::Kind>>;
138 static Edge getEmptyKey() {
return Edge(
nullptr, BaseInfo::getEmptyKey()); }
139 static Edge getTombstoneKey() {
return Edge(
nullptr, BaseInfo::getTombstoneKey()); }
140 static unsigned getHashValue(
const Edge &edge) {
141 return SourceInfo::getHashValue(edge.source) ^ BaseInfo::getHashValue(edge.targetAndKind);
143 static bool isEqual(
const Edge &lhs,
const Edge &rhs) {
return lhs == rhs; }
146 CallGraphNode(mlir::Region *callableRegion) : callableRegion(callableRegion) {}
149 void addEdge(CallGraphNode *node, Edge::Kind kind);
154 mlir::Region *callableRegion;
157 mlir::SetVector<Edge, mlir::SmallVector<Edge, 4>, llvm::SmallDenseSet<Edge, 4, EdgeKeyInfo>>
168 using NodeMapT = llvm::MapVector<mlir::Region *, std::unique_ptr<CallGraphNode>>;
172 class NodeIterator final
173 :
public llvm::mapped_iterator<
174 NodeMapT::const_iterator, CallGraphNode *(*)(const NodeMapT::value_type &)> {
175 static CallGraphNode *unwrap(
const NodeMapT::value_type &value) {
return value.second.get(); }
179 NodeIterator(NodeMapT::const_iterator it)
180 : llvm::mapped_iterator<
181 NodeMapT::const_iterator,
CallGraphNode *(*)(
const NodeMapT::value_type &)>(
213 resolveCallable(mlir::CallOpInterface call, mlir::SymbolTableCollection &symbolTable)
const;
223 size_t size()
const {
return nodes.size(); }
227 void print(llvm::raw_ostream &os)
const;
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation source
This class represents a directed edge between two nodes in the callgraph.
bool isChild() const
Returns true if this edge represents a Child edge.
CallGraphNode * getTarget() const
Returns the target node for this edge.
bool operator==(const Edge &edge) const
bool isCall() const
Returns true if this edge represents a Call edge.
CallGraphNode * getSource() const
Returns the source node of this edge.
bool isAbstract() const
Returns true if this edge represents an Abstract edge.
friend class CallGraphNode
This is a simple port of the mlir::CallGraphNode with llzk::CallGraph as a friend class,...
bool isExternal() const
Returns true if this node is an external node.
mlir::SmallVectorImpl< Edge >::const_iterator iterator
Iterator over the outgoing edges of this node.
llvm::iterator_range< iterator > edgesOut() const
mlir::Region * getCallableRegion() const
Returns the callable region this node represents.
void addChildEdge(CallGraphNode *child)
Adds a reference edge to the given child node.
bool hasChildren() const
Returns true if this node has any child edges.
void addCallEdge(CallGraphNode *node)
Add an outgoing call edge from this node.
void addAbstractEdge(CallGraphNode *node)
Adds an abstract reference edge to the given node.
llzk::function::FuncDefOp getCalledFunction() const
Returns the called function that the callable region represents.
This is a port of mlir::CallGraph that has been adapted to use the custom symbol lookup helpers (see ...
CallGraph(mlir::Operation *op)
CallGraphNode * getExternalCallerNode() const
Return the callgraph node representing an external caller.
NodeIterator iterator
An iterator over the nodes of the graph.
void dump() const
Dump the graph in a human readable format.
void print(llvm::raw_ostream &os) const
void eraseNode(CallGraphNode *node)
Erase the given node from the callgraph.
CallGraphNode * resolveCallable(mlir::CallOpInterface call, mlir::SymbolTableCollection &symbolTable) const
Resolve the callable for given callee to a node in the callgraph, or the external node if a valid nod...
CallGraphNode * lookupNode(mlir::Region *region) const
Lookup a call graph node for the given region, or nullptr if none is registered.
CallGraphNode * getUnknownCalleeNode() const
Return the callgraph node representing an indirect callee.
CallGraphNode * getOrAddNode(mlir::Region *region, CallGraphNode *parentNode)
Get or add a call graph node for the given region.
const llzk::CallGraphNode * NodeRef
static ChildIteratorType child_begin(NodeRef node)
static NodeRef getEntryNode(NodeRef node)
mapped_iterator< llzk::CallGraphNode::iterator, decltype(&unwrap)> ChildIteratorType
static NodeRef unwrap(const llzk::CallGraphNode::Edge &edge)
static ChildIteratorType child_end(NodeRef node)
static nodes_iterator nodes_begin(llzk::CallGraph *cg)
static nodes_iterator nodes_end(llzk::CallGraph *cg)
static NodeRef getEntryNode(const llzk::CallGraph *cg)
The entry node into the graph is the external node.
llzk::CallGraph::iterator nodes_iterator