annotate mlir/lib/Transforms/ViewOpGraph.cpp @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 0572611fdcc8
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- ViewOpGraph.cpp - View/write op graphviz graphs --------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "mlir/Transforms/ViewOpGraph.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
10 #include "PassDetail.h"
150
anatofuz
parents:
diff changeset
11 #include "mlir/IR/Block.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
12 #include "mlir/IR/BuiltinTypes.h"
150
anatofuz
parents:
diff changeset
13 #include "mlir/IR/Operation.h"
anatofuz
parents:
diff changeset
14 #include "llvm/Support/CommandLine.h"
anatofuz
parents:
diff changeset
15
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
16 using namespace mlir;
150
anatofuz
parents:
diff changeset
17
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
18 /// Return the size limits for eliding large attributes.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
19 static int64_t getLargeAttributeSizeLimit() {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
20 // Use the default from the printer flags if possible.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
21 if (Optional<int64_t> limit = OpPrintingFlags().getLargeElementsAttrLimit())
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
22 return *limit;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
23 return 16;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
24 }
150
anatofuz
parents:
diff changeset
25
anatofuz
parents:
diff changeset
26 namespace llvm {
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 // Specialize GraphTraits to treat Block as a graph of Operations as nodes and
anatofuz
parents:
diff changeset
29 // uses as edges.
anatofuz
parents:
diff changeset
30 template <> struct GraphTraits<Block *> {
anatofuz
parents:
diff changeset
31 using GraphType = Block *;
anatofuz
parents:
diff changeset
32 using NodeRef = Operation *;
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 using ChildIteratorType = Operation::user_iterator;
anatofuz
parents:
diff changeset
35 static ChildIteratorType child_begin(NodeRef n) { return n->user_begin(); }
anatofuz
parents:
diff changeset
36 static ChildIteratorType child_end(NodeRef n) { return n->user_end(); }
anatofuz
parents:
diff changeset
37
anatofuz
parents:
diff changeset
38 // Operation's destructor is private so use Operation* instead and use
anatofuz
parents:
diff changeset
39 // mapped iterator.
anatofuz
parents:
diff changeset
40 static Operation *AddressOf(Operation &op) { return &op; }
anatofuz
parents:
diff changeset
41 using nodes_iterator = mapped_iterator<Block::iterator, decltype(&AddressOf)>;
anatofuz
parents:
diff changeset
42 static nodes_iterator nodes_begin(Block *b) {
anatofuz
parents:
diff changeset
43 return nodes_iterator(b->begin(), &AddressOf);
anatofuz
parents:
diff changeset
44 }
anatofuz
parents:
diff changeset
45 static nodes_iterator nodes_end(Block *b) {
anatofuz
parents:
diff changeset
46 return nodes_iterator(b->end(), &AddressOf);
anatofuz
parents:
diff changeset
47 }
anatofuz
parents:
diff changeset
48 };
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 // Specialize DOTGraphTraits to produce more readable output.
anatofuz
parents:
diff changeset
51 template <> struct DOTGraphTraits<Block *> : public DefaultDOTGraphTraits {
anatofuz
parents:
diff changeset
52 using DefaultDOTGraphTraits::DefaultDOTGraphTraits;
anatofuz
parents:
diff changeset
53 static std::string getNodeLabel(Operation *op, Block *);
anatofuz
parents:
diff changeset
54 };
anatofuz
parents:
diff changeset
55
anatofuz
parents:
diff changeset
56 std::string DOTGraphTraits<Block *>::getNodeLabel(Operation *op, Block *b) {
anatofuz
parents:
diff changeset
57 // Reuse the print output for the node labels.
anatofuz
parents:
diff changeset
58 std::string ostr;
anatofuz
parents:
diff changeset
59 raw_string_ostream os(ostr);
anatofuz
parents:
diff changeset
60 os << op->getName() << "\n";
anatofuz
parents:
diff changeset
61
anatofuz
parents:
diff changeset
62 if (!op->getLoc().isa<UnknownLoc>()) {
anatofuz
parents:
diff changeset
63 os << op->getLoc() << "\n";
anatofuz
parents:
diff changeset
64 }
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 // Print resultant types
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
67 llvm::interleaveComma(op->getResultTypes(), os);
150
anatofuz
parents:
diff changeset
68 os << "\n";
anatofuz
parents:
diff changeset
69
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
70 // A value used to elide large container attribute.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
71 int64_t largeAttrLimit = getLargeAttributeSizeLimit();
150
anatofuz
parents:
diff changeset
72 for (auto attr : op->getAttrs()) {
anatofuz
parents:
diff changeset
73 os << '\n' << attr.first << ": ";
anatofuz
parents:
diff changeset
74 // Always emit splat attributes.
anatofuz
parents:
diff changeset
75 if (attr.second.isa<SplatElementsAttr>()) {
anatofuz
parents:
diff changeset
76 attr.second.print(os);
anatofuz
parents:
diff changeset
77 continue;
anatofuz
parents:
diff changeset
78 }
anatofuz
parents:
diff changeset
79
anatofuz
parents:
diff changeset
80 // Elide "big" elements attributes.
anatofuz
parents:
diff changeset
81 auto elements = attr.second.dyn_cast<ElementsAttr>();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
82 if (elements && elements.getNumElements() > largeAttrLimit) {
150
anatofuz
parents:
diff changeset
83 os << std::string(elements.getType().getRank(), '[') << "..."
anatofuz
parents:
diff changeset
84 << std::string(elements.getType().getRank(), ']') << " : "
anatofuz
parents:
diff changeset
85 << elements.getType();
anatofuz
parents:
diff changeset
86 continue;
anatofuz
parents:
diff changeset
87 }
anatofuz
parents:
diff changeset
88
anatofuz
parents:
diff changeset
89 auto array = attr.second.dyn_cast<ArrayAttr>();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
90 if (array && static_cast<int64_t>(array.size()) > largeAttrLimit) {
150
anatofuz
parents:
diff changeset
91 os << "[...]";
anatofuz
parents:
diff changeset
92 continue;
anatofuz
parents:
diff changeset
93 }
anatofuz
parents:
diff changeset
94
anatofuz
parents:
diff changeset
95 // Print all other attributes.
anatofuz
parents:
diff changeset
96 attr.second.print(os);
anatofuz
parents:
diff changeset
97 }
anatofuz
parents:
diff changeset
98 return os.str();
anatofuz
parents:
diff changeset
99 }
anatofuz
parents:
diff changeset
100
anatofuz
parents:
diff changeset
101 } // end namespace llvm
anatofuz
parents:
diff changeset
102
anatofuz
parents:
diff changeset
103 namespace {
anatofuz
parents:
diff changeset
104 // PrintOpPass is simple pass to write graph per function.
anatofuz
parents:
diff changeset
105 // Note: this is a module pass only to avoid interleaving on the same ostream
anatofuz
parents:
diff changeset
106 // due to multi-threading over functions.
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
107 class PrintOpPass : public ViewOpGraphPassBase<PrintOpPass> {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
108 public:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
109 PrintOpPass(raw_ostream &os, bool shortNames, const Twine &title) : os(os) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
110 this->shortNames = shortNames;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
111 this->title = title.str();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
112 }
150
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 std::string getOpName(Operation &op) {
anatofuz
parents:
diff changeset
115 auto symbolAttr =
anatofuz
parents:
diff changeset
116 op.getAttrOfType<StringAttr>(SymbolTable::getSymbolAttrName());
anatofuz
parents:
diff changeset
117 if (symbolAttr)
anatofuz
parents:
diff changeset
118 return std::string(symbolAttr.getValue());
anatofuz
parents:
diff changeset
119 ++unnamedOpCtr;
anatofuz
parents:
diff changeset
120 return (op.getName().getStringRef() + llvm::utostr(unnamedOpCtr)).str();
anatofuz
parents:
diff changeset
121 }
anatofuz
parents:
diff changeset
122
anatofuz
parents:
diff changeset
123 // Print all the ops in a module.
anatofuz
parents:
diff changeset
124 void processModule(ModuleOp module) {
anatofuz
parents:
diff changeset
125 for (Operation &op : module) {
anatofuz
parents:
diff changeset
126 // Modules may actually be nested, recurse on nesting.
anatofuz
parents:
diff changeset
127 if (auto nestedModule = dyn_cast<ModuleOp>(op)) {
anatofuz
parents:
diff changeset
128 processModule(nestedModule);
anatofuz
parents:
diff changeset
129 continue;
anatofuz
parents:
diff changeset
130 }
anatofuz
parents:
diff changeset
131 auto opName = getOpName(op);
anatofuz
parents:
diff changeset
132 for (Region &region : op.getRegions()) {
anatofuz
parents:
diff changeset
133 for (auto indexed_block : llvm::enumerate(region)) {
anatofuz
parents:
diff changeset
134 // Suffix block number if there are more than 1 block.
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
135 auto blockName = llvm::hasSingleElement(region)
150
anatofuz
parents:
diff changeset
136 ? ""
anatofuz
parents:
diff changeset
137 : ("__" + llvm::utostr(indexed_block.index()));
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
138 llvm::WriteGraph(os, &indexed_block.value(), shortNames,
150
anatofuz
parents:
diff changeset
139 Twine(title) + opName + blockName);
anatofuz
parents:
diff changeset
140 }
anatofuz
parents:
diff changeset
141 }
anatofuz
parents:
diff changeset
142 }
anatofuz
parents:
diff changeset
143 }
anatofuz
parents:
diff changeset
144
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
145 void runOnOperation() override { processModule(getOperation()); }
150
anatofuz
parents:
diff changeset
146
anatofuz
parents:
diff changeset
147 private:
anatofuz
parents:
diff changeset
148 raw_ostream &os;
anatofuz
parents:
diff changeset
149 int unnamedOpCtr = 0;
anatofuz
parents:
diff changeset
150 };
anatofuz
parents:
diff changeset
151 } // namespace
anatofuz
parents:
diff changeset
152
anatofuz
parents:
diff changeset
153 void mlir::viewGraph(Block &block, const Twine &name, bool shortNames,
anatofuz
parents:
diff changeset
154 const Twine &title, llvm::GraphProgram::Name program) {
anatofuz
parents:
diff changeset
155 llvm::ViewGraph(&block, name, shortNames, title, program);
anatofuz
parents:
diff changeset
156 }
anatofuz
parents:
diff changeset
157
anatofuz
parents:
diff changeset
158 raw_ostream &mlir::writeGraph(raw_ostream &os, Block &block, bool shortNames,
anatofuz
parents:
diff changeset
159 const Twine &title) {
anatofuz
parents:
diff changeset
160 return llvm::WriteGraph(os, &block, shortNames, title);
anatofuz
parents:
diff changeset
161 }
anatofuz
parents:
diff changeset
162
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
163 std::unique_ptr<OperationPass<ModuleOp>>
150
anatofuz
parents:
diff changeset
164 mlir::createPrintOpGraphPass(raw_ostream &os, bool shortNames,
anatofuz
parents:
diff changeset
165 const Twine &title) {
anatofuz
parents:
diff changeset
166 return std::make_unique<PrintOpPass>(os, shortNames, title);
anatofuz
parents:
diff changeset
167 }