18 #include "llvm/ADT/SCCIterator.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/iterator_range.h"
21 #include "llvm/Support/raw_ostream.h"
37 assert(!
isExternal() &&
"the external node has no callable region");
38 return callableRegion;
44 assert(
isExternal() &&
"abstract edges are only valid on external nodes");
45 addEdge(node, Edge::Kind::Abstract);
50 addEdge(node, Edge::Kind::Call);
55 addEdge(child, Edge::Kind::Child);
60 return llvm::any_of(edges, [](
const Edge &edge) {
return edge.
isChild(); });
65 edges.insert({node, kind});
77 if (CallOpInterface call = dyn_cast<CallOpInterface>(op)) {
81 if (resolveCalls && parentNode)
87 if (CallableOpInterface callable = dyn_cast<CallableOpInterface>(op)) {
88 if (
auto *callableRegion = callable.getCallableRegion())
89 parentNode = cg.
getOrAddNode(callableRegion, parentNode);
100 : externalCallerNode(nullptr),
101 unknownCalleeNode(nullptr) {
115 assert(region && isa<CallableOpInterface>(region->
getParentOp()) &&
116 "expected parent operation to be callable");
117 std::unique_ptr<CallGraphNode> &node = nodes[region];
140 const auto *it = nodes.find(region);
141 return it == nodes.end() ? nullptr : it->second.get();
149 Operation *callable = call.resolveCallableInTable(&symbolTable);
150 if (
auto callableOp = dyn_cast_or_null<CallableOpInterface>(callable))
151 if (
auto *node =
lookupNode(callableOp.getCallableRegion()))
166 for (
auto &it : nodes) {
180 os <<
"// ---- CallGraph ----\n";
185 os <<
"<External-Caller-Node>";
189 os <<
"<Unknown-Callee-Node>";
196 << callableRegion->getRegionNumber();
197 auto attrs = parentOp->getAttrDictionary();
199 os <<
" : " << attrs;
202 for (
auto &nodeIt : nodes) {
206 os <<
"// - Node : ";
211 for (
auto &edge : *node) {
215 else if (edge.isChild())
219 emitNodeName(edge.getTarget());
225 os <<
"// -- SCCs --\n";
227 for (
auto &scc : make_range(llvm::scc_begin(
this), llvm::scc_end(
this))) {
228 os <<
"// - SCC : \n";
229 for (
auto &node : scc) {
230 os <<
"// -- Node :";
237 os <<
"// -------------------\n";
static void computeCallGraph(Operation *op, CallGraph &cg, SymbolTableCollection &symbolTable, CallGraphNode *parentNode, bool resolveCalls)
Recursively compute the callgraph edges for the given operation.
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.
This class represents a single callable in the callgraph.
bool isExternal() const
Returns true if this node is an external node.
void addAbstractEdge(CallGraphNode *node)
Adds an abstract reference edge to the given node.
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.
Region * getCallableRegion() const
Returns the callable region this node represents.
void eraseNode(CallGraphNode *node)
Erase the given node from the callgraph.
CallGraphNode * resolveCallable(CallOpInterface call, SymbolTableCollection &symbolTable) const
Resolve the callable for given callee to a node in the callgraph, or the external node if a valid nod...
CallGraphNode * getUnknownCalleeNode() const
Return the callgraph node representing an indirect callee.
CallGraphNode * lookupNode(Region *region) const
Lookup a call graph node for the given region, or nullptr if none is registered.
void dump() const
Dump the graph in a human readable format.
CallGraphNode * getOrAddNode(Region *region, CallGraphNode *parentNode)
Get or add a call graph node for the given region.
void print(raw_ostream &os) const
CallGraphNode * getExternalCallerNode() const
Return the callgraph node representing an external caller.
Operation is the basic unit of execution within MLIR.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
OperationName getName()
The name of an operation is the key identifier for it.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Operation * getParentOp()
Return the parent operation this region is attached to.
This class represents a collection of SymbolTables.
Kind
An enumeration of the kinds of predicates.
Include the generated interface declarations.