blob: 03871fc52b96d83e9083b260ba057a0245cbda82 [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);
80 void print(const TerminatorInst *inst);
81
82 unsigned getBBID(const BasicBlock *block) {
83 auto it = basicBlockIDs.find(block);
84 assert(it != basicBlockIDs.end() && "Block not in this function?");
85 return it->second;
86 }
87
88private:
89 const CFGFunction *function;
90 raw_ostream &os;
91 DenseMap<BasicBlock*, unsigned> basicBlockIDs;
92};
93} // end anonymous namespace
94
95CFGFunctionState::CFGFunctionState(const CFGFunction *function, raw_ostream &os)
96 : function(function), os(os) {
97
98 // Each basic block gets a unique ID per function.
99 unsigned blockID = 0;
100 for (auto *block : function->blockList)
101 basicBlockIDs[block] = blockID++;
102}
103
104void CFGFunctionState::print() {
105 os << "cfgfunc ";
106 printFunctionSignature(this->getFunction(), os);
107 os << " {\n";
108
109 for (auto *block : function->blockList)
110 print(block);
111 os << "}\n\n";
112}
113
114void CFGFunctionState::print(const BasicBlock *block) {
115 os << "bb" << getBBID(block) << ":\n";
116
117 // TODO Print arguments and instructions.
118
119 print(block->getTerminator());
120}
121
122void CFGFunctionState::print(const TerminatorInst *inst) {
123 switch (inst->getKind()) {
Chris Lattnerf6d80a02018-06-24 11:18:29 -0700124 case TerminatorInst::Kind::Branch:
125 os << " br bb" << getBBID(cast<BranchInst>(inst)->getDest()) << "\n";
126 break;
Chris Lattner4c95a502018-06-23 16:03:42 -0700127 case TerminatorInst::Kind::Return:
128 os << " return\n";
129 break;
130 }
131}
132
133//===----------------------------------------------------------------------===//
134// print and dump methods
135//===----------------------------------------------------------------------===//
136
137void TerminatorInst::print(raw_ostream &os) const {
138 CFGFunctionState state(getFunction(), os);
139 state.print(this);
140}
141
142void TerminatorInst::dump() const {
143 print(llvm::errs());
144}
145
146void BasicBlock::print(raw_ostream &os) const {
147 CFGFunctionState state(getFunction(), os);
148 state.print();
149}
150
151void BasicBlock::dump() const {
152 print(llvm::errs());
153}
154
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700155void MLStatement::print(raw_ostream &os) const {
156 //TODO
157}
158
159void MLStatement::dump() const {
160 print(llvm::errs());
161}
Chris Lattner4c95a502018-06-23 16:03:42 -0700162void Function::print(raw_ostream &os) const {
163 switch (getKind()) {
164 case Kind::ExtFunc: return cast<ExtFunction>(this)->print(os);
165 case Kind::CFGFunc: return cast<CFGFunction>(this)->print(os);
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700166 case Kind::MLFunc: return cast<MLFunction>(this)->print(os);
Chris Lattner4c95a502018-06-23 16:03:42 -0700167 }
168}
169
170void Function::dump() const {
171 print(llvm::errs());
172}
173
174void CFGFunction::print(raw_ostream &os) const {
175 CFGFunctionState state(this, os);
176 state.print();
177}
178
Tatiana Shpeismanc96b5872018-06-28 17:02:32 -0700179void MLFunction::print(raw_ostream &os) const {
180 os << "mlfunc ";
181 // FIXME: should print argument names rather than just signature
182 printFunctionSignature(this, os);
183 os << " {\n";
184
185 for (auto *stmt : stmtList)
186 stmt->print(os);
187 os << " return\n";
188 os << "}\n\n";
189}
190
Chris Lattner4c95a502018-06-23 16:03:42 -0700191void Module::print(raw_ostream &os) const {
192 for (auto *fn : functionList)
193 fn->print(os);
194}
195
196void Module::dump() const {
197 print(llvm::errs());
198}
199