blob: be6573f2a800c74fe4f5d3e49d2b37a145920216 [file] [log] [blame]
Chris Lattner4c95a502018-06-23 16:03:42 -07001//===- AsmPrinter.cpp - MLIR Assembly Printer Implementation --------------===//
2//
3// Copyright 2019 The MLIR Authors.
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16// =============================================================================
17//
18// This file implements the MLIR AsmPrinter class, which is used to implement
19// the various print() methods on the core IR objects.
20//
21//===----------------------------------------------------------------------===//
22
Uday Bondhugulafaf37dd2018-06-29 18:09:29 -070023#include "mlir/IR/AffineExpr.h"
24#include "mlir/IR/AffineMap.h"
Chris Lattner7121b802018-07-04 20:45:39 -070025#include "mlir/IR/Attributes.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070026#include "mlir/IR/CFGFunction.h"
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -070027#include "mlir/IR/MLFunction.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070028#include "mlir/IR/Module.h"
Chris Lattnerff0d5902018-07-05 09:12:11 -070029#include "mlir/IR/OperationSet.h"
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -070030#include "mlir/IR/Statements.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070031#include "mlir/IR/Types.h"
32#include "mlir/Support/STLExtras.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070033#include "llvm/ADT/DenseMap.h"
Uday Bondhugulafaf37dd2018-06-29 18:09:29 -070034#include "llvm/Support/raw_ostream.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070035using namespace mlir;
36
37
Chris Lattner7121b802018-07-04 20:45:39 -070038void Identifier::print(raw_ostream &os) const {
39 os << str();
40}
41
42void Identifier::dump() const {
43 print(llvm::errs());
44}
45
Chris Lattner4c95a502018-06-23 16:03:42 -070046//===----------------------------------------------------------------------===//
MLIR Team4718bc92018-07-17 16:56:54 -070047// Module printing
48//===----------------------------------------------------------------------===//
49
50namespace {
51class ModuleState {
52 public:
53 ModuleState(raw_ostream &os);
54
55 void initialize(const Module *module);
56
57 void print(const Module *module);
58 void print(const Type *type) const;
59 void print(const Function* fn);
60
61 void recordAffineMapReference(const AffineMap* affineMap) {
62 if (affineMapIds.count(affineMap) == 0) {
63 affineMapIds[affineMap] = nextAffineMapId++;
64 }
65 }
66
67 int getAffineMapId(const AffineMap* affineMap) const {
68 auto it = affineMapIds.find(affineMap);
69 if (it == affineMapIds.end()) {
70 return -1;
71 }
72 return it->second;
73 }
74
75 private:
76 // Visit functions.
77 void visitFunction(const Function *fn);
78 void visitExtFunction(const ExtFunction *fn);
79 void visitCFGFunction(const CFGFunction *fn);
80 void visitMLFunction(const MLFunction *fn);
81 void visitType(const Type *type);
82
83 raw_ostream &os;
84 DenseMap<const AffineMap*, int> affineMapIds;
85 int nextAffineMapId = 0;
86};
87} // end anonymous namespace
88
89ModuleState::ModuleState(raw_ostream &os) : os(os) {
90}
91
92// Initializes module state, populating affine map state.
93void ModuleState::initialize(const Module *module) {
94 for (auto fn : module->functionList) {
95 visitFunction(fn);
96 }
97}
98
99// TODO Support visiting other types/instructions when implemented.
100void ModuleState::visitType(const Type *type) {
101 if (type->getKind() == Type::Kind::Function) {
102 // Visit input and result types for functions.
103 auto *funcType = cast<FunctionType>(type);
104 for (auto* input : funcType->getInputs()) {
105 visitType(input);
106 }
107 for (auto* result : funcType->getResults()) {
108 visitType(result);
109 }
110 } else if (type->getKind() == Type::Kind::MemRef) {
111 // Visit affine maps in memref type.
112 auto *memref = cast<MemRefType>(type);
113 for (AffineMap* map : memref->getAffineMaps()) {
114 recordAffineMapReference(map);
115 }
116 }
117}
118
119void ModuleState::visitExtFunction(const ExtFunction *fn) {
120 visitType(fn->getType());
121}
122
123void ModuleState::visitCFGFunction(const CFGFunction *fn) {
124 visitType(fn->getType());
125 // TODO Visit function body instructions.
126}
127
128void ModuleState::visitMLFunction(const MLFunction *fn) {
129 visitType(fn->getType());
130 // TODO Visit function body statements.
131}
132
133void ModuleState::visitFunction(const Function *fn) {
134 switch (fn->getKind()) {
135 case Function::Kind::ExtFunc:
136 return visitExtFunction(cast<ExtFunction>(fn));
137 case Function::Kind::CFGFunc:
138 return visitCFGFunction(cast<CFGFunction>(fn));
139 case Function::Kind::MLFunc:
140 return visitMLFunction(cast<MLFunction>(fn));
141 }
142}
143
144static void printExtFunction(const ExtFunction* fn,
145 const ModuleState* moduleState, raw_ostream &os);
146
147
148static void printCFGFunction(const CFGFunction* fn,
149 const ModuleState* moduleState, raw_ostream &os);
150
151static void printMLFunction(const MLFunction* fn,
152 const ModuleState* moduleState, raw_ostream &os);
153
154// Prints function with initialized module state.
155void ModuleState::print(const Function* fn) {
156 switch (fn->getKind()) {
157 case Function::Kind::ExtFunc:
158 return printExtFunction(cast<ExtFunction>(fn), this, os);
159 case Function::Kind::CFGFunc:
160 return printCFGFunction(cast<CFGFunction>(fn), this, os);
161 case Function::Kind::MLFunc:
162 return printMLFunction(cast<MLFunction>(fn), this, os);
163 }
164}
165
166// Prints affine map identifier.
167static void printAffineMapId(unsigned affineMapId, raw_ostream &os) {
168 os << "#map" << affineMapId;
169}
170
171void ModuleState::print(const Module *module) {
172 for (const auto& mapAndId : affineMapIds) {
173 printAffineMapId(mapAndId.second, os);
174 os << " = ";
175 mapAndId.first->print(os);
176 os << '\n';
177 }
178 for (auto *fn : module->functionList)
179 print(fn);
180}
181
182void ModuleState::print(const Type *type) const {
183 switch (type->getKind()) {
184 case Type::Kind::AffineInt: os << "affineint"; return;
185 case Type::Kind::BF16: os << "bf16"; return;
186 case Type::Kind::F16: os << "f16"; return;
187 case Type::Kind::F32: os << "f32"; return;
188 case Type::Kind::F64: os << "f64"; return;
189
190 case Type::Kind::Integer: {
191 auto *integer = cast<IntegerType>(type);
192 os << 'i' << integer->getWidth();
193 return;
194 }
195 case Type::Kind::Function: {
196 auto *func = cast<FunctionType>(type);
197 os << '(';
198 interleave(func->getInputs(),
199 [&](Type *type) { os << *type; },
200 [&]() { os << ", "; });
201 os << ") -> ";
202 auto results = func->getResults();
203 if (results.size() == 1)
204 os << *results[0];
205 else {
206 os << '(';
207 interleave(results,
208 [&](Type *type) { os << *type; },
209 [&]() { os << ", "; });
210 os << ')';
211 }
212 return;
213 }
214 case Type::Kind::Vector: {
215 auto *v = cast<VectorType>(type);
216 os << "vector<";
217 for (auto dim : v->getShape())
218 os << dim << 'x';
219 os << *v->getElementType() << '>';
220 return;
221 }
222 case Type::Kind::RankedTensor: {
223 auto *v = cast<RankedTensorType>(type);
224 os << "tensor<";
225 for (auto dim : v->getShape()) {
226 if (dim < 0)
227 os << '?';
228 else
229 os << dim;
230 os << 'x';
231 }
232 os << *v->getElementType() << '>';
233 return;
234 }
235 case Type::Kind::UnrankedTensor: {
236 auto *v = cast<UnrankedTensorType>(type);
237 os << "tensor<??" << *v->getElementType() << '>';
238 return;
239 }
240 case Type::Kind::MemRef: {
241 auto *v = cast<MemRefType>(type);
242 os << "memref<";
243 for (auto dim : v->getShape()) {
244 if (dim < 0)
245 os << '?';
246 else
247 os << dim;
248 os << 'x';
249 }
250 os << *v->getElementType();
251 for (auto map : v->getAffineMaps()) {
252 os << ", ";
253 const int mapId = getAffineMapId(map);
254 if (mapId >= 0) {
255 // Map will be printed at top of module so print reference to its id.
256 printAffineMapId(mapId, os);
257 } else {
258 // Map not in module state so print inline.
259 map->print(os);
260 }
261 }
262 os << ", " << v->getMemorySpace();
263 os << '>';
264 return;
265 }
266 }
267}
268
269//===----------------------------------------------------------------------===//
Chris Lattner4c95a502018-06-23 16:03:42 -0700270// Function printing
271//===----------------------------------------------------------------------===//
272
MLIR Team4718bc92018-07-17 16:56:54 -0700273static void printFunctionSignature(const Function *fn,
274 const ModuleState *moduleState,
275 raw_ostream &os) {
Chris Lattner4c95a502018-06-23 16:03:42 -0700276 auto type = fn->getType();
277
278 os << "@" << fn->getName() << '(';
279 interleave(type->getInputs(),
MLIR Team4718bc92018-07-17 16:56:54 -0700280 [&](Type *eltType) { moduleState->print(eltType); },
Chris Lattner4c95a502018-06-23 16:03:42 -0700281 [&]() { os << ", "; });
282 os << ')';
283
284 switch (type->getResults().size()) {
285 case 0: break;
286 case 1:
MLIR Team4718bc92018-07-17 16:56:54 -0700287 os << " -> ";
288 moduleState->print(type->getResults()[0]);
Chris Lattner4c95a502018-06-23 16:03:42 -0700289 break;
290 default:
291 os << " -> (";
292 interleave(type->getResults(),
MLIR Team4718bc92018-07-17 16:56:54 -0700293 [&](Type *eltType) { moduleState->print(eltType); },
Chris Lattner4c95a502018-06-23 16:03:42 -0700294 [&]() { os << ", "; });
295 os << ')';
296 break;
297 }
298}
299
300void ExtFunction::print(raw_ostream &os) const {
MLIR Team4718bc92018-07-17 16:56:54 -0700301 ModuleState moduleState(os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700302 os << "extfunc ";
MLIR Team4718bc92018-07-17 16:56:54 -0700303 printFunctionSignature(this, &moduleState, os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700304 os << "\n";
305}
306
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700307namespace {
308
309// FunctionState contains common functionality for printing
310// CFG and ML functions.
311class FunctionState {
312public:
MLIR Team4718bc92018-07-17 16:56:54 -0700313 FunctionState(MLIRContext *context, const ModuleState *moduleState,
314 raw_ostream &os);
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700315
316 void printOperation(const Operation *op);
317
318protected:
319 raw_ostream &os;
MLIR Team4718bc92018-07-17 16:56:54 -0700320 const ModuleState *moduleState;
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700321 const OperationSet &operationSet;
322};
323} // end anonymous namespace
324
MLIR Team4718bc92018-07-17 16:56:54 -0700325FunctionState::FunctionState(MLIRContext *context,
326 const ModuleState *moduleState,
327 raw_ostream &os)
328 : os(os), moduleState(moduleState),
329 operationSet(OperationSet::get(context)) {}
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700330
331void FunctionState::printOperation(const Operation *op) {
332 // Check to see if this is a known operation. If so, use the registered
333 // custom printer hook.
334 if (auto opInfo = operationSet.lookup(op->getName().str())) {
335 os << " ";
336 opInfo->printAssembly(op, os);
337 return;
338 }
339
340 // TODO: escape name if necessary.
341 os << " \"" << op->getName().str() << "\"()";
342
343 auto attrs = op->getAttrs();
344 if (!attrs.empty()) {
345 os << '{';
346 interleave(
347 attrs,
348 [&](NamedAttribute attr) { os << attr.first << ": " << *attr.second; },
349 [&]() { os << ", "; });
350 os << '}';
351 }
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700352}
353
Chris Lattner4c95a502018-06-23 16:03:42 -0700354//===----------------------------------------------------------------------===//
355// CFG Function printing
356//===----------------------------------------------------------------------===//
357
358namespace {
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700359class CFGFunctionState : public FunctionState {
Chris Lattner4c95a502018-06-23 16:03:42 -0700360public:
MLIR Team4718bc92018-07-17 16:56:54 -0700361 CFGFunctionState(const CFGFunction *function, const ModuleState *moduleState,
362 raw_ostream &os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700363
364 const CFGFunction *getFunction() const { return function; }
365
366 void print();
367 void print(const BasicBlock *block);
Chris Lattnered65a732018-06-28 20:45:33 -0700368
369 void print(const Instruction *inst);
370 void print(const OperationInst *inst);
371 void print(const ReturnInst *inst);
372 void print(const BranchInst *inst);
Chris Lattner4c95a502018-06-23 16:03:42 -0700373
374 unsigned getBBID(const BasicBlock *block) {
375 auto it = basicBlockIDs.find(block);
376 assert(it != basicBlockIDs.end() && "Block not in this function?");
377 return it->second;
378 }
379
380private:
381 const CFGFunction *function;
Chris Lattner3a467cc2018-07-01 20:28:00 -0700382 DenseMap<const BasicBlock*, unsigned> basicBlockIDs;
Chris Lattner4c95a502018-06-23 16:03:42 -0700383};
384} // end anonymous namespace
385
MLIR Team4718bc92018-07-17 16:56:54 -0700386CFGFunctionState::CFGFunctionState(const CFGFunction *function,
387 const ModuleState *moduleState,
388 raw_ostream &os)
389 : FunctionState(function->getContext(), moduleState, os),
390 function(function) {
Chris Lattner4c95a502018-06-23 16:03:42 -0700391 // Each basic block gets a unique ID per function.
392 unsigned blockID = 0;
Chris Lattner3a467cc2018-07-01 20:28:00 -0700393 for (auto &block : *function)
394 basicBlockIDs[&block] = blockID++;
Chris Lattner4c95a502018-06-23 16:03:42 -0700395}
396
397void CFGFunctionState::print() {
398 os << "cfgfunc ";
MLIR Team4718bc92018-07-17 16:56:54 -0700399 printFunctionSignature(this->getFunction(), moduleState, os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700400 os << " {\n";
401
Chris Lattner3a467cc2018-07-01 20:28:00 -0700402 for (auto &block : *function)
403 print(&block);
Chris Lattner4c95a502018-06-23 16:03:42 -0700404 os << "}\n\n";
405}
406
407void CFGFunctionState::print(const BasicBlock *block) {
408 os << "bb" << getBBID(block) << ":\n";
409
Chris Lattnered65a732018-06-28 20:45:33 -0700410 // TODO Print arguments.
Jacques Pienaarb020c542018-07-15 00:06:54 -0700411 for (auto &inst : block->getOperations()) {
Chris Lattner3a467cc2018-07-01 20:28:00 -0700412 print(&inst);
Jacques Pienaarb020c542018-07-15 00:06:54 -0700413 os << "\n";
414 }
Chris Lattner4c95a502018-06-23 16:03:42 -0700415
416 print(block->getTerminator());
Jacques Pienaarb020c542018-07-15 00:06:54 -0700417 os << "\n";
Chris Lattner4c95a502018-06-23 16:03:42 -0700418}
419
Chris Lattnered65a732018-06-28 20:45:33 -0700420void CFGFunctionState::print(const Instruction *inst) {
Chris Lattner4c95a502018-06-23 16:03:42 -0700421 switch (inst->getKind()) {
Chris Lattnered65a732018-06-28 20:45:33 -0700422 case Instruction::Kind::Operation:
423 return print(cast<OperationInst>(inst));
Chris Lattnerf6d80a02018-06-24 11:18:29 -0700424 case TerminatorInst::Kind::Branch:
Chris Lattnered65a732018-06-28 20:45:33 -0700425 return print(cast<BranchInst>(inst));
Chris Lattner4c95a502018-06-23 16:03:42 -0700426 case TerminatorInst::Kind::Return:
Chris Lattnered65a732018-06-28 20:45:33 -0700427 return print(cast<ReturnInst>(inst));
Chris Lattner4c95a502018-06-23 16:03:42 -0700428 }
429}
430
Chris Lattnered65a732018-06-28 20:45:33 -0700431void CFGFunctionState::print(const OperationInst *inst) {
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700432 printOperation(inst);
Chris Lattnered65a732018-06-28 20:45:33 -0700433}
434
435void CFGFunctionState::print(const BranchInst *inst) {
Jacques Pienaarb020c542018-07-15 00:06:54 -0700436 os << " br bb" << getBBID(inst->getDest());
Chris Lattnered65a732018-06-28 20:45:33 -0700437}
438void CFGFunctionState::print(const ReturnInst *inst) {
Jacques Pienaarb020c542018-07-15 00:06:54 -0700439 os << " return";
Chris Lattnered65a732018-06-28 20:45:33 -0700440}
441
Chris Lattner4c95a502018-06-23 16:03:42 -0700442//===----------------------------------------------------------------------===//
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700443// ML Function printing
Chris Lattner4c95a502018-06-23 16:03:42 -0700444//===----------------------------------------------------------------------===//
445
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700446namespace {
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700447class MLFunctionState : public FunctionState {
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700448public:
MLIR Team4718bc92018-07-17 16:56:54 -0700449 MLFunctionState(const MLFunction *function, const ModuleState *moduleState,
450 raw_ostream &os);
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700451
452 const MLFunction *getFunction() const { return function; }
453
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700454 // Prints ML function
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700455 void print();
456
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700457 // Methods to print ML function statements
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700458 void print(const Statement *stmt);
Tatiana Shpeismanfa412f72018-07-09 17:42:46 -0700459 void print(const OperationStmt *stmt);
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700460 void print(const ForStmt *stmt);
461 void print(const IfStmt *stmt);
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700462 void print(const StmtBlock *block);
463
464 // Number of spaces used for indenting nested statements
465 const static unsigned indentWidth = 2;
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700466
467private:
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700468 const MLFunction *function;
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700469 int numSpaces;
470};
471} // end anonymous namespace
472
MLIR Team4718bc92018-07-17 16:56:54 -0700473MLFunctionState::MLFunctionState(const MLFunction *function,
474 const ModuleState *moduleState,
475 raw_ostream &os)
476 : FunctionState(function->getContext(), moduleState, os),
477 function(function), numSpaces(0) {}
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700478
479void MLFunctionState::print() {
480 os << "mlfunc ";
481 // FIXME: should print argument names rather than just signature
MLIR Team4718bc92018-07-17 16:56:54 -0700482 printFunctionSignature(function, moduleState, os);
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700483 os << " {\n";
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700484 print(function);
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700485 os << " return\n";
486 os << "}\n\n";
487}
488
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700489void MLFunctionState::print(const StmtBlock *block) {
490 numSpaces += indentWidth;
Jacques Pienaarb020c542018-07-15 00:06:54 -0700491 for (auto &stmt : block->getStatements()) {
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700492 print(&stmt);
Jacques Pienaarb020c542018-07-15 00:06:54 -0700493 os << "\n";
494 }
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700495 numSpaces -= indentWidth;
496}
497
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700498void MLFunctionState::print(const Statement *stmt) {
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700499 switch (stmt->getKind()) {
Tatiana Shpeisman565b9642018-07-16 11:47:09 -0700500 case Statement::Kind::Operation:
501 return print(cast<OperationStmt>(stmt));
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700502 case Statement::Kind::For:
503 return print(cast<ForStmt>(stmt));
504 case Statement::Kind::If:
505 return print(cast<IfStmt>(stmt));
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700506 }
507}
508
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700509void MLFunctionState::print(const OperationStmt *stmt) {
510 printOperation(stmt);
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700511}
512
513void MLFunctionState::print(const ForStmt *stmt) {
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700514 os.indent(numSpaces) << "for {\n";
515 print(static_cast<const StmtBlock *>(stmt));
Tatiana Shpeisman565b9642018-07-16 11:47:09 -0700516 os.indent(numSpaces) << "}";
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700517}
518
519void MLFunctionState::print(const IfStmt *stmt) {
Tatiana Shpeisman1bcfe982018-07-13 13:03:13 -0700520 os.indent(numSpaces) << "if () {\n";
521 print(stmt->getThenClause());
522 os.indent(numSpaces) << "}";
523 if (stmt->hasElseClause()) {
524 os << " else {\n";
525 print(stmt->getElseClause());
526 os.indent(numSpaces) << "}";
527 }
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700528}
529
MLIR Team4718bc92018-07-17 16:56:54 -0700530void printExtFunction(const ExtFunction* fn, const ModuleState* moduleState,
531 raw_ostream &os) {
532 os << "extfunc ";
533 printFunctionSignature(fn, moduleState, os);
534 os << '\n';
535}
536
537void printCFGFunction(const CFGFunction* fn, const ModuleState* moduleState,
538 raw_ostream &os) {
539 CFGFunctionState state(fn, moduleState, os);
540 state.print();
541}
542
543void printMLFunction(const MLFunction* fn, const ModuleState* moduleState,
544 raw_ostream &os) {
545 MLFunctionState state(fn, moduleState, os);
546 state.print();
547}
548
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700549//===----------------------------------------------------------------------===//
550// print and dump methods
551//===----------------------------------------------------------------------===//
Chris Lattnered65a732018-06-28 20:45:33 -0700552
MLIR Team4718bc92018-07-17 16:56:54 -0700553void Type::print(raw_ostream &os) const {
554 ModuleState moduleState(os);
555 moduleState.print(this);
556}
557
558void Type::dump() const {
559 print(llvm::errs());
560}
561
Chris Lattnered65a732018-06-28 20:45:33 -0700562void Instruction::print(raw_ostream &os) const {
MLIR Team4718bc92018-07-17 16:56:54 -0700563 ModuleState moduleState(os);
564 CFGFunctionState state(getFunction(), &moduleState, os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700565 state.print(this);
566}
567
Chris Lattnered65a732018-06-28 20:45:33 -0700568void Instruction::dump() const {
Chris Lattner4c95a502018-06-23 16:03:42 -0700569 print(llvm::errs());
Jacques Pienaarb020c542018-07-15 00:06:54 -0700570 llvm::errs() << "\n";
Chris Lattner4c95a502018-06-23 16:03:42 -0700571}
572
MLIR Team718c82f2018-07-16 09:45:22 -0700573void AffineMap::dump() const {
574 print(llvm::errs());
575 llvm::errs() << "\n";
576}
Uday Bondhugula3934d4d2018-07-09 09:00:25 -0700577
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700578void AffineExpr::dump() const {
579 print(llvm::errs());
580 llvm::errs() << "\n";
581}
582
583void AffineAddExpr::print(raw_ostream &os) const {
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700584 os << "(" << *getLHS() << " + " << *getRHS() << ")";
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700585}
586
587void AffineSubExpr::print(raw_ostream &os) const {
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700588 os << "(" << *getLHS() << " - " << *getRHS() << ")";
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700589}
590
591void AffineMulExpr::print(raw_ostream &os) const {
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700592 os << "(" << *getLHS() << " * " << *getRHS() << ")";
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700593}
594
595void AffineModExpr::print(raw_ostream &os) const {
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700596 os << "(" << *getLHS() << " mod " << *getRHS() << ")";
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700597}
598
599void AffineFloorDivExpr::print(raw_ostream &os) const {
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700600 os << "(" << *getLHS() << " floordiv " << *getRHS() << ")";
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700601}
602
603void AffineCeilDivExpr::print(raw_ostream &os) const {
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700604 os << "(" << *getLHS() << " ceildiv " << *getRHS() << ")";
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700605}
606
607void AffineSymbolExpr::print(raw_ostream &os) const {
608 os << "s" << getPosition();
609}
610
611void AffineDimExpr::print(raw_ostream &os) const { os << "d" << getPosition(); }
612
613void AffineConstantExpr::print(raw_ostream &os) const { os << getValue(); }
614
Uday Bondhugulafaf37dd2018-06-29 18:09:29 -0700615void AffineExpr::print(raw_ostream &os) const {
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700616 switch (getKind()) {
617 case Kind::SymbolId:
618 return cast<AffineSymbolExpr>(this)->print(os);
619 case Kind::DimId:
620 return cast<AffineDimExpr>(this)->print(os);
621 case Kind::Constant:
622 return cast<AffineConstantExpr>(this)->print(os);
623 case Kind::Add:
624 return cast<AffineAddExpr>(this)->print(os);
625 case Kind::Sub:
626 return cast<AffineSubExpr>(this)->print(os);
627 case Kind::Mul:
628 return cast<AffineMulExpr>(this)->print(os);
629 case Kind::FloorDiv:
630 return cast<AffineFloorDivExpr>(this)->print(os);
631 case Kind::CeilDiv:
632 return cast<AffineCeilDivExpr>(this)->print(os);
633 case Kind::Mod:
634 return cast<AffineModExpr>(this)->print(os);
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700635 }
Uday Bondhugulafaf37dd2018-06-29 18:09:29 -0700636}
637
638void AffineMap::print(raw_ostream &os) const {
Uday Bondhugula015cbb12018-07-03 20:16:08 -0700639 // Dimension identifiers.
640 os << "(";
641 for (int i = 0; i < (int)getNumDims() - 1; i++)
642 os << "d" << i << ", ";
643 if (getNumDims() >= 1)
644 os << "d" << getNumDims() - 1;
645 os << ")";
646
647 // Symbolic identifiers.
648 if (getNumSymbols() >= 1) {
649 os << " [";
650 for (int i = 0; i < (int)getNumSymbols() - 1; i++)
651 os << "s" << i << ", ";
652 if (getNumSymbols() >= 1)
653 os << "s" << getNumSymbols() - 1;
654 os << "]";
655 }
656
657 // AffineMap should have at least one result.
658 assert(!getResults().empty());
659 // Result affine expressions.
660 os << " -> (";
661 interleave(getResults(), [&](AffineExpr *expr) { os << *expr; },
662 [&]() { os << ", "; });
Uday Bondhugula0115dbb2018-07-11 21:31:07 -0700663 os << ")";
664
665 if (!isBounded()) {
Uday Bondhugula0115dbb2018-07-11 21:31:07 -0700666 return;
667 }
668
669 // Print range sizes for bounded affine maps.
670 os << " size (";
671 interleave(getRangeSizes(), [&](AffineExpr *expr) { os << *expr; },
672 [&]() { os << ", "; });
MLIR Team718c82f2018-07-16 09:45:22 -0700673 os << ")";
Uday Bondhugulafaf37dd2018-06-29 18:09:29 -0700674}
675
Chris Lattner4c95a502018-06-23 16:03:42 -0700676void BasicBlock::print(raw_ostream &os) const {
MLIR Team4718bc92018-07-17 16:56:54 -0700677 ModuleState moduleState(os);
678 CFGFunctionState state(getFunction(), &moduleState, os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700679 state.print();
680}
681
682void BasicBlock::dump() const {
683 print(llvm::errs());
684}
685
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700686void Statement::print(raw_ostream &os) const {
MLIR Team4718bc92018-07-17 16:56:54 -0700687 ModuleState moduleState(os);
688 MLFunctionState state(getFunction(), &moduleState, os);
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700689 state.print(this);
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700690}
691
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700692void Statement::dump() const {
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700693 print(llvm::errs());
694}
Jacques Pienaarb020c542018-07-15 00:06:54 -0700695
Chris Lattner4c95a502018-06-23 16:03:42 -0700696void Function::print(raw_ostream &os) const {
697 switch (getKind()) {
698 case Kind::ExtFunc: return cast<ExtFunction>(this)->print(os);
699 case Kind::CFGFunc: return cast<CFGFunction>(this)->print(os);
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700700 case Kind::MLFunc: return cast<MLFunction>(this)->print(os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700701 }
702}
703
704void Function::dump() const {
705 print(llvm::errs());
706}
707
708void CFGFunction::print(raw_ostream &os) const {
MLIR Team4718bc92018-07-17 16:56:54 -0700709 ModuleState moduleState(os);
710 CFGFunctionState state(this, &moduleState, os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700711 state.print();
712}
713
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700714void MLFunction::print(raw_ostream &os) const {
MLIR Team4718bc92018-07-17 16:56:54 -0700715 ModuleState moduleState(os);
716 MLFunctionState state(this, &moduleState, os);
Tatiana Shpeismanbf079c92018-07-03 17:51:28 -0700717 state.print();
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700718}
719
Chris Lattner4c95a502018-06-23 16:03:42 -0700720void Module::print(raw_ostream &os) const {
MLIR Team4718bc92018-07-17 16:56:54 -0700721 ModuleState moduleState(os);
722 moduleState.initialize(this);
723 moduleState.print(this);
Chris Lattner4c95a502018-06-23 16:03:42 -0700724}
725
726void Module::dump() const {
727 print(llvm::errs());
728}