blob: 08fe8380748f0d3f04ce7a0289082af753821e94 [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"
24#include "mlir/IR/Module.h"
25#include "mlir/IR/Types.h"
26#include "mlir/Support/STLExtras.h"
27#include "llvm/Support/raw_ostream.h"
28#include "llvm/ADT/DenseMap.h"
29using namespace mlir;
30
31
32//===----------------------------------------------------------------------===//
33// Function printing
34//===----------------------------------------------------------------------===//
35
36static void printFunctionSignature(const Function *fn, raw_ostream &os) {
37 auto type = fn->getType();
38
39 os << "@" << fn->getName() << '(';
40 interleave(type->getInputs(),
41 [&](Type *eltType) { os << *eltType; },
42 [&]() { os << ", "; });
43 os << ')';
44
45 switch (type->getResults().size()) {
46 case 0: break;
47 case 1:
48 os << " -> " << *type->getResults()[0];
49 break;
50 default:
51 os << " -> (";
52 interleave(type->getResults(),
53 [&](Type *eltType) { os << *eltType; },
54 [&]() { os << ", "; });
55 os << ')';
56 break;
57 }
58}
59
60void ExtFunction::print(raw_ostream &os) const {
61 os << "extfunc ";
62 printFunctionSignature(this, os);
63 os << "\n";
64}
65
66//===----------------------------------------------------------------------===//
67// CFG Function printing
68//===----------------------------------------------------------------------===//
69
70namespace {
71class CFGFunctionState {
72public:
73 CFGFunctionState(const CFGFunction *function, raw_ostream &os);
74
75 const CFGFunction *getFunction() const { return function; }
76
77 void print();
78 void print(const BasicBlock *block);
79 void print(const TerminatorInst *inst);
80
81 unsigned getBBID(const BasicBlock *block) {
82 auto it = basicBlockIDs.find(block);
83 assert(it != basicBlockIDs.end() && "Block not in this function?");
84 return it->second;
85 }
86
87private:
88 const CFGFunction *function;
89 raw_ostream &os;
90 DenseMap<BasicBlock*, unsigned> basicBlockIDs;
91};
92} // end anonymous namespace
93
94CFGFunctionState::CFGFunctionState(const CFGFunction *function, raw_ostream &os)
95 : function(function), os(os) {
96
97 // Each basic block gets a unique ID per function.
98 unsigned blockID = 0;
99 for (auto *block : function->blockList)
100 basicBlockIDs[block] = blockID++;
101}
102
103void CFGFunctionState::print() {
104 os << "cfgfunc ";
105 printFunctionSignature(this->getFunction(), os);
106 os << " {\n";
107
108 for (auto *block : function->blockList)
109 print(block);
110 os << "}\n\n";
111}
112
113void CFGFunctionState::print(const BasicBlock *block) {
114 os << "bb" << getBBID(block) << ":\n";
115
116 // TODO Print arguments and instructions.
117
118 print(block->getTerminator());
119}
120
121void CFGFunctionState::print(const TerminatorInst *inst) {
122 switch (inst->getKind()) {
Chris Lattnerf6d80a02018-06-24 11:18:29 -0700123 case TerminatorInst::Kind::Branch:
124 os << " br bb" << getBBID(cast<BranchInst>(inst)->getDest()) << "\n";
125 break;
Chris Lattner4c95a502018-06-23 16:03:42 -0700126 case TerminatorInst::Kind::Return:
127 os << " return\n";
128 break;
129 }
130}
131
132//===----------------------------------------------------------------------===//
133// print and dump methods
134//===----------------------------------------------------------------------===//
135
136void TerminatorInst::print(raw_ostream &os) const {
137 CFGFunctionState state(getFunction(), os);
138 state.print(this);
139}
140
141void TerminatorInst::dump() const {
142 print(llvm::errs());
143}
144
145void BasicBlock::print(raw_ostream &os) const {
146 CFGFunctionState state(getFunction(), os);
147 state.print();
148}
149
150void BasicBlock::dump() const {
151 print(llvm::errs());
152}
153
154void Function::print(raw_ostream &os) const {
155 switch (getKind()) {
156 case Kind::ExtFunc: return cast<ExtFunction>(this)->print(os);
157 case Kind::CFGFunc: return cast<CFGFunction>(this)->print(os);
158 }
159}
160
161void Function::dump() const {
162 print(llvm::errs());
163}
164
165void CFGFunction::print(raw_ostream &os) const {
166 CFGFunctionState state(this, os);
167 state.print();
168}
169
170void Module::print(raw_ostream &os) const {
171 for (auto *fn : functionList)
172 fn->print(os);
173}
174
175void Module::dump() const {
176 print(llvm::errs());
177}
178