MLIR  17.0.0git
ViewLikeInterface.cpp
Go to the documentation of this file.
1 //===- ViewLikeInterface.cpp - View-like operations in MLIR ---------------===//
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 
10 
11 using namespace mlir;
12 
13 //===----------------------------------------------------------------------===//
14 // ViewLike Interfaces
15 //===----------------------------------------------------------------------===//
16 
17 /// Include the definitions of the loop-like interfaces.
18 #include "mlir/Interfaces/ViewLikeInterface.cpp.inc"
19 
21  StringRef name,
22  unsigned numElements,
23  ArrayRef<int64_t> staticVals,
24  ValueRange values) {
25  // Check static and dynamic offsets/sizes/strides does not overflow type.
26  if (staticVals.size() != numElements)
27  return op->emitError("expected ")
28  << numElements << " " << name << " values";
29  unsigned expectedNumDynamicEntries =
30  llvm::count_if(staticVals, [&](int64_t staticVal) {
31  return ShapedType::isDynamic(staticVal);
32  });
33  if (values.size() != expectedNumDynamicEntries)
34  return op->emitError("expected ")
35  << expectedNumDynamicEntries << " dynamic " << name << " values";
36  return success();
37 }
38 
40 mlir::detail::verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op) {
41  std::array<unsigned, 3> maxRanks = op.getArrayAttrMaxRanks();
42  // Offsets can come in 2 flavors:
43  // 1. Either single entry (when maxRanks == 1).
44  // 2. Or as an array whose rank must match that of the mixed sizes.
45  // So that the result type is well-formed.
46  if (!(op.getMixedOffsets().size() == 1 && maxRanks[0] == 1) && // NOLINT
47  op.getMixedOffsets().size() != op.getMixedSizes().size())
48  return op->emitError(
49  "expected mixed offsets rank to match mixed sizes rank (")
50  << op.getMixedOffsets().size() << " vs " << op.getMixedSizes().size()
51  << ") so the rank of the result type is well-formed.";
52  // Ranks of mixed sizes and strides must always match so the result type is
53  // well-formed.
54  if (op.getMixedSizes().size() != op.getMixedStrides().size())
55  return op->emitError(
56  "expected mixed sizes rank to match mixed strides rank (")
57  << op.getMixedSizes().size() << " vs " << op.getMixedStrides().size()
58  << ") so the rank of the result type is well-formed.";
59 
60  if (failed(verifyListOfOperandsOrIntegers(op, "offset", maxRanks[0],
61  op.static_offsets(), op.offsets())))
62  return failure();
63  if (failed(verifyListOfOperandsOrIntegers(op, "size", maxRanks[1],
64  op.static_sizes(), op.sizes())))
65  return failure();
66  if (failed(verifyListOfOperandsOrIntegers(op, "stride", maxRanks[2],
67  op.static_strides(), op.strides())))
68  return failure();
69  return success();
70 }
71 
73  OperandRange values,
74  ArrayRef<int64_t> integers) {
75  printer << '[';
76  if (integers.empty()) {
77  printer << "]";
78  return;
79  }
80  unsigned idx = 0;
81  llvm::interleaveComma(integers, printer, [&](int64_t integer) {
82  if (ShapedType::isDynamic(integer))
83  printer << values[idx++];
84  else
85  printer << integer;
86  });
87  printer << ']';
88 }
89 
91  OpAsmParser &parser,
93  DenseI64ArrayAttr &integers) {
94 
95  SmallVector<int64_t, 4> integerVals;
96  auto parseIntegerOrValue = [&]() {
98  auto res = parser.parseOptionalOperand(operand);
99  if (res.has_value() && succeeded(res.value())) {
100  values.push_back(operand);
101  integerVals.push_back(ShapedType::kDynamic);
102  } else {
103  int64_t integer;
104  if (failed(parser.parseInteger(integer)))
105  return failure();
106  integerVals.push_back(integer);
107  }
108  return success();
109  };
111  parseIntegerOrValue,
112  " in dynamic index list"))
113  return parser.emitError(parser.getNameLoc())
114  << "expected SSA value or integer";
115  integers = parser.getBuilder().getDenseI64ArrayAttr(integerVals);
116  return success();
117 }
118 
120  OffsetSizeAndStrideOpInterface a, OffsetSizeAndStrideOpInterface b,
122  if (a.static_offsets().size() != b.static_offsets().size())
123  return false;
124  if (a.static_sizes().size() != b.static_sizes().size())
125  return false;
126  if (a.static_strides().size() != b.static_strides().size())
127  return false;
128  for (auto it : llvm::zip(a.getMixedOffsets(), b.getMixedOffsets()))
129  if (!cmp(std::get<0>(it), std::get<1>(it)))
130  return false;
131  for (auto it : llvm::zip(a.getMixedSizes(), b.getMixedSizes()))
132  if (!cmp(std::get<0>(it), std::get<1>(it)))
133  return false;
134  for (auto it : llvm::zip(a.getMixedStrides(), b.getMixedStrides()))
135  if (!cmp(std::get<0>(it), std::get<1>(it)))
136  return false;
137  return true;
138 }
@ Square
Square brackets surrounding zero or more operands.
virtual ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())=0
Parse a list of comma-separated items with an optional delimiter.
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
ParseResult parseInteger(IntT &result)
Parse an integer value from the stream.
virtual SMLoc getNameLoc() const =0
Return the location of the original name token.
DenseI64ArrayAttr getDenseI64ArrayAttr(ArrayRef< int64_t > values)
Definition: Builders.cpp:157
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
virtual OptionalParseResult parseOptionalOperand(UnresolvedOperand &result, bool allowResultNumber=true)=0
Parse a single operand if present.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This class represents a single result from folding an operation.
Definition: OpDefinition.h:233
This class implements the operand iterators for the Operation class.
Definition: ValueRange.h:42
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:75
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:224
This class represents success/failure for parsing-like operations that find it important to chain tog...
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:350
Base class for DenseArrayAttr that is instantiated and specialized for each supported element type be...
bool sameOffsetsSizesAndStrides(OffsetSizeAndStrideOpInterface a, OffsetSizeAndStrideOpInterface b, llvm::function_ref< bool(OpFoldResult, OpFoldResult)> cmp)
LogicalResult verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op)
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
void printDynamicIndexList(OpAsmPrinter &printer, Operation *op, OperandRange values, ArrayRef< int64_t > integers)
Printer hook for custom directive in assemblyFormat.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
Definition: LogicalResult.h:68
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
ParseResult parseDynamicIndexList(OpAsmParser &parser, SmallVectorImpl< OpAsmParser::UnresolvedOperand > &values, DenseI64ArrayAttr &integers)
Pasrer hook for custom directive in assemblyFormat.
LogicalResult verifyListOfOperandsOrIntegers(Operation *op, StringRef name, unsigned expectedNumElements, ArrayRef< int64_t > attr, ValueRange values)
Verify that a the values has as many elements as the number of entries in attr for which isDynamic ev...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
This is the representation of an operand reference.