MLIR 22.0.0git
MatchInterfaces.cpp
Go to the documentation of this file.
1//===- MatchInterfaces.cpp - Transform Dialect Interfaces -----------------===//
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#include "llvm/Support/InterleavedRange.h"
12
13using namespace mlir;
14
15//===----------------------------------------------------------------------===//
16// Printing and parsing for match ops.
17//===----------------------------------------------------------------------===//
18
19/// Keyword syntax for positional specification inversion.
20constexpr const static llvm::StringLiteral kDimExceptKeyword = "except";
21
22/// Keyword syntax for full inclusion in positional specification.
23constexpr const static llvm::StringLiteral kDimAllKeyword = "all";
24
26 DenseI64ArrayAttr &rawDimList,
27 UnitAttr &isInverted,
28 UnitAttr &isAll) {
29 Builder &builder = parser.getBuilder();
30 if (parser.parseOptionalKeyword(kDimAllKeyword).succeeded()) {
31 rawDimList = builder.getDenseI64ArrayAttr({});
32 isInverted = nullptr;
33 isAll = builder.getUnitAttr();
34 return success();
35 }
36
37 isAll = nullptr;
38 isInverted = nullptr;
39 if (parser.parseOptionalKeyword(kDimExceptKeyword).succeeded()) {
40 isInverted = builder.getUnitAttr();
41 }
42
43 if (isInverted) {
44 if (parser.parseLParen().failed())
45 return failure();
46 }
47
49 ParseResult listResult = parser.parseCommaSeparatedList(
50 [&]() { return parser.parseInteger(values.emplace_back()); });
51 if (listResult.failed())
52 return failure();
53
54 rawDimList = builder.getDenseI64ArrayAttr(values);
55
56 if (isInverted) {
57 if (parser.parseRParen().failed())
58 return failure();
59 }
60 return success();
61}
62
64 DenseI64ArrayAttr rawDimList,
65 UnitAttr isInverted, UnitAttr isAll) {
66 if (isAll) {
67 printer << kDimAllKeyword;
68 return;
69 }
70 if (isInverted) {
71 printer << kDimExceptKeyword << "(";
72 }
73 printer << llvm::interleaved(rawDimList.asArrayRef());
74 if (isInverted) {
75 printer << ")";
76 }
77}
78
81 bool inverted, bool all) {
82 if (all) {
83 if (inverted) {
84 return op->emitOpError()
85 << "cannot request both 'all' and 'inverted' values in the list";
86 }
87 if (!raw.empty()) {
88 return op->emitOpError()
89 << "cannot both request 'all' and specific values in the list";
90 }
91 }
92 if (!all && raw.empty()) {
93 return op->emitOpError() << "must request specific values in the list if "
94 "'all' is not specified";
95 }
96 SmallVector<int64_t> rawVector = llvm::to_vector(raw);
97 auto *it = llvm::unique(rawVector);
98 if (it != rawVector.end())
99 return op->emitOpError() << "expected the listed values to be unique";
100
101 return success();
102}
103
105 Location loc, bool isAll, bool isInverted, ArrayRef<int64_t> rawList,
107 assert(maxNumber > 0 && "expected size to be positive");
108 assert(!(isAll && isInverted) && "cannot invert all");
109 if (isAll) {
110 result = llvm::to_vector(llvm::seq<int64_t>(0, maxNumber));
112 }
113
114 SmallVector<int64_t> expanded;
115 llvm::SmallDenseSet<int64_t> visited;
116 expanded.reserve(rawList.size());
117 SmallVectorImpl<int64_t> &target = isInverted ? expanded : result;
118 for (int64_t raw : rawList) {
119 int64_t updated = raw < 0 ? maxNumber + raw : raw;
120 if (updated >= maxNumber) {
121 return emitSilenceableFailure(loc)
122 << "position overflow " << updated << " (updated from " << raw
123 << ") for maximum " << maxNumber;
124 }
125 if (updated < 0) {
126 return emitSilenceableFailure(loc) << "position underflow " << updated
127 << " (updated from " << raw << ")";
128 }
129 if (!visited.insert(updated).second) {
130 return emitSilenceableFailure(loc) << "repeated position " << updated
131 << " (updated from " << raw << ")";
132 }
133 target.push_back(updated);
134 }
135
136 if (!isInverted)
138
139 result.reserve(result.size() + (maxNumber - expanded.size()));
140 for (int64_t candidate : llvm::seq<int64_t>(0, maxNumber)) {
141 if (llvm::is_contained(expanded, candidate))
142 continue;
143 result.push_back(candidate);
144 }
145
147}
148
149//===----------------------------------------------------------------------===//
150// Generated interface implementation.
151//===----------------------------------------------------------------------===//
152
153#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.cpp.inc"
return success()
constexpr static const llvm::StringLiteral kDimAllKeyword
Keyword syntax for full inclusion in positional specification.
constexpr static const llvm::StringLiteral kDimExceptKeyword
Keyword syntax for positional specification inversion.
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
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 ParseResult parseOptionalKeyword(StringRef keyword)=0
Parse the given keyword if present.
virtual ParseResult parseRParen()=0
Parse a ) token.
ParseResult parseInteger(IntT &result)
Parse an integer value from the stream.
virtual ParseResult parseLParen()=0
Parse a ( token.
This class is a general helper class for creating context-global objects like types,...
Definition Builders.h:51
UnitAttr getUnitAttr()
Definition Builders.cpp:98
DenseI64ArrayAttr getDenseI64ArrayAttr(ArrayRef< int64_t > values)
Definition Builders.cpp:167
The result of a transform IR operation application.
static DiagnosedSilenceableFailure success()
Constructs a DiagnosedSilenceableFailure in the success state.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
LogicalResult verifyTransformMatchDimsOp(Operation *op, ArrayRef< int64_t > raw, bool inverted, bool all)
Checks if the positional specification defined is valid and reports errors otherwise.
void printTransformMatchDims(OpAsmPrinter &printer, Operation *op, DenseI64ArrayAttr rawDimList, UnitAttr isInverted, UnitAttr isAll)
Prints a positional index specification for transform match operations.
DiagnosedSilenceableFailure expandTargetSpecification(Location loc, bool isAll, bool isInverted, ArrayRef< int64_t > rawList, int64_t maxNumber, SmallVectorImpl< int64_t > &result)
Populates result with the positional identifiers relative to maxNumber.
ParseResult parseTransformMatchDims(OpAsmParser &parser, DenseI64ArrayAttr &rawDimList, UnitAttr &isInverted, UnitAttr &isAll)
Parses a positional index specification for transform match operations.
Include the generated interface declarations.
detail::DenseArrayAttrImpl< int64_t > DenseI64ArrayAttr
DiagnosedSilenceableFailure emitSilenceableFailure(Location loc, const Twine &message={})
Emits a silenceable failure with the given message.