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 RewriterBase &rewriter
135) {
136 assert(slot.ptr == getResult());
137 assert(slot.elemType == getType());
138
139 rewriter.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.elementPtrs.lookup(indexAsArray));
149
150 ArrayType destructAsArrayTy = llvm::dyn_cast<ArrayType>(destructAs);
151 assert(destructAsArrayTy && "expected ArrayType");
152
153 auto subCreate = rewriter.create<CreateArrayOp>(getLoc(), destructAsArrayTy);
154 slotMap.try_emplace<MemorySlot>(index, {subCreate.getResult(), destructAs});
155 }
156
157 return slotMap;
158}
159
162 const DestructurableMemorySlot &slot, RewriterBase &rewriter
163) {
164 assert(slot.ptr == getResult());
165 rewriter.eraseOp(*this);
166}
167
169SmallVector<MemorySlot> CreateArrayOp::getPromotableSlots() {
170 ArrayType arrType = getType();
171 if (!arrType.hasStaticShape()) {
172 return {};
173 }
174 // Can only support arrays containing a single element (the SROA pass can be run first to
175 // destructure all arrays into size-1 arrays).
176 if (arrType.getNumElements() != 1) {
177 return {};
178 }
179 return {MemorySlot {getResult(), arrType.getElementType()}};
180}
181
183Value CreateArrayOp::getDefaultValue(const MemorySlot &slot, RewriterBase &rewriter) {
184 return rewriter.create<undef::UndefOp>(getLoc(), slot.elemType);
185}
186
188void CreateArrayOp::handleBlockArgument(const MemorySlot &, BlockArgument, RewriterBase &) {}
189
192 const MemorySlot &slot, Value defaultValue, RewriterBase &rewriter
193) {
194 if (defaultValue.use_empty()) {
195 rewriter.eraseOp(defaultValue.getDefiningOp());
196 } else {
197 rewriter.eraseOp(*this);
198 }
199}
200
201//===------------------------------------------------------------------===//
202// ArrayAccessOpInterface
203//===------------------------------------------------------------------===//
204
208 ArrayType arrTy = getArrRefType();
209 if (arrTy.hasStaticShape()) {
210 if (auto converted = ArrayIndexGen::from(arrTy).checkAndConvert(getIndices())) {
211 return ArrayAttr::get(getContext(), *converted);
212 }
213 }
214 return nullptr;
215}
216
219 const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices,
220 SmallVectorImpl<MemorySlot> &mustBeSafelyUsed
221) {
222 if (slot.ptr != getArrRef()) {
223 return false;
224 }
225
226 ArrayAttr indexAsAttr = indexOperandsToAttributeArray();
227 if (!indexAsAttr) {
228 return false;
229 }
230
231 // Scalar read/write case has 0 dimensions in the read/write value.
232 if (!getValueOperandDims().empty()) {
233 return false;
234 }
235
236 // Just insert the index.
237 usedIndices.insert(indexAsAttr);
238 return true;
239}
240
243 const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots,
244 RewriterBase &rewriter
245) {
246 assert(slot.ptr == getArrRef());
247 assert(slot.elemType == getArrRefType());
248 // ASSERT: non-scalar read/write should have been desugared earlier
249 assert(getValueOperandDims().empty() && "only scalar read/write supported");
250
251 ArrayAttr indexAsAttr = indexOperandsToAttributeArray();
252 assert(indexAsAttr && "canRewire() should have returned false");
253 const MemorySlot &memorySlot = subslots.at(indexAsAttr);
254
255 // Write to the sub-slot created for the index of `this`, using index 0
256 auto idx0 = rewriter.create<arith::ConstantIndexOp>(getLoc(), 0);
257 rewriter.modifyOpInPlace(*this, [&]() {
258 getArrRefMutable().set(memorySlot.ptr);
259 getIndicesMutable().clear();
260 getIndicesMutable().assign(idx0);
261 });
262 return DeletionKind::Keep;
263}
264
265//===------------------------------------------------------------------===//
266// ReadArrayOp
267//===------------------------------------------------------------------===//
268
269namespace {
270
271LogicalResult
272ensureNumIndicesMatchDims(ArrayType ty, size_t numIndices, const OwningEmitErrorFn &errFn) {
273 ArrayRef<Attribute> dims = ty.getDimensionSizes();
274 // Ensure the number of provided indices matches the array dimensions
275 auto compare = numIndices <=> dims.size();
276 if (compare != 0) {
277 return errFn().append(
278 "has ", (compare < 0 ? "insufficient" : "too many"), " indexed dimensions: expected ",
279 dims.size(), " but found ", numIndices
280 );
281 }
282 return success();
283}
284
285} // namespace
286
287LogicalResult ReadArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
288 // Ensure any SymbolRef used in the type are valid
289 return verifyTypeResolution(tables, *this, ArrayRef<Type> {getArrRef().getType(), getType()});
290}
291
293 MLIRContext *context, std::optional<Location> location, ReadArrayOpAdaptor adaptor,
294 llvm::SmallVectorImpl<Type> &inferredReturnTypes
295) {
296 inferredReturnTypes.resize(1);
297 Type lvalType = adaptor.getArrRef().getType();
298 assert(llvm::isa<ArrayType>(lvalType)); // per ODS spec of ReadArrayOp
299 inferredReturnTypes[0] = llvm::cast<ArrayType>(lvalType).getElementType();
300 return success();
301}
302
303bool ReadArrayOp::isCompatibleReturnTypes(TypeRange l, TypeRange r) {
304 return singletonTypeListsUnify(l, r);
305}
306
307LogicalResult ReadArrayOp::verify() {
308 // Ensure the number of indices used match the shape of the array exactly.
309 return ensureNumIndicesMatchDims(getArrRefType(), getIndices().size(), getEmitOpErrFn(this));
310}
311
314 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
315 SmallVectorImpl<OpOperand *> &newBlockingUses
316) {
317 if (blockingUses.size() != 1) {
318 return false;
319 }
320 Value blockingUse = (*blockingUses.begin())->get();
321 return blockingUse == slot.ptr && getArrRef() == slot.ptr &&
322 getResult().getType() == slot.elemType;
323}
324
327 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
328 RewriterBase &rewriter, Value reachingDefinition
329) {
330 // `canUsesBeRemoved` checked this blocking use must be the loaded `slot.ptr`
331 rewriter.replaceAllUsesWith(getResult(), reachingDefinition);
332 return DeletionKind::Delete;
333}
334
335//===------------------------------------------------------------------===//
336// WriteArrayOp
337//===------------------------------------------------------------------===//
338
339LogicalResult WriteArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
340 // Ensure any SymbolRef used in the type are valid
342 tables, *this, ArrayRef<Type> {getArrRefType(), getRvalue().getType()}
343 );
344}
345
346LogicalResult WriteArrayOp::verify() {
347 // Ensure the number of indices used match the shape of the array exactly.
348 return ensureNumIndicesMatchDims(getArrRefType(), getIndices().size(), getEmitOpErrFn(this));
349}
350
353 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
354 SmallVectorImpl<OpOperand *> &newBlockingUses
355) {
356 if (blockingUses.size() != 1) {
357 return false;
358 }
359 Value blockingUse = (*blockingUses.begin())->get();
360 return blockingUse == slot.ptr && getArrRef() == slot.ptr && getRvalue() != slot.ptr &&
361 getRvalue().getType() == slot.elemType;
362}
363
366 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
367 RewriterBase &rewriter, Value reachingDefinition
368) {
369 return DeletionKind::Delete;
370}
371
372//===------------------------------------------------------------------===//
373// ExtractArrayOp
374//===------------------------------------------------------------------===//
375
376LogicalResult ExtractArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
377 // Ensure any SymbolRef used in the type are valid
378 return verifyTypeResolution(tables, *this, getArrRefType());
379}
380
382 MLIRContext *context, std::optional<Location> location, ExtractArrayOpAdaptor adaptor,
383 llvm::SmallVectorImpl<Type> &inferredReturnTypes
384) {
385 size_t numToSkip = adaptor.getIndices().size();
386 Type arrRefType = adaptor.getArrRef().getType();
387 assert(llvm::isa<ArrayType>(arrRefType)); // per ODS spec of ExtractArrayOp
388 ArrayType arrRefArrType = llvm::cast<ArrayType>(arrRefType);
389 ArrayRef<Attribute> arrRefDimSizes = arrRefArrType.getDimensionSizes();
390
391 // Check for invalid cases
392 auto compare = numToSkip <=> arrRefDimSizes.size();
393 if (compare == 0) {
394 return mlir::emitOptionalError(
395 location, "'", ExtractArrayOp::getOperationName(),
396 "' op cannot select all dimensions of an array. Use '", ReadArrayOp::getOperationName(),
397 "' instead."
398 );
399 } else if (compare > 0) {
400 return mlir::emitOptionalError(
401 location, "'", ExtractArrayOp::getOperationName(),
402 "' op cannot select more dimensions than exist in the source array"
403 );
404 }
405
406 // Generate and store reduced array type
407 inferredReturnTypes.resize(1);
408 inferredReturnTypes[0] =
409 ArrayType::get(arrRefArrType.getElementType(), arrRefDimSizes.drop_front(numToSkip));
410 return success();
411}
412
413bool ExtractArrayOp::isCompatibleReturnTypes(TypeRange l, TypeRange r) {
414 return singletonTypeListsUnify(l, r);
415}
416
417//===------------------------------------------------------------------===//
418// InsertArrayOp
419//===------------------------------------------------------------------===//
420
421LogicalResult InsertArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
422 // Ensure any SymbolRef used in the types are valid
424 tables, *this, ArrayRef<Type> {getArrRefType(), getRvalue().getType()}
425 );
426}
427
428LogicalResult InsertArrayOp::verify() {
429 size_t numIndices = getIndices().size();
430
431 ArrayType baseArrRefArrType = getArrRefType();
432
433 Type rValueType = getRvalue().getType();
434 assert(llvm::isa<ArrayType>(rValueType)); // per ODS spec of InsertArrayOp
435 ArrayType rValueArrType = llvm::cast<ArrayType>(rValueType);
436
437 ArrayRef<Attribute> dimsFromBase = baseArrRefArrType.getDimensionSizes();
438 // Ensure the number of indices specified does not exceed base dimension count.
439 if (numIndices > dimsFromBase.size()) {
440 return emitOpError("cannot select more dimensions than exist in the source array");
441 }
442
443 ArrayRef<Attribute> dimsFromRValue = rValueArrType.getDimensionSizes();
444 ArrayRef<Attribute> dimsFromBaseReduced = dimsFromBase.drop_front(numIndices);
445 // Ensure the rValue dimension count equals the base reduced dimension count
446 auto compare = dimsFromRValue.size() <=> dimsFromBaseReduced.size();
447 if (compare != 0) {
448 return emitOpError().append(
449 "has ", (compare < 0 ? "insufficient" : "too many"), " indexed dimensions: expected ",
450 (dimsFromBase.size() - dimsFromRValue.size()), " but found ", numIndices
451 );
452 }
453
454 // Ensure dimension sizes are compatible (ignoring the indexed dimensions)
455 if (!typeParamsUnify(dimsFromBaseReduced, dimsFromRValue)) {
456 std::string message;
457 llvm::raw_string_ostream ss(message);
458 auto appendOne = [&ss](Attribute a) { appendWithoutType(ss, a); };
459 ss << "cannot unify array dimensions [";
460 llvm::interleaveComma(dimsFromBaseReduced, ss, appendOne);
461 ss << "] with [";
462 llvm::interleaveComma(dimsFromRValue, ss, appendOne);
463 ss << "]";
464 return emitOpError().append(message);
465 }
466
467 // Ensure element types of the arrays are compatible
468 if (!typesUnify(baseArrRefArrType.getElementType(), rValueArrType.getElementType())) {
469 return emitOpError().append(
470 "incorrect array element type; expected: ", baseArrRefArrType.getElementType(),
471 ", found: ", rValueArrType.getElementType()
472 );
473 }
474
475 return success();
476}
477
478//===------------------------------------------------------------------===//
479// ArrayLengthOp
480//===------------------------------------------------------------------===//
481
482LogicalResult ArrayLengthOp::verifySymbolUses(SymbolTableCollection &tables) {
483 // Ensure any SymbolRef used in the type are valid
484 return verifyTypeResolution(tables, *this, getArrRefType());
485}
486
487} // namespace llzk::array
::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.
bool canRewire(const ::mlir::DestructurableMemorySlot &slot, ::llvm::SmallPtrSetImpl<::mlir::Attribute > &usedIndices, ::mlir::SmallVectorImpl<::mlir::MemorySlot > &mustBeSafelyUsed)
Required by companion interface DestructurableAccessorOpInterface / SROA pass.
Definition Ops.cpp:218
::mlir::DeletionKind rewire(const ::mlir::DestructurableMemorySlot &slot, ::llvm::DenseMap<::mlir::Attribute, ::mlir::MemorySlot > &subslots, ::mlir::RewriterBase &rewriter)
Required by companion interface DestructurableAccessorOpInterface / SROA pass.
Definition Ops.cpp:242
::mlir::ArrayAttr indexOperandsToAttributeArray()
Returns the multi-dimensional indices of the array access as an Attribute array or a null pointer if ...
Definition Ops.cpp:207
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Gets the SSA Value for the referenced array.
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:158
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:482
::mlir::Type getElementType() const
::std::optional<::llvm::DenseMap<::mlir::Attribute, ::mlir::Type > > getSubelementIndexMap() const
Required by DestructurableTypeInterface / SROA pass.
Definition Types.cpp:121
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={})
void handlePromotionComplete(const ::mlir::MemorySlot &slot, ::mlir::Value defaultValue, ::mlir::RewriterBase &rewriter)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:191
::llvm::DenseMap<::mlir::Attribute, ::mlir::MemorySlot > destructure(const ::mlir::DestructurableMemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::Attribute > &usedIndices, ::mlir::RewriterBase &rewriter)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:132
::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
::mlir::Value getDefaultValue(const ::mlir::MemorySlot &slot, ::mlir::RewriterBase &rewriter)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:183
::mlir::LogicalResult verify()
Definition Ops.cpp:100
void handleDestructuringComplete(const ::mlir::DestructurableMemorySlot &slot, ::mlir::RewriterBase &rewriter)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:161
::llvm::SmallVector<::mlir::MemorySlot > getPromotableSlots()
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:169
void handleBlockArgument(const ::mlir::MemorySlot &slot, ::mlir::BlockArgument argument, ::mlir::RewriterBase &rewriter)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:188
::llvm::ArrayRef< int32_t > getNumDimsPerMap()
Definition Ops.cpp.inc:653
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:71
::mlir::OperandRangeRange getMapOperands()
Definition Ops.cpp.inc:412
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:66
::mlir::Operation::operand_range getElements()
Definition Ops.cpp.inc:408
::mlir::TypedValue<::llzk::array::ArrayType > getResult()
Definition Ops.cpp.inc:438
static bool isCompatibleReturnTypes(::mlir::TypeRange l, ::mlir::TypeRange r)
Definition Ops.cpp:413
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:376
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:523
::mlir::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)
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:487
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:640
::mlir::TypedValue<::llzk::array::ArrayType > getRvalue()
Definition Ops.cpp.inc:1184
::mlir::Operation::operand_range getIndices()
Definition Ops.cpp.inc:1180
::mlir::LogicalResult verify()
Definition Ops.cpp:428
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:421
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:771
::mlir::Operation::operand_range getIndices()
Definition Ops.cpp.inc:1442
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Definition Ops.cpp.inc:1438
::mlir::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)
::mlir::LogicalResult verify()
Definition Ops.cpp:307
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:287
bool canUsesBeRemoved(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::OpOperand * > &blockingUses, ::llvm::SmallVectorImpl<::mlir::OpOperand * > &newBlockingUses)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:313
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:727
static bool isCompatibleReturnTypes(::mlir::TypeRange l, ::mlir::TypeRange r)
Definition Ops.cpp:303
::mlir::DeletionKind removeBlockingUses(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl< mlir::OpOperand * > &blockingUses, ::mlir::RewriterBase &rewriter, ::mlir::Value reachingDefinition)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:326
::mlir::Value getResult()
Definition Ops.cpp.inc:1467
bool canUsesBeRemoved(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::OpOperand * > &blockingUses, ::llvm::SmallVectorImpl<::mlir::OpOperand * > &newBlockingUses)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:352
::mlir::Operation::operand_range getIndices()
Definition Ops.cpp.inc:1768
::mlir::LogicalResult verify()
Definition Ops.cpp:346
::mlir::DeletionKind removeBlockingUses(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl< mlir::OpOperand * > &blockingUses, ::mlir::RewriterBase &rewriter, ::mlir::Value reachingDefinition)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:365
::mlir::Value getRvalue()
Definition Ops.cpp.inc:1772
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:895
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Definition Ops.cpp.inc:1764
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:339
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,...
bool singletonTypeListsUnify(Iter1 lhs, Iter2 rhs, mlir::ArrayRef< llvm::StringRef > rhsReversePrefix={}, UnificationMap *unifications=nullptr)
Definition TypeHelper.h:232
std::function< mlir::InFlightDiagnostic()> OwningEmitErrorFn
Definition ErrorHelper.h:22
LogicalResult verifyTypeResolution(SymbolTableCollection &tables, Operation *origin, Type ty)
OwningEmitErrorFn getEmitOpErrFn(mlir::Operation *op)
Definition ErrorHelper.h:24
bool typesUnify(Type lhs, Type rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
bool typeParamsUnify(const ArrayRef< Attribute > &lhsParams, const ArrayRef< Attribute > &rhsParams, UnificationMap *unifications)
void appendWithoutType(mlir::raw_ostream &os, mlir::Attribute a)