14#include <mlir/IR/BuiltinOps.h>
15#include <mlir/IR/SymbolTable.h>
17#include <llvm/ADT/GraphTraits.h>
18#include <llvm/ADT/MapVector.h>
19#include <llvm/ADT/SetVector.h>
20#include <llvm/Support/DOTGraphTraits.h>
26class SymbolUseGraphNode {
27 mlir::ModuleOp symbolPathRoot;
28 mlir::SymbolRefAttr symbolPath;
29 bool isStructConstParam;
33 mlir::SetVector<SymbolUseGraphNode *> predecessors;
35 mlir::SetVector<SymbolUseGraphNode *> successors;
37 SymbolUseGraphNode(mlir::ModuleOp pathRoot, mlir::SymbolRefAttr path)
38 : symbolPathRoot(pathRoot), symbolPath(path), isStructConstParam(
false) {
39 assert(pathRoot &&
"'pathRoot' cannot be nullptr");
40 assert(path &&
"'path' cannot be nullptr");
44 SymbolUseGraphNode() : symbolPathRoot(
nullptr), symbolPath(
nullptr), isStructConstParam(
false) {}
47 static bool isRealNodeImpl(
const SymbolUseGraphNode *node) {
return node->symbolPath !=
nullptr; }
50 void addSuccessor(SymbolUseGraphNode *node);
53 void removeSuccessor(SymbolUseGraphNode *node);
74 return llvm::find_if(predecessors, isRealNodeImpl) != predecessors.end();
76 size_t numPredecessors()
const {
return llvm::count_if(predecessors, isRealNodeImpl); }
80 return llvm::find_if(successors, isRealNodeImpl) != successors.end();
82 size_t numSuccessors()
const {
return llvm::count_if(successors, isRealNodeImpl); }
86 mlir::SetVector<SymbolUseGraphNode *>::const_iterator, bool (*)(
const SymbolUseGraphNode *)>;
95 return llvm::make_filter_range(predecessors, isRealNodeImpl);
100 return llvm::make_filter_range(successors, isRealNodeImpl);
103 mlir::FailureOr<SymbolLookupResultUntyped>
104 lookupSymbol(mlir::SymbolTableCollection &tables,
bool reportMissing =
true)
const;
108 void print(llvm::raw_ostream &os)
const;
115 using NodeMapKeyT = std::pair<mlir::ModuleOp, mlir::SymbolRefAttr>;
117 using NodeMapT = llvm::MapVector<NodeMapKeyT, std::unique_ptr<SymbolUseGraphNode>>;
133 class NodeIterator final
134 :
public llvm::mapped_iterator<
135 NodeMapT::const_iterator, SymbolUseGraphNode *(*)(const NodeMapT::value_type &)> {
137 return value.second.get();
142 NodeIterator(NodeMapT::const_iterator it)
143 : llvm::mapped_iterator<
151 mlir::ModuleOp pathRoot, mlir::SymbolRefAttr path,
SymbolUseGraphNode *predecessorNode
155 void buildGraph(mlir::SymbolOpInterface symbolOp);
171 size_t
size() const {
return nodes.size(); }
179 inline llvm::iterator_range<roots_iterator>
rootsIter()
const {
189 inline llvm::iterator_range<iterator>
nodesIter()
const {
190 return llvm::make_range(
begin(),
end());
195 void print(llvm::raw_ostream &os)
const;
218 :
public GraphTraits<const llzk::SymbolUseGraphNode *> {
245 :
public GraphTraits<Inverse<const llzk::SymbolUseGraphNode *>> {
246 using GraphType = Inverse<const llzk::SymbolUseGraph *>;
This file defines methods symbol lookup across LLZK operations and included files.
size_t numSuccessors() const
mlir::FailureOr< SymbolLookupResultUntyped > lookupSymbol(mlir::SymbolTableCollection &tables, bool reportMissing=true) const
bool isRealNode() const
Return 'false' iff this node is an artificial node created for the graph head/tail.
bool hasSuccessor() const
Return true if this node has any successors.
iterator predecessors_begin() const
size_t numPredecessors() const
std::string toString() const
Print the node in a human readable format.
iterator predecessors_end() const
bool isStructParam() const
Return true iff the symbol is a struct constant parameter name.
bool hasPredecessor() const
Return true if this node has any predecessors.
iterator successors_begin() const
llvm::iterator_range< iterator > predecessorIter() const
Range over predecessor nodes.
mlir::SymbolRefAttr getSymbolPath() const
The symbol path+name relative to the closest root ModuleOp.
iterator successors_end() const
mlir::ModuleOp getSymbolPathRoot() const
Return the root ModuleOp for the path.
friend class SymbolUseGraph
void print(llvm::raw_ostream &os) const
llvm::iterator_range< iterator > successorIter() const
Range over successor nodes.
llvm::filter_iterator< mlir::SetVector< SymbolUseGraphNode * >::const_iterator, bool(*)(const SymbolUseGraphNode *)> iterator
Iterator over predecessors/successors.
Builds a graph structure representing the relationships between symbols and their uses.
size_t size() const
Return the total number of nodes in the graph.
void dump() const
Dump the graph in a human readable format.
roots_iterator roots_end() const
SymbolUseGraphNode::iterator roots_iterator
Iterator over the root nodes (i.e., nodes that have no predecessors).
llvm::iterator_range< roots_iterator > rootsIter() const
Range over root nodes (i.e., nodes that have no predecessors).
void dumpToDotFile(std::string filename="") const
Dump the graph to file in dot graph format.
roots_iterator roots_begin() const
NodeIterator iterator
An iterator over the nodes of the graph.
SymbolUseGraph(mlir::SymbolOpInterface rootSymbolOp)
llvm::iterator_range< iterator > nodesIter() const
Range over all nodes in the graph.
void print(llvm::raw_ostream &os) const
const SymbolUseGraphNode * lookupNode(mlir::ModuleOp pathRoot, mlir::SymbolRefAttr path) const
Return the existing node for the symbol reference relative to the given module, else nullptr.
DOTGraphTraits(bool isSimple=false)
std::string getNodeLabel(NodeRef n, GraphType)
const llzk::SymbolUseGraphNode * NodeRef
const llzk::SymbolUseGraph * GraphType
static std::string getGraphName(GraphType)
DOTGraphTraits(bool isSimple=false)
std::string getNodeLabel(NodeRef n, GraphType g)
const llzk::SymbolUseGraphNode * NodeRef
llzk::SymbolUseGraphNode::iterator ChildIteratorType
static ChildIteratorType child_begin(NodeRef node)
static ChildIteratorType child_end(NodeRef node)
static NodeRef getEntryNode(Inverse< NodeRef > node)
static nodes_iterator nodes_begin(GraphType g)
static nodes_iterator nodes_end(GraphType g)
llzk::SymbolUseGraph::iterator nodes_iterator
nodes_iterator/begin/end - Allow iteration over all nodes in the graph.
static NodeRef getEntryNode(GraphType g)
The entry node into the inverse graph is the tail node.
Inverse< const llzk::SymbolUseGraph * > GraphType
static unsigned size(GraphType g)
Return total number of nodes in the graph.
static ChildIteratorType child_end(NodeRef node)
const llzk::SymbolUseGraphNode * NodeRef
llzk::SymbolUseGraphNode::iterator ChildIteratorType
ChildIteratorType/begin/end - Allow iteration over all nodes in the graph.
static NodeRef getEntryNode(NodeRef node)
static ChildIteratorType child_begin(NodeRef node)
static nodes_iterator nodes_begin(GraphType g)
llzk::SymbolUseGraph::iterator nodes_iterator
nodes_iterator/begin/end - Allow iteration over all nodes in the graph.
static unsigned size(GraphType g)
Return total number of nodes in the graph.
const llzk::SymbolUseGraph * GraphType
static NodeRef getEntryNode(GraphType g)
The entry node into the graph is the root node.
static nodes_iterator nodes_end(GraphType g)