1 //===- Builders.h - MLIR Declarative Builder Classes ------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Provides intuitive composable interfaces for building structured MLIR
10 // snippets in a declarative fashion.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_DIALECT_AFFINE_EDSC_BUILDERS_H_
15 #define MLIR_DIALECT_AFFINE_EDSC_BUILDERS_H_
16 
17 #include "mlir/Dialect/Affine/IR/AffineOps.h"
18 #include "mlir/EDSC/Builders.h"
19 #include "mlir/IR/Builders.h"
20 #include "mlir/IR/Types.h"
21 
22 namespace mlir {
23 namespace edsc {
24 
25 /// Creates a perfect nest of affine "for" loops, given the list of lower
26 /// bounds, upper bounds and steps. The three lists are expected to contain the
27 /// same number of elements. Uses the OpBuilder and Location stored in
28 /// ScopedContext and assumes they are non-null. The optional "bodyBuilderFn"
29 /// callback is called to construct the body of the innermost loop and is passed
30 /// the list of loop induction variables, in order from outermost to innermost.
31 /// The function is expected to use the builder and location stored in
32 /// ScopedContext at the moment of the call. The function should not create
33 /// the affine terminator op, which will be added regardless of the
34 /// "bodyBuilderFn" being present.
35 void affineLoopNestBuilder(
36     ValueRange lbs, ValueRange ubs, ArrayRef<int64_t> steps,
37     function_ref<void(ValueRange)> bodyBuilderFn = nullptr);
38 
39 /// Creates a single affine "for" loop, iterating from max(lbs) to min(ubs) with
40 /// the given step. Uses the OpBuilder and Location stored in ScopedContext and
41 /// assumes they are non-null. The optional "bodyBuilderFn" callback is called
42 /// to construct the body of the loop and is passed the induction variable. The
43 /// function is expected to use the builder and location stored in ScopedContext
44 /// at the moment of the call. The function should not create the affine
45 /// terminator op, which will be added regardless of the "bodyBuilderFn" being
46 /// present.
47 void affineLoopBuilder(ValueRange lbs, ValueRange ubs, int64_t step,
48                        function_ref<void(Value)> bodyBuilderFn = nullptr);
49 
50 namespace op {
51 
52 Value operator+(Value lhs, Value rhs);
53 Value operator-(Value lhs, Value rhs);
54 Value operator*(Value lhs, Value rhs);
55 Value operator/(Value lhs, Value rhs);
56 Value operator%(Value lhs, Value rhs);
57 Value floorDiv(Value lhs, Value rhs);
58 Value ceilDiv(Value lhs, Value rhs);
59 
60 /// Logical operator overloadings.
61 Value negate(Value value);
62 Value operator&&(Value lhs, Value rhs);
63 Value operator||(Value lhs, Value rhs);
64 Value operator^(Value lhs, Value rhs);
65 
66 /// Comparison operator overloadings.
67 Value eq(Value lhs, Value rhs);
68 Value ne(Value lhs, Value rhs);
69 Value slt(Value lhs, Value rhs);
70 Value sle(Value lhs, Value rhs);
71 Value sgt(Value lhs, Value rhs);
72 Value sge(Value lhs, Value rhs);
73 Value ult(Value lhs, Value rhs);
74 Value ule(Value lhs, Value rhs);
75 Value ugt(Value lhs, Value rhs);
76 Value uge(Value lhs, Value rhs);
77 
78 } // namespace op
79 
80 /// Arithmetic operator overloadings.
81 template <typename Load, typename Store>
82 Value TemplatedIndexedValue<Load, Store>::operator+(Value e) {
83   using op::operator+;
84   return static_cast<Value>(*this) + e;
85 }
86 template <typename Load, typename Store>
87 Value TemplatedIndexedValue<Load, Store>::operator-(Value e) {
88   using op::operator-;
89   return static_cast<Value>(*this) - e;
90 }
91 template <typename Load, typename Store>
92 Value TemplatedIndexedValue<Load, Store>::operator*(Value e) {
93   using op::operator*;
94   return static_cast<Value>(*this) * e;
95 }
96 template <typename Load, typename Store>
97 Value TemplatedIndexedValue<Load, Store>::operator/(Value e) {
98   using op::operator/;
99   return static_cast<Value>(*this) / e;
100 }
101 template <typename Load, typename Store>
102 Value TemplatedIndexedValue<Load, Store>::operator%(Value e) {
103   using op::operator%;
104   return static_cast<Value>(*this) % e;
105 }
106 template <typename Load, typename Store>
107 Value TemplatedIndexedValue<Load, Store>::operator^(Value e) {
108   using op::operator^;
109   return static_cast<Value>(*this) ^ e;
110 }
111 
112 /// Assignment-arithmetic operator overloadings.
113 template <typename Load, typename Store>
114 Store TemplatedIndexedValue<Load, Store>::operator+=(Value e) {
115   using op::operator+;
116   return Store(*this + e, getBase(), indices);
117 }
118 template <typename Load, typename Store>
119 Store TemplatedIndexedValue<Load, Store>::operator-=(Value e) {
120   using op::operator-;
121   return Store(*this - e, getBase(), indices);
122 }
123 template <typename Load, typename Store>
124 Store TemplatedIndexedValue<Load, Store>::operator*=(Value e) {
125   using op::operator*;
126   return Store(*this * e, getBase(), indices);
127 }
128 template <typename Load, typename Store>
129 Store TemplatedIndexedValue<Load, Store>::operator/=(Value e) {
130   using op::operator/;
131   return Store(*this / e, getBase(), indices);
132 }
133 template <typename Load, typename Store>
134 Store TemplatedIndexedValue<Load, Store>::operator%=(Value e) {
135   using op::operator%;
136   return Store(*this % e, getBase(), indices);
137 }
138 template <typename Load, typename Store>
139 Store TemplatedIndexedValue<Load, Store>::operator^=(Value e) {
140   using op::operator^;
141   return Store(*this ^ e, getBase(), indices);
142 }
143 
144 /// Logical operator overloadings.
145 template <typename Load, typename Store>
146 Value TemplatedIndexedValue<Load, Store>::operator&&(Value e) {
147   using op::operator&&;
148   return static_cast<Value>(*this) && e;
149 }
150 template <typename Load, typename Store>
151 Value TemplatedIndexedValue<Load, Store>::operator||(Value e) {
152   using op::operator||;
153   return static_cast<Value>(*this) || e;
154 }
155 
156 /// Comparison operator overloadings.
157 template <typename Load, typename Store>
eq(Value e)158 Value TemplatedIndexedValue<Load, Store>::eq(Value e) {
159   return eq(value, e);
160 }
161 template <typename Load, typename Store>
ne(Value e)162 Value TemplatedIndexedValue<Load, Store>::ne(Value e) {
163   return ne(value, e);
164 }
165 template <typename Load, typename Store>
slt(Value e)166 Value TemplatedIndexedValue<Load, Store>::slt(Value e) {
167   using op::slt;
168   return slt(static_cast<Value>(*this), e);
169 }
170 template <typename Load, typename Store>
sle(Value e)171 Value TemplatedIndexedValue<Load, Store>::sle(Value e) {
172   using op::sle;
173   return sle(static_cast<Value>(*this), e);
174 }
175 template <typename Load, typename Store>
sgt(Value e)176 Value TemplatedIndexedValue<Load, Store>::sgt(Value e) {
177   using op::sgt;
178   return sgt(static_cast<Value>(*this), e);
179 }
180 template <typename Load, typename Store>
sge(Value e)181 Value TemplatedIndexedValue<Load, Store>::sge(Value e) {
182   using op::sge;
183   return sge(static_cast<Value>(*this), e);
184 }
185 template <typename Load, typename Store>
ult(Value e)186 Value TemplatedIndexedValue<Load, Store>::ult(Value e) {
187   using op::ult;
188   return ult(static_cast<Value>(*this), e);
189 }
190 template <typename Load, typename Store>
ule(Value e)191 Value TemplatedIndexedValue<Load, Store>::ule(Value e) {
192   using op::ule;
193   return ule(static_cast<Value>(*this), e);
194 }
195 template <typename Load, typename Store>
ugt(Value e)196 Value TemplatedIndexedValue<Load, Store>::ugt(Value e) {
197   using op::ugt;
198   return ugt(static_cast<Value>(*this), e);
199 }
200 template <typename Load, typename Store>
uge(Value e)201 Value TemplatedIndexedValue<Load, Store>::uge(Value e) {
202   using op::uge;
203   return uge(static_cast<Value>(*this), e);
204 }
205 
206 } // namespace edsc
207 } // namespace mlir
208 
209 #endif // MLIR_DIALECT_AFFINE_EDSC_BUILDERS_H_
210