blob: 1a003b687cbf886687bfa6024ef15bda51cd9b44 [file] [log] [blame]
Chris Lattner158e0a3e2018-07-08 20:51:38 -07001//===- Builders.h - Helpers for constructing MLIR Classes -------*- C++ -*-===//
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#ifndef MLIR_IR_BUILDERS_H
19#define MLIR_IR_BUILDERS_H
20
21#include "mlir/IR/CFGFunction.h"
Tatiana Shpeisman565b9642018-07-16 11:47:09 -070022#include "mlir/IR/MLFunction.h"
23#include "mlir/IR/Statements.h"
Chris Lattner158e0a3e2018-07-08 20:51:38 -070024
25namespace mlir {
26class MLIRContext;
27class Module;
28class Type;
29class PrimitiveType;
30class IntegerType;
31class FunctionType;
32class VectorType;
33class RankedTensorType;
34class UnrankedTensorType;
Chris Lattner1ac20cb2018-07-10 10:59:53 -070035class BoolAttr;
36class IntegerAttr;
37class FloatAttr;
38class StringAttr;
39class ArrayAttr;
MLIR Teamb61885d2018-07-18 16:29:21 -070040class AffineMapAttr;
Chris Lattner1ac20cb2018-07-10 10:59:53 -070041class AffineMap;
42class AffineExpr;
43class AffineConstantExpr;
44class AffineDimExpr;
45class AffineSymbolExpr;
Chris Lattner158e0a3e2018-07-08 20:51:38 -070046
47/// This class is a general helper class for creating context-global objects
48/// like types, attributes, and affine expressions.
49class Builder {
50public:
51 explicit Builder(MLIRContext *context) : context(context) {}
52 explicit Builder(Module *module);
53
54 MLIRContext *getContext() const { return context; }
55
Chris Lattner1ac20cb2018-07-10 10:59:53 -070056 Identifier getIdentifier(StringRef str);
57 Module *createModule();
58
Chris Lattner158e0a3e2018-07-08 20:51:38 -070059 // Types.
60 PrimitiveType *getAffineIntType();
61 PrimitiveType *getBF16Type();
62 PrimitiveType *getF16Type();
63 PrimitiveType *getF32Type();
64 PrimitiveType *getF64Type();
65 IntegerType *getIntegerType(unsigned width);
66 FunctionType *getFunctionType(ArrayRef<Type *> inputs,
67 ArrayRef<Type *> results);
68 VectorType *getVectorType(ArrayRef<unsigned> shape, Type *elementType);
69 RankedTensorType *getTensorType(ArrayRef<int> shape, Type *elementType);
70 UnrankedTensorType *getTensorType(Type *elementType);
71
Chris Lattner1ac20cb2018-07-10 10:59:53 -070072 // Attributes.
73 BoolAttr *getBoolAttr(bool value);
74 IntegerAttr *getIntegerAttr(int64_t value);
75 FloatAttr *getFloatAttr(double value);
76 StringAttr *getStringAttr(StringRef bytes);
77 ArrayAttr *getArrayAttr(ArrayRef<Attribute *> value);
MLIR Teamb61885d2018-07-18 16:29:21 -070078 AffineMapAttr *getAffineMapAttr(AffineMap *value);
Chris Lattner1ac20cb2018-07-10 10:59:53 -070079
80 // Affine Expressions and Affine Map.
81 AffineMap *getAffineMap(unsigned dimCount, unsigned symbolCount,
Uday Bondhugula0115dbb2018-07-11 21:31:07 -070082 ArrayRef<AffineExpr *> results,
83 ArrayRef<AffineExpr *> rangeSizes);
Chris Lattner1ac20cb2018-07-10 10:59:53 -070084 AffineDimExpr *getDimExpr(unsigned position);
85 AffineSymbolExpr *getSymbolExpr(unsigned position);
86 AffineConstantExpr *getConstantExpr(int64_t constant);
87 AffineExpr *getAddExpr(AffineExpr *lhs, AffineExpr *rhs);
88 AffineExpr *getSubExpr(AffineExpr *lhs, AffineExpr *rhs);
89 AffineExpr *getMulExpr(AffineExpr *lhs, AffineExpr *rhs);
90 AffineExpr *getModExpr(AffineExpr *lhs, AffineExpr *rhs);
91 AffineExpr *getFloorDivExpr(AffineExpr *lhs, AffineExpr *rhs);
92 AffineExpr *getCeilDivExpr(AffineExpr *lhs, AffineExpr *rhs);
93
Chris Lattner158e0a3e2018-07-08 20:51:38 -070094 // TODO: Helpers for affine map/exprs, etc.
Chris Lattner158e0a3e2018-07-08 20:51:38 -070095protected:
96 MLIRContext *context;
97};
98
99/// This class helps build a CFGFunction. Instructions that are created are
100/// automatically inserted at an insertion point or added to the current basic
101/// block.
102class CFGFuncBuilder : public Builder {
103public:
104 CFGFuncBuilder(BasicBlock *block)
105 : Builder(block->getFunction()->getContext()),
106 function(block->getFunction()) {
107 setInsertionPoint(block);
108 }
109 CFGFuncBuilder(CFGFunction *function)
110 : Builder(function->getContext()), function(function) {}
111
112 /// Reset the insertion point to no location. Creating an operation without a
113 /// set insertion point is an error, but this can still be useful when the
114 /// current insertion point a builder refers to is being removed.
115 void clearInsertionPoint() {
116 this->block = nullptr;
117 insertPoint = BasicBlock::iterator();
118 }
119
120 /// Set the insertion point to the end of the specified block.
121 void setInsertionPoint(BasicBlock *block) {
122 this->block = block;
123 insertPoint = block->end();
124 }
125
Chris Lattner3b2ef762018-07-18 15:31:25 -0700126 OperationInst *createOperation(Identifier name, ArrayRef<CFGValue *> operands,
127 ArrayRef<Type *> resultTypes,
Chris Lattner158e0a3e2018-07-08 20:51:38 -0700128 ArrayRef<NamedAttribute> attributes) {
Chris Lattner3b2ef762018-07-18 15:31:25 -0700129 auto op =
130 OperationInst::create(name, operands, resultTypes, attributes, context);
Chris Lattner158e0a3e2018-07-08 20:51:38 -0700131 block->getOperations().push_back(op);
132 return op;
133 }
134
135 // Terminators.
136
Chris Lattner40746442018-07-21 14:32:09 -0700137 ReturnInst *createReturnInst(ArrayRef<CFGValue *> operands) {
138 return insertTerminator(ReturnInst::create(operands));
139 }
Chris Lattner158e0a3e2018-07-08 20:51:38 -0700140
141 BranchInst *createBranchInst(BasicBlock *dest) {
Chris Lattner40746442018-07-21 14:32:09 -0700142 return insertTerminator(BranchInst::create(dest));
Chris Lattner158e0a3e2018-07-08 20:51:38 -0700143 }
144
145private:
146 template <typename T>
147 T *insertTerminator(T *term) {
148 block->setTerminator(term);
149 return term;
150 }
151
152 CFGFunction *function;
153 BasicBlock *block = nullptr;
154 BasicBlock::iterator insertPoint;
155};
156
Tatiana Shpeisman565b9642018-07-16 11:47:09 -0700157/// This class helps build an MLFunction. Statements that are created are
158/// automatically inserted at an insertion point or added to the current
159/// statement block.
160class MLFuncBuilder : public Builder {
161public:
162 MLFuncBuilder(MLFunction *function) : Builder(function->getContext()) {}
163
164 MLFuncBuilder(StmtBlock *block) : MLFuncBuilder(block->getFunction()) {
165 setInsertionPoint(block);
166 }
167
168 /// Reset the insertion point to no location. Creating an operation without a
169 /// set insertion point is an error, but this can still be useful when the
170 /// current insertion point a builder refers to is being removed.
171 void clearInsertionPoint() {
172 this->block = nullptr;
173 insertPoint = StmtBlock::iterator();
174 }
175
176 /// Set the insertion point to the end of the specified block.
177 void setInsertionPoint(StmtBlock *block) {
178 this->block = block;
179 insertPoint = block->end();
180 }
181
182 OperationStmt *createOperation(Identifier name,
183 ArrayRef<NamedAttribute> attributes) {
184 auto op = new OperationStmt(name, attributes, context);
185 block->getStatements().push_back(op);
186 return op;
187 }
188
Tatiana Shpeisman1da50c42018-07-19 09:52:39 -0700189 // Creates for statement. When step is not specified, it is set to 1.
190 ForStmt *createFor(AffineConstantExpr *lowerBound,
191 AffineConstantExpr *upperBound,
192 AffineConstantExpr *step = nullptr);
Tatiana Shpeisman565b9642018-07-16 11:47:09 -0700193
194 IfStmt *createIf() {
195 auto stmt = new IfStmt();
196 block->getStatements().push_back(stmt);
197 return stmt;
198 }
199
200private:
201 StmtBlock *block = nullptr;
202 StmtBlock::iterator insertPoint;
203};
Chris Lattner158e0a3e2018-07-08 20:51:38 -0700204
205} // namespace mlir
206
207#endif