12#include <mlir/Analysis/CallGraph.h>
13#include <mlir/Interfaces/CallInterfaces.h>
15#include <llvm/ADT/GraphTraits.h>
16#include <llvm/ADT/MapVector.h>
17#include <llvm/ADT/PointerIntPair.h>
18#include <llvm/ADT/SCCIterator.h>
19#include <llvm/ADT/SetVector.h>
25class SymbolTableCollection;
40 enum class Kind : std::uint8_t {
60 bool isAbstract()
const {
return targetAndKind.getInt() == Kind::Abstract; }
63 bool isCall()
const {
return targetAndKind.getInt() == Kind::Call; }
66 bool isChild()
const {
return targetAndKind.getInt() == Kind::Child; }
76 return source == edge.source && targetAndKind == edge.targetAndKind;
80 Edge(CallGraphNode *src, CallGraphNode *target, Kind kind)
81 :
source(src), targetAndKind(target, kind) {}
82 Edge(
CallGraphNode *src, llvm::PointerIntPair<CallGraphNode *, 2, Kind> tgtAndKind)
83 :
source(src), targetAndKind(tgtAndKind) {}
90 llvm::PointerIntPair<CallGraphNode *, 2, Kind> targetAndKind;
120 using iterator = mlir::SmallVectorImpl<Edge>::const_iterator;
124 llvm::iterator_range<iterator>
edgesOut()
const {
return llvm::make_range(
begin(),
end()); }
132 using SourceInfo = mlir::DenseMapInfo<CallGraphNode *>;
133 using BaseInfo = mlir::DenseMapInfo<llvm::PointerIntPair<CallGraphNode *, 2, Edge::Kind>>;
135 static Edge getEmptyKey() {
return Edge(
nullptr, BaseInfo::getEmptyKey()); }
136 static Edge getTombstoneKey() {
return Edge(
nullptr, BaseInfo::getTombstoneKey()); }
137 static unsigned getHashValue(
const Edge &edge) {
138 return SourceInfo::getHashValue(edge.source) ^ BaseInfo::getHashValue(edge.targetAndKind);
140 static bool isEqual(
const Edge &lhs,
const Edge &rhs) {
return lhs == rhs; }
143 CallGraphNode(mlir::Region *callable) : callableRegion(callable) {}
146 void addEdge(CallGraphNode *node, Edge::Kind kind);
151 mlir::Region *callableRegion;
154 mlir::SetVector<Edge, mlir::SmallVector<Edge, 4>, llvm::SmallDenseSet<Edge, 4, EdgeKeyInfo>>
165 using NodeMapT = llvm::MapVector<mlir::Region *, std::unique_ptr<CallGraphNode>>;
169 class NodeIterator final
170 :
public llvm::mapped_iterator<
171 NodeMapT::const_iterator, CallGraphNode *(*)(const NodeMapT::value_type &)> {
172 static CallGraphNode *unwrap(
const NodeMapT::value_type &value) {
return value.second.get(); }
176 NodeIterator(NodeMapT::const_iterator it)
177 : llvm::mapped_iterator<
178 NodeMapT::const_iterator,
CallGraphNode *(*)(
const NodeMapT::value_type &)>(
210 resolveCallable(mlir::CallOpInterface call, mlir::SymbolTableCollection &symbolTable)
const;
220 size_t size()
const {
return nodes.size(); }
224 void print(llvm::raw_ostream &os)
const;
242template <>
struct GraphTraits<const
llzk::CallGraphNode *> {
255struct GraphTraits<const
llzk::CallGraph *> :
public GraphTraits<const llzk::CallGraphNode *> {
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.
mlir::CallableOpInterface getCalledFunction() const
Returns the called function that the callable region represents.
void addAbstractEdge(CallGraphNode *node)
Adds an abstract reference edge to the given node.
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