LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
Ops.cpp
Go to the documentation of this file.
1//===-- Ops.cpp - Array operation implementations ---------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
15
16#include <mlir/Dialect/Arith/IR/Arith.h>
17#include <mlir/Dialect/Utils/IndexingUtils.h>
18#include <mlir/IR/Attributes.h>
19#include <mlir/IR/BuiltinOps.h>
20#include <mlir/IR/Diagnostics.h>
21#include <mlir/IR/OwningOpRef.h>
22#include <mlir/IR/SymbolTable.h>
23#include <mlir/IR/ValueRange.h>
24#include <mlir/Support/LogicalResult.h>
25
26#include <llvm/ADT/ArrayRef.h>
27#include <llvm/ADT/Twine.h>
28
29// TableGen'd implementation files
31
32// TableGen'd implementation files
33#define GET_OP_CLASSES
35
36using namespace mlir;
37
38namespace llzk::array {
39
40//===------------------------------------------------------------------===//
41// CreateArrayOp
42//===------------------------------------------------------------------===//
43
45 OpBuilder &odsBuilder, OperationState &odsState, ArrayType result, ValueRange elements
46) {
47 odsState.addTypes(result);
48 odsState.addOperands(elements);
49 // This builds CreateArrayOp from a list of elements. In that case, the dimensions of the array
50 // type cannot be defined via an affine map which means there are no affine map operands.
52 odsBuilder, odsState, static_cast<int32_t>(elements.size())
53 );
54}
55
57 OpBuilder &odsBuilder, OperationState &odsState, ArrayType result,
58 ArrayRef<ValueRange> mapOperands, DenseI32ArrayAttr numDimsPerMap
59) {
60 odsState.addTypes(result);
62 odsBuilder, odsState, mapOperands, numDimsPerMap
63 );
64}
65
66LogicalResult CreateArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
67 // Ensure any SymbolRef used in the type are valid
68 return verifyTypeResolution(tables, *this, llvm::cast<Type>(getType()));
69}
70
71void CreateArrayOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
72 setNameFn(getResult(), "array");
73}
74
75llvm::SmallVector<Type> CreateArrayOp::resultTypeToElementsTypes(Type resultType) {
76 // The ODS restricts $result with LLZK_ArrayType so this cast is safe.
77 ArrayType a = llvm::cast<ArrayType>(resultType);
78 return llvm::SmallVector<Type>(a.getNumElements(), a.getElementType());
79}
80
82 OpAsmParser &parser, llvm::SmallVector<Type, 1> &elementsTypes,
83 ArrayRef<OpAsmParser::UnresolvedOperand> elements, Type resultType
84) {
85 assert(elementsTypes.size() == 0); // it was not yet initialized
86 // If the '$elements' operand is not empty, then the expected type for the operand
87 // is computed to match the type of the '$result'. Otherwise, it remains empty.
88 if (elements.size() > 0) {
89 elementsTypes.append(resultTypeToElementsTypes(resultType));
90 }
91 return success();
92}
93
95 OpAsmPrinter &printer, CreateArrayOp, TypeRange, OperandRange, Type
96) {
97 // nothing to print, it's derived and therefore not represented in the output
98}
99
100LogicalResult CreateArrayOp::verify() {
101 Type retTy = getResult().getType();
102 assert(llvm::isa<ArrayType>(retTy)); // per ODS spec of CreateArrayOp
103
104 // Collect the array dimensions that are defined via AffineMapAttr
105 SmallVector<AffineMapAttr> mapAttrs;
106 // Extend the lifetime of the temporary to suppress warnings.
107 ArrayType arrTy = llvm::cast<ArrayType>(retTy);
108 for (Attribute a : arrTy.getDimensionSizes()) {
109 if (AffineMapAttr m = dyn_cast<AffineMapAttr>(a)) {
110 mapAttrs.push_back(m);
111 }
112 }
114 getMapOperands(), getNumDimsPerMap(), mapAttrs, *this
115 );
116}
117
119SmallVector<DestructurableMemorySlot> CreateArrayOp::getDestructurableSlots() {
120 assert(getElements().empty() && "must run after initialization is split from allocation");
121 ArrayType arrType = getType();
122 if (!arrType.hasStaticShape() || arrType.getNumElements() == 1) {
123 return {};
124 }
125 if (auto destructured = arrType.getSubelementIndexMap()) {
126 return {DestructurableMemorySlot {{getResult(), arrType}, std::move(*destructured)}};
127 }
128 return {};
129}
130
132DenseMap<Attribute, MemorySlot> CreateArrayOp::destructure(
133 const DestructurableMemorySlot &slot, const SmallPtrSetImpl<Attribute> &usedIndices,
134 OpBuilder &builder, SmallVectorImpl<DestructurableAllocationOpInterface> &newAllocators
135) {
136 assert(slot.ptr == getResult());
137 assert(slot.elemType == getType());
138
139 builder.setInsertionPointAfter(*this);
140
141 DenseMap<Attribute, MemorySlot> slotMap; // result
142 for (Attribute index : usedIndices) {
143 // This is an ArrayAttr since indexing is multi-dimensional
144 ArrayAttr indexAsArray = llvm::dyn_cast<ArrayAttr>(index);
145 assert(indexAsArray && "expected ArrayAttr");
146
147 Type destructAs = getType().getTypeAtIndex(indexAsArray);
148 assert(destructAs == slot.subelementTypes.lookup(indexAsArray));
149
150 ArrayType destructAsArrayTy = llvm::dyn_cast<ArrayType>(destructAs);
151 assert(destructAsArrayTy && "expected ArrayType");
152
153 auto subCreate = builder.create<CreateArrayOp>(getLoc(), destructAsArrayTy);
154 newAllocators.push_back(subCreate);
155 slotMap.try_emplace<MemorySlot>(index, {subCreate.getResult(), destructAs});
156 }
157
158 return slotMap;
159}
160
162std::optional<DestructurableAllocationOpInterface> CreateArrayOp::handleDestructuringComplete(
163 const DestructurableMemorySlot &slot, OpBuilder & /*builder*/
164) {
165 assert(slot.ptr == getResult());
166 this->erase();
167 return std::nullopt;
168}
169
171SmallVector<MemorySlot> CreateArrayOp::getPromotableSlots() {
172 ArrayType arrType = getType();
173 if (!arrType.hasStaticShape()) {
174 return {};
175 }
176 // Can only support arrays containing a single element (the SROA pass can be run first to
177 // destructure all arrays into size-1 arrays).
178 if (arrType.getNumElements() != 1) {
179 return {};
180 }
181 return {MemorySlot {getResult(), arrType.getElementType()}};
182}
183
185Value CreateArrayOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) {
186 return builder.create<undef::UndefOp>(getLoc(), slot.elemType);
187}
188
190void CreateArrayOp::handleBlockArgument(const MemorySlot &, BlockArgument, OpBuilder &) {}
191
193std::optional<PromotableAllocationOpInterface> CreateArrayOp::handlePromotionComplete(
194 const MemorySlot & /*slot*/, Value defaultValue, OpBuilder & /*builder*/
195) {
196 if (defaultValue.use_empty()) {
197 defaultValue.getDefiningOp()->erase();
198 } else {
199 this->erase();
200 }
201 // Return `nullopt` because it produces only a single slot
202 return std::nullopt;
203}
204
205//===------------------------------------------------------------------===//
206// ArrayAccessOpInterface
207//===------------------------------------------------------------------===//
208
212 ArrayType arrTy = getArrRefType();
213 if (arrTy.hasStaticShape()) {
214 if (auto converted = ArrayIndexGen::from(arrTy).checkAndConvert(getIndices())) {
215 return ArrayAttr::get(getContext(), *converted);
216 }
217 }
218 return nullptr;
219}
220
223 const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices,
224 SmallVectorImpl<MemorySlot> & /*mustBeSafelyUsed*/, const DataLayout & /*dataLayout*/
225) {
226 if (slot.ptr != getArrRef()) {
227 return false;
228 }
229
230 ArrayAttr indexAsAttr = indexOperandsToAttributeArray();
231 if (!indexAsAttr) {
232 return false;
233 }
234
235 // Scalar read/write case has 0 dimensions in the read/write value.
236 if (!getValueOperandDims().empty()) {
237 return false;
238 }
239
240 // Just insert the index.
241 usedIndices.insert(indexAsAttr);
242 return true;
243}
244
247 const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots,
248 OpBuilder &builder, const DataLayout & /*dataLayout*/
249) {
250 assert(slot.ptr == getArrRef());
251 assert(slot.elemType == getArrRefType());
252 // ASSERT: non-scalar read/write should have been desugared earlier
253 assert(getValueOperandDims().empty() && "only scalar read/write supported");
254
255 ArrayAttr indexAsAttr = indexOperandsToAttributeArray();
256 assert(indexAsAttr && "canRewire() should have returned false");
257 const MemorySlot &memorySlot = subslots.at(indexAsAttr);
258
259 // Temporarily set insertion point before the current op for what's built below
260 OpBuilder::InsertionGuard guard(builder);
261 builder.setInsertionPoint(this->getOperation());
262
263 // Write to the sub-slot created for the index of `this`, using index 0
264 getArrRefMutable().set(memorySlot.ptr);
265 getIndicesMutable().clear();
266 getIndicesMutable().assign(builder.create<arith::ConstantIndexOp>(getLoc(), 0));
267
268 return DeletionKind::Keep;
269}
270
271//===------------------------------------------------------------------===//
272// ReadArrayOp
273//===------------------------------------------------------------------===//
274
275namespace {
276
277LogicalResult
278ensureNumIndicesMatchDims(ArrayType ty, size_t numIndices, const OwningEmitErrorFn &errFn) {
279 ArrayRef<Attribute> dims = ty.getDimensionSizes();
280 // Ensure the number of provided indices matches the array dimensions
281 auto compare = numIndices <=> dims.size();
282 if (compare != 0) {
283 return errFn().append(
284 "has ", (compare < 0 ? "insufficient" : "too many"), " indexed dimensions: expected ",
285 dims.size(), " but found ", numIndices
286 );
287 }
288 return success();
289}
290
291} // namespace
292
293LogicalResult ReadArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
294 // Ensure any SymbolRef used in the type are valid
295 return verifyTypeResolution(tables, *this, ArrayRef<Type> {getArrRef().getType(), getType()});
296}
297
299 MLIRContext *context, std::optional<Location> location, ReadArrayOpAdaptor adaptor,
300 llvm::SmallVectorImpl<Type> &inferredReturnTypes
301) {
302 inferredReturnTypes.resize(1);
303 Type lvalType = adaptor.getArrRef().getType();
304 assert(llvm::isa<ArrayType>(lvalType)); // per ODS spec of ReadArrayOp
305 inferredReturnTypes[0] = llvm::cast<ArrayType>(lvalType).getElementType();
306 return success();
307}
308
309bool ReadArrayOp::isCompatibleReturnTypes(TypeRange l, TypeRange r) {
310 return singletonTypeListsUnify(l, r);
311}
312
313LogicalResult ReadArrayOp::verify() {
314 // Ensure the number of indices used match the shape of the array exactly.
315 return ensureNumIndicesMatchDims(getArrRefType(), getIndices().size(), getEmitOpErrFn(this));
316}
317
320 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
321 SmallVectorImpl<OpOperand *> &newBlockingUses, const DataLayout & /*datalayout*/
322) {
323 if (blockingUses.size() != 1) {
324 return false;
325 }
326 Value blockingUse = (*blockingUses.begin())->get();
327 return blockingUse == slot.ptr && getArrRef() == slot.ptr &&
328 getResult().getType() == slot.elemType;
329}
330
333 const MemorySlot & /*slot*/, const SmallPtrSetImpl<OpOperand *> &blockingUses,
334 OpBuilder & /*builder*/, Value reachingDefinition, const DataLayout & /*dataLayout*/
335) {
336 // `canUsesBeRemoved` checked this blocking use must be the loaded `slot.ptr`
337 getResult().replaceAllUsesWith(reachingDefinition);
338 return DeletionKind::Delete;
339}
340
341//===------------------------------------------------------------------===//
342// WriteArrayOp
343//===------------------------------------------------------------------===//
344
345LogicalResult WriteArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
346 // Ensure any SymbolRef used in the type are valid
348 tables, *this, ArrayRef<Type> {getArrRefType(), getRvalue().getType()}
349 );
350}
351
352LogicalResult WriteArrayOp::verify() {
353 // Ensure the number of indices used match the shape of the array exactly.
354 return ensureNumIndicesMatchDims(getArrRefType(), getIndices().size(), getEmitOpErrFn(this));
355}
356
359 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
360 SmallVectorImpl<OpOperand *> &newBlockingUses, const DataLayout & /*datalayout*/
361) {
362 if (blockingUses.size() != 1) {
363 return false;
364 }
365 Value blockingUse = (*blockingUses.begin())->get();
366 return blockingUse == slot.ptr && getArrRef() == slot.ptr && getRvalue() != slot.ptr &&
367 getRvalue().getType() == slot.elemType;
368}
369
372 const MemorySlot &, const SmallPtrSetImpl<OpOperand *> &, OpBuilder &, Value, const DataLayout &
373) {
374 return DeletionKind::Delete;
375}
376
377//===------------------------------------------------------------------===//
378// ExtractArrayOp
379//===------------------------------------------------------------------===//
380
381LogicalResult ExtractArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
382 // Ensure any SymbolRef used in the type are valid
383 return verifyTypeResolution(tables, *this, getArrRefType());
384}
385
387 MLIRContext *context, std::optional<Location> location, ExtractArrayOpAdaptor adaptor,
388 llvm::SmallVectorImpl<Type> &inferredReturnTypes
389) {
390 size_t numToSkip = adaptor.getIndices().size();
391 Type arrRefType = adaptor.getArrRef().getType();
392 assert(llvm::isa<ArrayType>(arrRefType)); // per ODS spec of ExtractArrayOp
393 ArrayType arrRefArrType = llvm::cast<ArrayType>(arrRefType);
394 ArrayRef<Attribute> arrRefDimSizes = arrRefArrType.getDimensionSizes();
395
396 // Check for invalid cases
397 auto compare = numToSkip <=> arrRefDimSizes.size();
398 if (compare == 0) {
399 return mlir::emitOptionalError(
400 location, '\'', ExtractArrayOp::getOperationName(),
401 "' op cannot select all dimensions of an array. Use '", ReadArrayOp::getOperationName(),
402 "' instead."
403 );
404 } else if (compare > 0) {
405 return mlir::emitOptionalError(
406 location, '\'', ExtractArrayOp::getOperationName(),
407 "' op cannot select more dimensions than exist in the source array"
408 );
409 }
410
411 // Generate and store reduced array type
412 inferredReturnTypes.resize(1);
413 inferredReturnTypes[0] =
414 ArrayType::get(arrRefArrType.getElementType(), arrRefDimSizes.drop_front(numToSkip));
415 return success();
416}
417
418bool ExtractArrayOp::isCompatibleReturnTypes(TypeRange l, TypeRange r) {
419 return singletonTypeListsUnify(l, r);
420}
421
422//===------------------------------------------------------------------===//
423// InsertArrayOp
424//===------------------------------------------------------------------===//
425
426LogicalResult InsertArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
427 // Ensure any SymbolRef used in the types are valid
429 tables, *this, ArrayRef<Type> {getArrRefType(), getRvalue().getType()}
430 );
431}
432
433LogicalResult InsertArrayOp::verify() {
434 ArrayType baseArrRefArrType = getArrRefType();
435 Type rValueType = getRvalue().getType();
436 assert(llvm::isa<ArrayType>(rValueType)); // per ODS spec of InsertArrayOp
437 ArrayType rValueArrType = llvm::cast<ArrayType>(rValueType);
438
439 // size of lhs dimensions == numIndices + size of rhs dimensions
440 size_t lhsDims = baseArrRefArrType.getDimensionSizes().size();
441 size_t numIndices = getIndices().size();
442 size_t rhsDims = rValueArrType.getDimensionSizes().size();
443
444 // Ensure the number of indices specified does not exceed base dimension count.
445 if (numIndices > lhsDims) {
446 return emitOpError("cannot select more dimensions than exist in the source array");
447 }
448
449 // Ensure the rValue dimension count equals the base reduced dimension count
450 auto compare = (numIndices + rhsDims) <=> lhsDims;
451 if (compare != 0) {
452 return emitOpError().append(
453 "has ", (compare < 0 ? "insufficient" : "too many"), " indexed dimensions: expected ",
454 (lhsDims - rhsDims), " but found ", numIndices
455 );
456 }
457
458 // Having verified the indices are of appropriate size, we verify the subarray type.
459 // This will verify the dimensions of the subarray, which is why we only check the
460 // size of the indices above.
461 return verifySubArrayType(getEmitOpErrFn(this), baseArrRefArrType, rValueArrType);
462}
463
464//===------------------------------------------------------------------===//
465// ArrayLengthOp
466//===------------------------------------------------------------------===//
467
468LogicalResult ArrayLengthOp::verifySymbolUses(SymbolTableCollection &tables) {
469 // Ensure any SymbolRef used in the type are valid
470 return verifyTypeResolution(tables, *this, getArrRefType());
471}
472
473} // namespace llzk::array
::mlir::DeletionKind rewire(const ::mlir::DestructurableMemorySlot &slot, ::llvm::DenseMap<::mlir::Attribute, ::mlir::MemorySlot > &subslots, ::mlir::OpBuilder &builder, const ::mlir::DataLayout &dataLayout)
Required by companion interface DestructurableAccessorOpInterface / SROA pass.
Definition Ops.cpp:246
::mlir::Operation::operand_range getIndices()
Gets the operand range containing the index for each dimension.
::mlir::OpOperand & getArrRefMutable()
Gets the mutable operand slot holding the SSA Value for the referenced array.
inline ::mlir::ArrayRef<::mlir::Attribute > getValueOperandDims()
Compute the dimensions of the read/write value.
::mlir::ArrayAttr indexOperandsToAttributeArray()
Returns the multi-dimensional indices of the array access as an Attribute array or a null pointer if ...
Definition Ops.cpp:211
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Gets the SSA Value for the referenced array.
bool canRewire(const ::mlir::DestructurableMemorySlot &slot, ::llvm::SmallPtrSetImpl<::mlir::Attribute > &usedIndices, ::mlir::SmallVectorImpl<::mlir::MemorySlot > &mustBeSafelyUsed, const ::mlir::DataLayout &dataLayout)
Required by companion interface DestructurableAccessorOpInterface / SROA pass.
Definition Ops.cpp:222
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced array.
::mlir::MutableOperandRange getIndicesMutable()
Gets the mutable operand range containing the index for each dimension.
static ArrayIndexGen from(ArrayType)
Construct new ArrayIndexGen. Will assert if hasStaticShape() is false.
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:192
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:468
::mlir::Type getElementType() const
::std::optional<::llvm::DenseMap<::mlir::Attribute, ::mlir::Type > > getSubelementIndexMap() const
Required by DestructurableTypeInterface / SROA pass.
Definition Types.cpp:118
static ArrayType get(::mlir::Type elementType, ::llvm::ArrayRef<::mlir::Attribute > dimensionSizes)
Definition Types.cpp.inc:83
::llvm::ArrayRef<::mlir::Attribute > getDimensionSizes() const
static void printInferredArrayType(::mlir::OpAsmPrinter &printer, CreateArrayOp, ::mlir::TypeRange, ::mlir::OperandRange, ::mlir::Type)
Definition Ops.cpp:94
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::llzk::array::ArrayType result, ::mlir::ValueRange elements={})
::mlir::TypedValue<::llzk::array::ArrayType > getResult()
Definition Ops.h.inc:408
::mlir::ParseResult parseInferredArrayType(::mlir::OpAsmParser &parser, ::llvm::SmallVector<::mlir::Type, 1 > &elementsTypes, ::mlir::ArrayRef<::mlir::OpAsmParser::UnresolvedOperand > elements, ::mlir::Type resultType)
Definition Ops.cpp:81
::llvm::SmallVector<::mlir::DestructurableMemorySlot > getDestructurableSlots()
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:119
::std::optional<::mlir::PromotableAllocationOpInterface > handlePromotionComplete(const ::mlir::MemorySlot &slot, ::mlir::Value defaultValue, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:193
::std::optional<::mlir::DestructurableAllocationOpInterface > handleDestructuringComplete(const ::mlir::DestructurableMemorySlot &slot, ::mlir::OpBuilder &builder)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:162
::llvm::LogicalResult verify()
Definition Ops.cpp:100
::mlir::Value getDefaultValue(const ::mlir::MemorySlot &slot, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:185
::llvm::SmallVector<::mlir::MemorySlot > getPromotableSlots()
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:171
::llvm::DenseMap<::mlir::Attribute, ::mlir::MemorySlot > destructure(const ::mlir::DestructurableMemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::Attribute > &usedIndices, ::mlir::OpBuilder &builder, ::mlir::SmallVectorImpl<::mlir::DestructurableAllocationOpInterface > &newAllocators)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:132
::llvm::ArrayRef< int32_t > getNumDimsPerMap()
Definition Ops.cpp.inc:541
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:71
void handleBlockArgument(const ::mlir::MemorySlot &slot, ::mlir::BlockArgument argument, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:190
::mlir::OperandRangeRange getMapOperands()
Definition Ops.h.inc:392
::mlir::Operation::operand_range getElements()
Definition Ops.h.inc:388
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:66
static bool isCompatibleReturnTypes(::mlir::TypeRange l, ::mlir::TypeRange r)
Definition Ops.cpp:418
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:381
::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location > location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type > &inferredReturnTypes)
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:638
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:576
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:792
::mlir::Operation::operand_range getIndices()
Definition Ops.h.inc:751
::llvm::LogicalResult verify()
Definition Ops.cpp:433
::mlir::TypedValue<::llzk::array::ArrayType > getRvalue()
Definition Ops.h.inc:755
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:426
::mlir::DeletionKind removeBlockingUses(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl< mlir::OpOperand * > &blockingUses, ::mlir::OpBuilder &builder, ::mlir::Value reachingDefinition, const ::mlir::DataLayout &dataLayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:332
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:956
::mlir::TypedValue<::mlir::Type > getResult()
Definition Ops.h.inc:921
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Definition Ops.h.inc:897
::mlir::Operation::operand_range getIndices()
Definition Ops.h.inc:901
::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location > location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type > &inferredReturnTypes)
::llvm::LogicalResult verify()
Definition Ops.cpp:313
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:293
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:886
static bool isCompatibleReturnTypes(::mlir::TypeRange l, ::mlir::TypeRange r)
Definition Ops.cpp:309
bool canUsesBeRemoved(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::OpOperand * > &blockingUses, ::llvm::SmallVectorImpl<::mlir::OpOperand * > &newBlockingUses, const ::mlir::DataLayout &datalayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:319
::llvm::LogicalResult verify()
Definition Ops.cpp:352
::mlir::Operation::operand_range getIndices()
Definition Ops.h.inc:1069
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:1117
bool canUsesBeRemoved(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::OpOperand * > &blockingUses, ::llvm::SmallVectorImpl<::mlir::OpOperand * > &newBlockingUses, const ::mlir::DataLayout &datalayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:358
::mlir::DeletionKind removeBlockingUses(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl< mlir::OpOperand * > &blockingUses, ::mlir::OpBuilder &builder, ::mlir::Value reachingDefinition, const ::mlir::DataLayout &dataLayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:371
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Definition Ops.h.inc:1065
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:345
::mlir::TypedValue<::mlir::Type > getRvalue()
Definition Ops.h.inc:1073
OpClass::Properties & buildInstantiationAttrs(mlir::OpBuilder &odsBuilder, mlir::OperationState &odsState, mlir::ArrayRef< mlir::ValueRange > mapOperands, mlir::DenseI32ArrayAttr numDimsPerMap, int32_t firstSegmentSize=0)
Utility for build() functions that initializes the operandSegmentSizes, mapOpGroupSizes,...
LogicalResult verifyAffineMapInstantiations(OperandRangeRange mapOps, ArrayRef< int32_t > numDimsPerMap, ArrayRef< AffineMapAttr > mapAttrs, Operation *origin)
OpClass::Properties & buildInstantiationAttrsEmpty(mlir::OpBuilder &odsBuilder, mlir::OperationState &odsState, int32_t firstSegmentSize=0)
Utility for build() functions that initializes the operandSegmentSizes, mapOpGroupSizes,...
LogicalResult verifySubArrayType(EmitErrorFn emitError, ArrayType arrayType, ArrayType subArrayType)
Determine if the subArrayType is a valid subarray of arrayType.
bool singletonTypeListsUnify(Iter1 lhs, Iter2 rhs, mlir::ArrayRef< llvm::StringRef > rhsReversePrefix={}, UnificationMap *unifications=nullptr)
Definition TypeHelper.h:236
LogicalResult verifyTypeResolution(SymbolTableCollection &tables, Operation *origin, Type ty)
OwningEmitErrorFn getEmitOpErrFn(mlir::Operation *op)
std::function< InFlightDiagnosticWrapper()> OwningEmitErrorFn
This type is required in cases like the functions below to take ownership of the lambda so it is not ...