blob: 639000b53d30a8009ace3b3e50b470552e5c9f72 [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
23#include "mlir/IR/CFGFunction.h"
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -070024#include "mlir/IR/MLFunction.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070025#include "mlir/IR/Module.h"
26#include "mlir/IR/Types.h"
27#include "mlir/Support/STLExtras.h"
28#include "llvm/Support/raw_ostream.h"
29#include "llvm/ADT/DenseMap.h"
30using namespace mlir;
31
32
33//===----------------------------------------------------------------------===//
34// Function printing
35//===----------------------------------------------------------------------===//
36
37static void printFunctionSignature(const Function *fn, raw_ostream &os) {
38 auto type = fn->getType();
39
40 os << "@" << fn->getName() << '(';
41 interleave(type->getInputs(),
42 [&](Type *eltType) { os << *eltType; },
43 [&]() { os << ", "; });
44 os << ')';
45
46 switch (type->getResults().size()) {
47 case 0: break;
48 case 1:
49 os << " -> " << *type->getResults()[0];
50 break;
51 default:
52 os << " -> (";
53 interleave(type->getResults(),
54 [&](Type *eltType) { os << *eltType; },
55 [&]() { os << ", "; });
56 os << ')';
57 break;
58 }
59}
60
61void ExtFunction::print(raw_ostream &os) const {
62 os << "extfunc ";
63 printFunctionSignature(this, os);
64 os << "\n";
65}
66
67//===----------------------------------------------------------------------===//
68// CFG Function printing
69//===----------------------------------------------------------------------===//
70
71namespace {
72class CFGFunctionState {
73public:
74 CFGFunctionState(const CFGFunction *function, raw_ostream &os);
75
76 const CFGFunction *getFunction() const { return function; }
77
78 void print();
79 void print(const BasicBlock *block);
Chris Lattnered65a732018-06-28 20:45:33 -070080
81 void print(const Instruction *inst);
82 void print(const OperationInst *inst);
83 void print(const ReturnInst *inst);
84 void print(const BranchInst *inst);
Chris Lattner4c95a502018-06-23 16:03:42 -070085
86 unsigned getBBID(const BasicBlock *block) {
87 auto it = basicBlockIDs.find(block);
88 assert(it != basicBlockIDs.end() && "Block not in this function?");
89 return it->second;
90 }
91
92private:
93 const CFGFunction *function;
94 raw_ostream &os;
95 DenseMap<BasicBlock*, unsigned> basicBlockIDs;
96};
97} // end anonymous namespace
98
99CFGFunctionState::CFGFunctionState(const CFGFunction *function, raw_ostream &os)
100 : function(function), os(os) {
101
102 // Each basic block gets a unique ID per function.
103 unsigned blockID = 0;
104 for (auto *block : function->blockList)
105 basicBlockIDs[block] = blockID++;
106}
107
108void CFGFunctionState::print() {
109 os << "cfgfunc ";
110 printFunctionSignature(this->getFunction(), os);
111 os << " {\n";
112
113 for (auto *block : function->blockList)
114 print(block);
115 os << "}\n\n";
116}
117
118void CFGFunctionState::print(const BasicBlock *block) {
119 os << "bb" << getBBID(block) << ":\n";
120
Chris Lattnered65a732018-06-28 20:45:33 -0700121 // TODO Print arguments.
122 for (auto inst : block->instList)
123 print(inst);
Chris Lattner4c95a502018-06-23 16:03:42 -0700124
125 print(block->getTerminator());
126}
127
Chris Lattnered65a732018-06-28 20:45:33 -0700128void CFGFunctionState::print(const Instruction *inst) {
Chris Lattner4c95a502018-06-23 16:03:42 -0700129 switch (inst->getKind()) {
Chris Lattnered65a732018-06-28 20:45:33 -0700130 case Instruction::Kind::Operation:
131 return print(cast<OperationInst>(inst));
Chris Lattnerf6d80a02018-06-24 11:18:29 -0700132 case TerminatorInst::Kind::Branch:
Chris Lattnered65a732018-06-28 20:45:33 -0700133 return print(cast<BranchInst>(inst));
Chris Lattner4c95a502018-06-23 16:03:42 -0700134 case TerminatorInst::Kind::Return:
Chris Lattnered65a732018-06-28 20:45:33 -0700135 return print(cast<ReturnInst>(inst));
Chris Lattner4c95a502018-06-23 16:03:42 -0700136 }
137}
138
Chris Lattnered65a732018-06-28 20:45:33 -0700139void CFGFunctionState::print(const OperationInst *inst) {
140 // TODO: escape name if necessary.
141 os << " \"" << inst->getName().str() << "\"()\n";
142}
143
144void CFGFunctionState::print(const BranchInst *inst) {
145 os << " br bb" << getBBID(inst->getDest()) << "\n";
146}
147void CFGFunctionState::print(const ReturnInst *inst) {
148 os << " return\n";
149}
150
Chris Lattner4c95a502018-06-23 16:03:42 -0700151//===----------------------------------------------------------------------===//
152// print and dump methods
153//===----------------------------------------------------------------------===//
154
Chris Lattnered65a732018-06-28 20:45:33 -0700155
156void Instruction::print(raw_ostream &os) const {
Chris Lattner4c95a502018-06-23 16:03:42 -0700157 CFGFunctionState state(getFunction(), os);
158 state.print(this);
159}
160
Chris Lattnered65a732018-06-28 20:45:33 -0700161void Instruction::dump() const {
Chris Lattner4c95a502018-06-23 16:03:42 -0700162 print(llvm::errs());
163}
164
165void BasicBlock::print(raw_ostream &os) const {
166 CFGFunctionState state(getFunction(), os);
167 state.print();
168}
169
170void BasicBlock::dump() const {
171 print(llvm::errs());
172}
173
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700174void MLStatement::print(raw_ostream &os) const {
175 //TODO
176}
177
178void MLStatement::dump() const {
179 print(llvm::errs());
180}
Chris Lattner4c95a502018-06-23 16:03:42 -0700181void Function::print(raw_ostream &os) const {
182 switch (getKind()) {
183 case Kind::ExtFunc: return cast<ExtFunction>(this)->print(os);
184 case Kind::CFGFunc: return cast<CFGFunction>(this)->print(os);
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700185 case Kind::MLFunc: return cast<MLFunction>(this)->print(os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700186 }
187}
188
189void Function::dump() const {
190 print(llvm::errs());
191}
192
193void CFGFunction::print(raw_ostream &os) const {
194 CFGFunctionState state(this, os);
195 state.print();
196}
197
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700198void MLFunction::print(raw_ostream &os) const {
199 os << "mlfunc ";
200 // FIXME: should print argument names rather than just signature
201 printFunctionSignature(this, os);
202 os << " {\n";
203
204 for (auto *stmt : stmtList)
205 stmt->print(os);
206 os << " return\n";
207 os << "}\n\n";
208}
209
Chris Lattner4c95a502018-06-23 16:03:42 -0700210void Module::print(raw_ostream &os) const {
211 for (auto *fn : functionList)
212 fn->print(os);
213}
214
215void Module::dump() const {
216 print(llvm::errs());
217}
218