blob: f93508d971fa3ecd4d1417f02fac6f1f228651dd [file] [log] [blame]
Chris Lattner158e0a3e2018-07-08 20:51:38 -07001//===- Builders.cpp - Helpers for constructing MLIR Classes ---------------===//
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#include "mlir/IR/Builders.h"
Chris Lattner1ac20cb2018-07-10 10:59:53 -070019#include "mlir/IR/AffineExpr.h"
20#include "mlir/IR/AffineMap.h"
21#include "mlir/IR/Attributes.h"
Uday Bondhugulabc535622018-08-07 14:24:38 -070022#include "mlir/IR/IntegerSet.h"
Chris Lattnerfc647d52018-08-27 21:05:16 -070023#include "mlir/IR/Location.h"
Chris Lattner158e0a3e2018-07-08 20:51:38 -070024#include "mlir/IR/Module.h"
25#include "mlir/IR/Types.h"
26using namespace mlir;
27
28Builder::Builder(Module *module) : context(module->getContext()) {}
29
Chris Lattner1ac20cb2018-07-10 10:59:53 -070030Identifier Builder::getIdentifier(StringRef str) {
31 return Identifier::get(str, context);
32}
33
34Module *Builder::createModule() { return new Module(context); }
35
36//===----------------------------------------------------------------------===//
Chris Lattnerfc647d52018-08-27 21:05:16 -070037// Locations.
38//===----------------------------------------------------------------------===//
39
40UnknownLoc *Builder::getUnknownLoc() { return UnknownLoc::get(context); }
41
42UniquedFilename Builder::getUniquedFilename(StringRef filename) {
43 return UniquedFilename::get(filename, context);
44}
45
46FileLineColLoc *Builder::getFileLineColLoc(UniquedFilename filename,
47 unsigned line, unsigned column) {
48 return FileLineColLoc::get(filename, line, column, context);
49}
50
51//===----------------------------------------------------------------------===//
Chris Lattner158e0a3e2018-07-08 20:51:38 -070052// Types.
Chris Lattner1ac20cb2018-07-10 10:59:53 -070053//===----------------------------------------------------------------------===//
54
Chris Lattnerc3251192018-07-27 13:09:58 -070055FloatType *Builder::getBF16Type() { return Type::getBF16(context); }
Chris Lattner158e0a3e2018-07-08 20:51:38 -070056
Chris Lattnerc3251192018-07-27 13:09:58 -070057FloatType *Builder::getF16Type() { return Type::getF16(context); }
Chris Lattner158e0a3e2018-07-08 20:51:38 -070058
Chris Lattnerc3251192018-07-27 13:09:58 -070059FloatType *Builder::getF32Type() { return Type::getF32(context); }
Chris Lattner158e0a3e2018-07-08 20:51:38 -070060
Chris Lattnerc3251192018-07-27 13:09:58 -070061FloatType *Builder::getF64Type() { return Type::getF64(context); }
Chris Lattner158e0a3e2018-07-08 20:51:38 -070062
Chris Lattnerc3251192018-07-27 13:09:58 -070063OtherType *Builder::getAffineIntType() { return Type::getAffineInt(context); }
Chris Lattner158e0a3e2018-07-08 20:51:38 -070064
Chris Lattnerc3251192018-07-27 13:09:58 -070065OtherType *Builder::getTFControlType() { return Type::getTFControl(context); }
Jacques Pienaarc0d69302018-07-27 11:07:12 -070066
James Molloy72b0cbe2018-08-01 12:55:27 -070067OtherType *Builder::getTFStringType() { return Type::getTFString(context); }
68
Chris Lattner158e0a3e2018-07-08 20:51:38 -070069IntegerType *Builder::getIntegerType(unsigned width) {
70 return Type::getInteger(width, context);
71}
72
73FunctionType *Builder::getFunctionType(ArrayRef<Type *> inputs,
74 ArrayRef<Type *> results) {
75 return FunctionType::get(inputs, results, context);
76}
77
Jacques Pienaarc03c6952018-08-10 11:56:47 -070078MemRefType *Builder::getMemRefType(ArrayRef<int> shape, Type *elementType,
79 ArrayRef<AffineMap *> affineMapComposition,
80 unsigned memorySpace) {
81 return MemRefType::get(shape, elementType, affineMapComposition, memorySpace);
82}
83
Chris Lattner158e0a3e2018-07-08 20:51:38 -070084VectorType *Builder::getVectorType(ArrayRef<unsigned> shape,
85 Type *elementType) {
86 return VectorType::get(shape, elementType);
87}
88
89RankedTensorType *Builder::getTensorType(ArrayRef<int> shape,
90 Type *elementType) {
91 return RankedTensorType::get(shape, elementType);
92}
93
94UnrankedTensorType *Builder::getTensorType(Type *elementType) {
95 return UnrankedTensorType::get(elementType);
96}
Chris Lattner1ac20cb2018-07-10 10:59:53 -070097
98//===----------------------------------------------------------------------===//
99// Attributes.
100//===----------------------------------------------------------------------===//
101
102BoolAttr *Builder::getBoolAttr(bool value) {
103 return BoolAttr::get(value, context);
104}
105
106IntegerAttr *Builder::getIntegerAttr(int64_t value) {
107 return IntegerAttr::get(value, context);
108}
109
110FloatAttr *Builder::getFloatAttr(double value) {
111 return FloatAttr::get(value, context);
112}
113
114StringAttr *Builder::getStringAttr(StringRef bytes) {
115 return StringAttr::get(bytes, context);
116}
117
118ArrayAttr *Builder::getArrayAttr(ArrayRef<Attribute *> value) {
119 return ArrayAttr::get(value, context);
120}
121
Uday Bondhugula67701712018-08-21 16:01:23 -0700122AffineMapAttr *Builder::getAffineMapAttr(AffineMap *map) {
123 return AffineMapAttr::get(map, context);
MLIR Teamb61885d2018-07-18 16:29:21 -0700124}
125
James Molloyf0d2f442018-08-03 01:54:46 -0700126TypeAttr *Builder::getTypeAttr(Type *type) {
127 return TypeAttr::get(type, context);
128}
129
Chris Lattner1aa46322018-08-21 17:55:22 -0700130FunctionAttr *Builder::getFunctionAttr(const Function *value) {
Chris Lattner4613d9e2018-08-19 21:17:22 -0700131 return FunctionAttr::get(value, context);
132}
133
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700134//===----------------------------------------------------------------------===//
Uday Bondhugulabc535622018-08-07 14:24:38 -0700135// Affine Expressions, Affine Maps, and Integet Sets.
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700136//===----------------------------------------------------------------------===//
137
138AffineMap *Builder::getAffineMap(unsigned dimCount, unsigned symbolCount,
Uday Bondhugula0115dbb2018-07-11 21:31:07 -0700139 ArrayRef<AffineExpr *> results,
140 ArrayRef<AffineExpr *> rangeSizes) {
141 return AffineMap::get(dimCount, symbolCount, results, rangeSizes, context);
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700142}
143
144AffineDimExpr *Builder::getDimExpr(unsigned position) {
145 return AffineDimExpr::get(position, context);
146}
147
148AffineSymbolExpr *Builder::getSymbolExpr(unsigned position) {
149 return AffineSymbolExpr::get(position, context);
150}
151
152AffineConstantExpr *Builder::getConstantExpr(int64_t constant) {
153 return AffineConstantExpr::get(constant, context);
154}
155
156AffineExpr *Builder::getAddExpr(AffineExpr *lhs, AffineExpr *rhs) {
Uday Bondhugulac1faf662018-07-19 14:08:50 -0700157 return AffineBinaryOpExpr::get(AffineExpr::Kind::Add, lhs, rhs, context);
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700158}
159
160AffineExpr *Builder::getMulExpr(AffineExpr *lhs, AffineExpr *rhs) {
Uday Bondhugulac1faf662018-07-19 14:08:50 -0700161 return AffineBinaryOpExpr::get(AffineExpr::Kind::Mul, lhs, rhs, context);
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700162}
163
Uday Bondhugulacf4f4c42018-09-12 10:21:23 -0700164// Most multiply expressions are pure affine (rhs is a constant).
165AffineExpr *Builder::getMulExpr(AffineExpr *lhs, int64_t rhs) {
166 return AffineBinaryOpExpr::get(AffineExpr::Kind::Mul, lhs,
167 getConstantExpr(rhs), context);
168}
169
170AffineExpr *Builder::getSubExpr(AffineExpr *lhs, AffineExpr *rhs) {
171 return getAddExpr(lhs, getMulExpr(rhs, getConstantExpr(-1)));
172}
173
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700174AffineExpr *Builder::getModExpr(AffineExpr *lhs, AffineExpr *rhs) {
Uday Bondhugulac1faf662018-07-19 14:08:50 -0700175 return AffineBinaryOpExpr::get(AffineExpr::Kind::Mod, lhs, rhs, context);
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700176}
177
Uday Bondhugulacf4f4c42018-09-12 10:21:23 -0700178// Most modulo expressions are pure affine.
179AffineExpr *Builder::getModExpr(AffineExpr *lhs, uint64_t rhs) {
180 return AffineBinaryOpExpr::get(AffineExpr::Kind::Mod, lhs,
181 getConstantExpr(rhs), context);
182}
183
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700184AffineExpr *Builder::getFloorDivExpr(AffineExpr *lhs, AffineExpr *rhs) {
Uday Bondhugulac1faf662018-07-19 14:08:50 -0700185 return AffineBinaryOpExpr::get(AffineExpr::Kind::FloorDiv, lhs, rhs, context);
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700186}
187
Uday Bondhugulacf4f4c42018-09-12 10:21:23 -0700188// Most floordiv expressions are pure affine.
189AffineExpr *Builder::getFloorDivExpr(AffineExpr *lhs, uint64_t rhs) {
190 return AffineBinaryOpExpr::get(AffineExpr::Kind::FloorDiv, lhs,
191 getConstantExpr(rhs), context);
192}
193
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700194AffineExpr *Builder::getCeilDivExpr(AffineExpr *lhs, AffineExpr *rhs) {
Uday Bondhugulac1faf662018-07-19 14:08:50 -0700195 return AffineBinaryOpExpr::get(AffineExpr::Kind::CeilDiv, lhs, rhs, context);
Chris Lattner1ac20cb2018-07-10 10:59:53 -0700196}
Tatiana Shpeisman1da50c42018-07-19 09:52:39 -0700197
Uday Bondhugulacf4f4c42018-09-12 10:21:23 -0700198// Most ceildiv expressions are pure affine.
199AffineExpr *Builder::getCeilDivExpr(AffineExpr *lhs, uint64_t rhs) {
200 return AffineBinaryOpExpr::get(AffineExpr::Kind::CeilDiv, lhs,
201 getConstantExpr(rhs), context);
202}
203
Uday Bondhugulabc535622018-08-07 14:24:38 -0700204IntegerSet *Builder::getIntegerSet(unsigned dimCount, unsigned symbolCount,
205 ArrayRef<AffineExpr *> constraints,
206 ArrayRef<bool> isEq) {
207 return IntegerSet::get(dimCount, symbolCount, constraints, isEq, context);
208}
209
Tatiana Shpeismande8829f2018-08-24 23:38:14 -0700210AffineMap *Builder::getConstantMap(int64_t val) {
211 return AffineMap::get(0, 0, getConstantExpr(val), {}, context);
212}
213
214AffineMap *Builder::getDimIdentityMap() {
215 return AffineMap::get(1, 0, getDimExpr(0), {}, context);
216}
217
218AffineMap *Builder::getSymbolIdentityMap() {
219 return AffineMap::get(0, 1, getSymbolExpr(0), {}, context);
220}
221
Tatiana Shpeisman1da50c42018-07-19 09:52:39 -0700222//===----------------------------------------------------------------------===//
Tatiana Shpeisman6708b452018-07-24 10:15:13 -0700223// CFG function elements.
224//===----------------------------------------------------------------------===//
225
Chris Lattner8a9310a2018-08-24 21:13:19 -0700226/// Add new basic block and set the insertion point to the end of it. If an
227/// 'insertBefore' basic block is passed, the block will be placed before the
228/// specified block. If not, the block will be appended to the end of the
229/// current function.
230BasicBlock *CFGFuncBuilder::createBlock(BasicBlock *insertBefore) {
Tatiana Shpeisman6708b452018-07-24 10:15:13 -0700231 BasicBlock *b = new BasicBlock();
Chris Lattner8a9310a2018-08-24 21:13:19 -0700232
233 // If we are supposed to insert before a specific block, do so, otherwise add
234 // the block to the end of the function.
235 if (insertBefore)
236 function->getBlocks().insert(CFGFunction::iterator(insertBefore), b);
237 else
238 function->push_back(b);
239
Tatiana Shpeisman6708b452018-07-24 10:15:13 -0700240 setInsertionPoint(b);
241 return b;
242}
243
Chris Lattnereed6c4d2018-08-07 09:12:35 -0700244/// Create an operation given the fields represented as an OperationState.
245OperationInst *CFGFuncBuilder::createOperation(const OperationState &state) {
246 SmallVector<CFGValue *, 8> operands;
247 operands.reserve(state.operands.size());
248 for (auto elt : state.operands)
249 operands.push_back(cast<CFGValue>(elt));
250
Chris Lattner1628fa02018-08-23 14:32:25 -0700251 auto *op = OperationInst::create(state.location, state.name, operands,
252 state.types, state.attributes, context);
Chris Lattnereed6c4d2018-08-07 09:12:35 -0700253 block->getOperations().insert(insertPoint, op);
254 return op;
255}
256
Tatiana Shpeisman6708b452018-07-24 10:15:13 -0700257//===----------------------------------------------------------------------===//
258// Statements.
Tatiana Shpeisman1da50c42018-07-19 09:52:39 -0700259//===----------------------------------------------------------------------===//
260
Chris Lattnereed6c4d2018-08-07 09:12:35 -0700261/// Create an operation given the fields represented as an OperationState.
262OperationStmt *MLFuncBuilder::createOperation(const OperationState &state) {
263 SmallVector<MLValue *, 8> operands;
264 operands.reserve(state.operands.size());
265 for (auto elt : state.operands)
266 operands.push_back(cast<MLValue>(elt));
267
Chris Lattner1628fa02018-08-23 14:32:25 -0700268 auto *op = OperationStmt::create(state.location, state.name, operands,
269 state.types, state.attributes, context);
Chris Lattnereed6c4d2018-08-07 09:12:35 -0700270 block->getStatements().insert(insertPoint, op);
271 return op;
272}
273
Chris Lattnerfc647d52018-08-27 21:05:16 -0700274ForStmt *MLFuncBuilder::createFor(Location *location,
Tatiana Shpeismande8829f2018-08-24 23:38:14 -0700275 ArrayRef<MLValue *> lbOperands,
276 AffineMap *lbMap,
277 ArrayRef<MLValue *> ubOperands,
278 AffineMap *ubMap, int64_t step) {
279 auto *stmt = ForStmt::create(location, lbOperands, lbMap, ubOperands, ubMap,
280 step, context);
Chris Lattner1628fa02018-08-23 14:32:25 -0700281 block->getStatements().insert(insertPoint, stmt);
282 return stmt;
283}
284
Tatiana Shpeismanc6aa35b2018-08-28 15:26:20 -0700285IfStmt *MLFuncBuilder::createIf(Location *location,
286 ArrayRef<MLValue *> operands, IntegerSet *set) {
287 auto *stmt = IfStmt::create(location, operands, set);
Tatiana Shpeismand880b352018-07-31 23:14:16 -0700288 block->getStatements().insert(insertPoint, stmt);
Tatiana Shpeisman1da50c42018-07-19 09:52:39 -0700289 return stmt;
290}