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(); });
64void CallGraphNode::addEdge(
CallGraphNode *node, Edge::Kind kind) {
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);
115 assert(region && isa<CallableOpInterface>(region->
getParentOp()) &&
116 "expected parent operation to be callable");
117 std::unique_ptr<CallGraphNode> &node = nodes[region];
131 externalCallerNode.addAbstractEdge(node.get());
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) {
179#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
183 os <<
"// ---- CallGraph ----\n";
188 os <<
"<External-Caller-Node>";
192 os <<
"<Unknown-Callee-Node>";
198 os <<
"'" << callableRegion->getParentOp()->getName() <<
"' - Region #"
199 << callableRegion->getRegionNumber();
200 NamedAttrList attrs(parentOp->getDiscardableAttrDictionary());
201 parentOp->getName().walkInherentAttrs(
204 if (!attrs.
empty()) {
207 os << attr.
getName().getValue() <<
" = ";
214 for (
auto &nodeIt : nodes) {
218 os <<
"// - Node : ";
223 for (
auto &edge : *node) {
227 else if (edge.isChild())
231 emitNodeName(edge.getTarget());
237 os <<
"// -- SCCs --\n";
239 for (
auto &scc : make_range(llvm::scc_begin(
this), llvm::scc_end(
this))) {
240 os <<
"// - SCC : \n";
241 for (
auto &node : scc) {
242 os <<
"// -- Node :";
249 os <<
"// -------------------\n";
static void computeCallGraph(Operation *op, CallGraph &cg, SymbolTableCollection &symbolTable, CallGraphNode *parentNode, bool resolveCalls)
Recursively compute the callgraph edges for the given operation.
Attributes are known-constant values of operations.
void print(raw_ostream &os, bool elideType=false) const
Print the attribute.
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.
CallGraphNode * getUnknownCalleeNode() const
Return the callgraph node representing an indirect callee.
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 * getExternalCallerNode() const
Return the callgraph node representing an external caller.
CallGraphNode * lookupNode(Region *region) const
Lookup a call graph node for the given region, or nullptr if none is registered.
LLVM_DUMP_METHOD 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
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
NamedAttribute represents a combination of a name and an Attribute value.
StringAttr getName() const
Return the name of the attribute.
Attribute getValue() const
Return the value of the attribute.
Operation is the basic unit of execution within MLIR.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
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.
Include the generated interface declarations.