MLIR  21.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 
13 using namespace mlir;
14 
15 //===----------------------------------------------------------------------===//
16 // Printing and parsing for match ops.
17 //===----------------------------------------------------------------------===//
18 
19 /// Keyword syntax for positional specification inversion.
20 constexpr const static llvm::StringLiteral kDimExceptKeyword = "except";
21 
22 /// Keyword syntax for full inclusion in positional specification.
23 constexpr 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 
48  SmallVector<int64_t> values;
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,
106  int64_t maxNumber, SmallVectorImpl<int64_t> &result) {
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"
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 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 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:50
UnitAttr getUnitAttr()
Definition: Builders.cpp:94
DenseI64ArrayAttr getDenseI64ArrayAttr(ArrayRef< int64_t > values)
Definition: Builders.cpp:163
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.
Definition: Operation.cpp:673
Base class for DenseArrayAttr that is instantiated and specialized for each supported element type be...
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.
DiagnosedSilenceableFailure emitSilenceableFailure(Location loc, const Twine &message={})
Emits a silenceable failure with the given message.