@@ -124,6 +124,56 @@ class FloatArithmeticOp<string mnemonic, list<OpTrait> traits = []> :
124
124
ArithmeticOp<mnemonic, traits>,
125
125
Arguments<(ins FloatLike:$lhs, FloatLike:$rhs)>;
126
126
127
+ // Base class for memref allocating ops: alloca and alloc.
128
+ //
129
+ // %0 = alloclike(%m)[%s] : memref<8x?xf32, (d0, d1)[s0] -> ((d0 + s0), d1)>
130
+ //
131
+ class AllocLikeOp<string mnemonic, list<OpTrait> traits = []> :
132
+ Std_Op<mnemonic, traits> {
133
+
134
+ let arguments = (ins Variadic<Index>:$value,
135
+ Confined<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$alignment);
136
+ let results = (outs AnyMemRef);
137
+
138
+ let builders = [OpBuilder<
139
+ "Builder *builder, OperationState &result, MemRefType memrefType", [{
140
+ result.types.push_back(memrefType);
141
+ }]>,
142
+ OpBuilder<
143
+ "Builder *builder, OperationState &result, MemRefType memrefType, " #
144
+ "ValueRange operands, IntegerAttr alignment = IntegerAttr()", [{
145
+ result.addOperands(operands);
146
+ result.types.push_back(memrefType);
147
+ if (alignment)
148
+ result.addAttribute(getAlignmentAttrName(), alignment);
149
+ }]>];
150
+
151
+ let extraClassDeclaration = [{
152
+ static StringRef getAlignmentAttrName() { return "alignment"; }
153
+
154
+ MemRefType getType() { return getResult().getType().cast<MemRefType>(); }
155
+
156
+ /// Returns the number of symbolic operands (the ones in square brackets),
157
+ /// which bind to the symbols of the memref's layout map.
158
+ unsigned getNumSymbolicOperands() {
159
+ return getNumOperands() - getType().getNumDynamicDims();
160
+ }
161
+
162
+ /// Returns the symbolic operands (the ones in square brackets), which bind
163
+ /// to the symbols of the memref's layout map.
164
+ operand_range getSymbolicOperands() {
165
+ return {operand_begin() + getType().getNumDynamicDims(), operand_end()};
166
+ }
167
+
168
+ /// Returns the dynamic sizes for this alloc operation if specified.
169
+ operand_range getDynamicSizes() { return getOperands(); }
170
+ }];
171
+
172
+ let parser = [{ return ::parseAllocLikeOp(parser, result); }];
173
+
174
+ let hasCanonicalizer = 1;
175
+ }
176
+
127
177
//===----------------------------------------------------------------------===//
128
178
// AbsFOp
129
179
//===----------------------------------------------------------------------===//
@@ -225,7 +275,7 @@ def AddIOp : IntArithmeticOp<"addi", [Commutative]> {
225
275
// AllocOp
226
276
//===----------------------------------------------------------------------===//
227
277
228
- def AllocOp : Std_Op <"alloc"> {
278
+ def AllocOp : AllocLikeOp <"alloc"> {
229
279
let summary = "memory allocation operation";
230
280
let description = [{
231
281
The `alloc` operation allocates a region of memory, as specified by its
@@ -234,23 +284,24 @@ def AllocOp : Std_Op<"alloc"> {
234
284
Example:
235
285
236
286
```mlir
237
- %0 = alloc() : memref<8x64xf32, (d0, d1) -> (d0, d1), 1>
287
+ %0 = alloc() : memref<8x64xf32, 1>
238
288
```
239
289
240
290
The optional list of dimension operands are bound to the dynamic dimensions
241
291
specified in its memref type. In the example below, the ssa value '%d' is
242
292
bound to the second dimension of the memref (which is dynamic).
243
293
244
294
```mlir
245
- %0 = alloc(%d) : memref<8x?xf32, (d0, d1) -> (d0, d1), 1>
295
+ %0 = alloc(%d) : memref<8x?xf32, 1>
246
296
```
247
297
248
298
The optional list of symbol operands are bound to the symbols of the
249
299
memrefs affine map. In the example below, the ssa value '%s' is bound to
250
300
the symbol 's0' in the affine map specified in the allocs memref type.
251
301
252
302
```mlir
253
- %0 = alloc()[%s] : memref<8x64xf32, (d0, d1)[s0] -> ((d0 + s0), d1), 1>
303
+ %0 = alloc()[%s] : memref<8x64xf32,
304
+ affine_map<(d0, d1)[s0] -> ((d0 + s0), d1)>, 1>
254
305
```
255
306
256
307
This operation returns a single ssa value of memref type, which can be used
@@ -262,49 +313,49 @@ def AllocOp : Std_Op<"alloc"> {
262
313
263
314
```mlir
264
315
%0 = alloc()[%s] {alignment = 8} :
265
- memref<8x64xf32, (d0, d1)[s0] -> ((d0 + s0), d1), 1>
316
+ memref<8x64xf32, affine_map< (d0, d1)[s0] -> ((d0 + s0), d1)> , 1>
266
317
```
267
318
}];
319
+ }
268
320
269
- let arguments = (ins Variadic<Index>:$value,
270
- Confined<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$alignment);
271
- let results = (outs AnyMemRef);
321
+ //===----------------------------------------------------------------------===//
322
+ // AllocaOp
323
+ //===----------------------------------------------------------------------===//
272
324
273
- let builders = [OpBuilder<
274
- "Builder *builder, OperationState &result, MemRefType memrefType", [{
275
- result.types.push_back(memrefType);
276
- }]>,
277
- OpBuilder<
278
- "Builder *builder, OperationState &result, MemRefType memrefType, " #
279
- "ArrayRef<Value> operands, IntegerAttr alignment = IntegerAttr()", [{
280
- result.addOperands(operands);
281
- result.types.push_back(memrefType);
282
- if (alignment)
283
- result.addAttribute(getAlignmentAttrName(), alignment);
284
- }]>];
325
+ def AllocaOp : AllocLikeOp<"alloca"> {
326
+ let summary = "stack memory allocation operation";
327
+ let description = [{
328
+ The `alloca` operation allocates memory on the stack, to be automatically
329
+ released when the stack frame is discarded. The amount of memory allocated
330
+ is specified by its memref and additional operands. For example:
285
331
286
- let extraClassDeclaration = [{
287
- static StringRef getAlignmentAttrName() { return "alignment"; }
332
+ ```mlir
333
+ %0 = alloca() : memref<8x64xf32>
334
+ ```
288
335
289
- MemRefType getType() { return getResult().getType().cast<MemRefType>(); }
336
+ The optional list of dimension operands are bound to the dynamic dimensions
337
+ specified in its memref type. In the example below, the SSA value '%d' is
338
+ bound to the second dimension of the memref (which is dynamic).
290
339
291
- /// Returns the number of symbolic operands (the ones in square brackets),
292
- /// which bind to the symbols of the memref's layout map.
293
- unsigned getNumSymbolicOperands() {
294
- return getNumOperands() - getType().getNumDynamicDims();
295
- }
340
+ ```mlir
341
+ %0 = alloca(%d) : memref<8x?xf32>
342
+ ```
296
343
297
- /// Returns the symbolic operands (the ones in square brackets), which bind
298
- /// to the symbols of the memref's layout map.
299
- operand_range getSymbolicOperands() {
300
- return {operand_begin() + getType().getNumDynamicDims(), operand_end()};
301
- }
344
+ The optional list of symbol operands are bound to the symbols of the
345
+ memref's affine map. In the example below, the SSA value '%s' is bound to
346
+ the symbol 's0' in the affine map specified in the allocs memref type.
302
347
303
- /// Returns the dynamic sizes for this alloc operation if specified.
304
- operand_range getDynamicSizes() { return getOperands(); }
305
- }];
348
+ ```mlir
349
+ %0 = alloca()[%s] : memref<8x64xf32,
350
+ affine_map<(d0, d1)[s0] -> ((d0 + s0), d1)>>
351
+ ```
306
352
307
- let hasCanonicalizer = 1;
353
+ This operation returns a single SSA value of memref type, which can be used
354
+ by subsequent load and store operations. An optional alignment attribute, if
355
+ specified, guarantees alignment at least to that boundary. If not specified,
356
+ an alignment on any convenient boundary compatible with the type will be
357
+ chosen.
358
+ }];
308
359
}
309
360
310
361
//===----------------------------------------------------------------------===//
0 commit comments