MLIR  14.0.0git
TypeParser.cpp
Go to the documentation of this file.
1 //===- TypeParser.cpp - MLIR Type Parser Implementation -------------------===//
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 //
9 // This file implements the parser for the MLIR Types.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Parser.h"
14 #include "mlir/IR/AffineMap.h"
15 #include "mlir/IR/BuiltinTypes.h"
16 #include "mlir/IR/OpDefinition.h"
17 #include "mlir/IR/TensorEncoding.h"
18 
19 using namespace mlir;
20 using namespace mlir::detail;
21 
22 /// Optionally parse a type.
24  // There are many different starting tokens for a type, check them here.
25  switch (getToken().getKind()) {
26  case Token::l_paren:
27  case Token::kw_memref:
28  case Token::kw_tensor:
29  case Token::kw_complex:
30  case Token::kw_tuple:
31  case Token::kw_vector:
32  case Token::inttype:
33  case Token::kw_bf16:
34  case Token::kw_f16:
35  case Token::kw_f32:
36  case Token::kw_f64:
37  case Token::kw_index:
38  case Token::kw_none:
39  case Token::exclamation_identifier:
40  return failure(!(type = parseType()));
41 
42  default:
43  return llvm::None;
44  }
45 }
46 
47 /// Parse an arbitrary type.
48 ///
49 /// type ::= function-type
50 /// | non-function-type
51 ///
53  if (getToken().is(Token::l_paren))
54  return parseFunctionType();
55  return parseNonFunctionType();
56 }
57 
58 /// Parse a function result type.
59 ///
60 /// function-result-type ::= type-list-parens
61 /// | non-function-type
62 ///
64  if (getToken().is(Token::l_paren))
65  return parseTypeListParens(elements);
66 
68  if (!t)
69  return failure();
70  elements.push_back(t);
71  return success();
72 }
73 
74 /// Parse a list of types without an enclosing parenthesis. The list must have
75 /// at least one member.
76 ///
77 /// type-list-no-parens ::= type (`,` type)*
78 ///
80  auto parseElt = [&]() -> ParseResult {
81  auto elt = parseType();
82  elements.push_back(elt);
83  return elt ? success() : failure();
84  };
85 
86  return parseCommaSeparatedList(parseElt);
87 }
88 
89 /// Parse a parenthesized list of types.
90 ///
91 /// type-list-parens ::= `(` `)`
92 /// | `(` type-list-no-parens `)`
93 ///
95  if (parseToken(Token::l_paren, "expected '('"))
96  return failure();
97 
98  // Handle empty lists.
99  if (getToken().is(Token::r_paren))
100  return consumeToken(), success();
101 
102  if (parseTypeListNoParens(elements) ||
103  parseToken(Token::r_paren, "expected ')'"))
104  return failure();
105  return success();
106 }
107 
108 /// Parse a complex type.
109 ///
110 /// complex-type ::= `complex` `<` type `>`
111 ///
113  consumeToken(Token::kw_complex);
114 
115  // Parse the '<'.
116  if (parseToken(Token::less, "expected '<' in complex type"))
117  return nullptr;
118 
119  llvm::SMLoc elementTypeLoc = getToken().getLoc();
120  auto elementType = parseType();
121  if (!elementType ||
122  parseToken(Token::greater, "expected '>' in complex type"))
123  return nullptr;
124  if (!elementType.isa<FloatType>() && !elementType.isa<IntegerType>())
125  return emitError(elementTypeLoc, "invalid element type for complex"),
126  nullptr;
127 
128  return ComplexType::get(elementType);
129 }
130 
131 /// Parse a function type.
132 ///
133 /// function-type ::= type-list-parens `->` function-result-type
134 ///
136  assert(getToken().is(Token::l_paren));
137 
138  SmallVector<Type, 4> arguments, results;
139  if (parseTypeListParens(arguments) ||
140  parseToken(Token::arrow, "expected '->' in function type") ||
141  parseFunctionResultTypes(results))
142  return nullptr;
143 
144  return builder.getFunctionType(arguments, results);
145 }
146 
147 /// Parse the offset and strides from a strided layout specification.
148 ///
149 /// strided-layout ::= `offset:` dimension `,` `strides: ` stride-list
150 ///
152  SmallVectorImpl<int64_t> &strides) {
153  // Parse offset.
154  consumeToken(Token::kw_offset);
155  if (!consumeIf(Token::colon))
156  return emitError("expected colon after `offset` keyword");
157  auto maybeOffset = getToken().getUnsignedIntegerValue();
158  bool question = getToken().is(Token::question);
159  if (!maybeOffset && !question)
160  return emitError("invalid offset");
161  offset = maybeOffset ? static_cast<int64_t>(maybeOffset.getValue())
162  : MemRefType::getDynamicStrideOrOffset();
163  consumeToken();
164 
165  if (!consumeIf(Token::comma))
166  return emitError("expected comma after offset value");
167 
168  // Parse stride list.
169  if (parseToken(Token::kw_strides,
170  "expected `strides` keyword after offset specification") ||
171 
172  parseToken(Token::colon, "expected colon after `strides` keyword") ||
173  parseStrideList(strides))
174  return failure();
175  return success();
176 }
177 
178 /// Parse a memref type.
179 ///
180 /// memref-type ::= ranked-memref-type | unranked-memref-type
181 ///
182 /// ranked-memref-type ::= `memref` `<` dimension-list-ranked type
183 /// (`,` layout-specification)? (`,` memory-space)? `>`
184 ///
185 /// unranked-memref-type ::= `memref` `<*x` type (`,` memory-space)? `>`
186 ///
187 /// stride-list ::= `[` (dimension (`,` dimension)*)? `]`
188 /// strided-layout ::= `offset:` dimension `,` `strides: ` stride-list
189 /// layout-specification ::= semi-affine-map | strided-layout | attribute
190 /// memory-space ::= integer-literal | attribute
191 ///
193  llvm::SMLoc loc = getToken().getLoc();
194  consumeToken(Token::kw_memref);
195 
196  if (parseToken(Token::less, "expected '<' in memref type"))
197  return nullptr;
198 
199  bool isUnranked;
200  SmallVector<int64_t, 4> dimensions;
201 
202  if (consumeIf(Token::star)) {
203  // This is an unranked memref type.
204  isUnranked = true;
205  if (parseXInDimensionList())
206  return nullptr;
207 
208  } else {
209  isUnranked = false;
210  if (parseDimensionListRanked(dimensions))
211  return nullptr;
212  }
213 
214  // Parse the element type.
215  auto typeLoc = getToken().getLoc();
216  auto elementType = parseType();
217  if (!elementType)
218  return nullptr;
219 
220  // Check that memref is formed from allowed types.
221  if (!BaseMemRefType::isValidElementType(elementType))
222  return emitError(typeLoc, "invalid memref element type"), nullptr;
223 
224  MemRefLayoutAttrInterface layout;
225  Attribute memorySpace;
226 
227  auto parseElt = [&]() -> ParseResult {
228  // Check for AffineMap as offset/strides.
229  if (getToken().is(Token::kw_offset)) {
230  int64_t offset;
231  SmallVector<int64_t, 4> strides;
232  if (failed(parseStridedLayout(offset, strides)))
233  return failure();
234  // Construct strided affine map.
235  AffineMap map =
236  makeStridedLinearLayoutMap(strides, offset, state.context);
237  layout = AffineMapAttr::get(map);
238  } else {
239  // Either it is MemRefLayoutAttrInterface or memory space attribute.
240  Attribute attr = parseAttribute();
241  if (!attr)
242  return failure();
243 
244  if (attr.isa<MemRefLayoutAttrInterface>()) {
245  layout = attr.cast<MemRefLayoutAttrInterface>();
246  } else if (memorySpace) {
247  return emitError("multiple memory spaces specified in memref type");
248  } else {
249  memorySpace = attr;
250  return success();
251  }
252  }
253 
254  if (isUnranked)
255  return emitError("cannot have affine map for unranked memref type");
256  if (memorySpace)
257  return emitError("expected memory space to be last in memref type");
258 
259  return success();
260  };
261 
262  // Parse a list of mappings and address space if present.
263  if (!consumeIf(Token::greater)) {
264  // Parse comma separated list of affine maps, followed by memory space.
265  if (parseToken(Token::comma, "expected ',' or '>' in memref type") ||
266  parseCommaSeparatedListUntil(Token::greater, parseElt,
267  /*allowEmptyList=*/false)) {
268  return nullptr;
269  }
270  }
271 
272  if (isUnranked)
273  return getChecked<UnrankedMemRefType>(loc, elementType, memorySpace);
274 
275  return getChecked<MemRefType>(loc, dimensions, elementType, layout,
276  memorySpace);
277 }
278 
279 /// Parse any type except the function type.
280 ///
281 /// non-function-type ::= integer-type
282 /// | index-type
283 /// | float-type
284 /// | extended-type
285 /// | vector-type
286 /// | tensor-type
287 /// | memref-type
288 /// | complex-type
289 /// | tuple-type
290 /// | none-type
291 ///
292 /// index-type ::= `index`
293 /// float-type ::= `f16` | `bf16` | `f32` | `f64` | `f80` | `f128`
294 /// none-type ::= `none`
295 ///
297  switch (getToken().getKind()) {
298  default:
299  return (emitError("expected non-function type"), nullptr);
300  case Token::kw_memref:
301  return parseMemRefType();
302  case Token::kw_tensor:
303  return parseTensorType();
304  case Token::kw_complex:
305  return parseComplexType();
306  case Token::kw_tuple:
307  return parseTupleType();
308  case Token::kw_vector:
309  return parseVectorType();
310  // integer-type
311  case Token::inttype: {
312  auto width = getToken().getIntTypeBitwidth();
313  if (!width.hasValue())
314  return (emitError("invalid integer width"), nullptr);
315  if (width.getValue() > IntegerType::kMaxWidth) {
316  emitError(getToken().getLoc(), "integer bitwidth is limited to ")
317  << IntegerType::kMaxWidth << " bits";
318  return nullptr;
319  }
320 
321  IntegerType::SignednessSemantics signSemantics = IntegerType::Signless;
322  if (Optional<bool> signedness = getToken().getIntTypeSignedness())
323  signSemantics = *signedness ? IntegerType::Signed : IntegerType::Unsigned;
324 
325  consumeToken(Token::inttype);
326  return IntegerType::get(getContext(), width.getValue(), signSemantics);
327  }
328 
329  // float-type
330  case Token::kw_bf16:
331  consumeToken(Token::kw_bf16);
332  return builder.getBF16Type();
333  case Token::kw_f16:
334  consumeToken(Token::kw_f16);
335  return builder.getF16Type();
336  case Token::kw_f32:
337  consumeToken(Token::kw_f32);
338  return builder.getF32Type();
339  case Token::kw_f64:
340  consumeToken(Token::kw_f64);
341  return builder.getF64Type();
342  case Token::kw_f80:
343  consumeToken(Token::kw_f80);
344  return builder.getF80Type();
345  case Token::kw_f128:
346  consumeToken(Token::kw_f128);
347  return builder.getF128Type();
348 
349  // index-type
350  case Token::kw_index:
351  consumeToken(Token::kw_index);
352  return builder.getIndexType();
353 
354  // none-type
355  case Token::kw_none:
356  consumeToken(Token::kw_none);
357  return builder.getNoneType();
358 
359  // extended type
360  case Token::exclamation_identifier:
361  return parseExtendedType();
362  }
363 }
364 
365 /// Parse a tensor type.
366 ///
367 /// tensor-type ::= `tensor` `<` dimension-list type `>`
368 /// dimension-list ::= dimension-list-ranked | `*x`
369 ///
371  consumeToken(Token::kw_tensor);
372 
373  if (parseToken(Token::less, "expected '<' in tensor type"))
374  return nullptr;
375 
376  bool isUnranked;
377  SmallVector<int64_t, 4> dimensions;
378 
379  if (consumeIf(Token::star)) {
380  // This is an unranked tensor type.
381  isUnranked = true;
382 
383  if (parseXInDimensionList())
384  return nullptr;
385 
386  } else {
387  isUnranked = false;
388  if (parseDimensionListRanked(dimensions))
389  return nullptr;
390  }
391 
392  // Parse the element type.
393  auto elementTypeLoc = getToken().getLoc();
394  auto elementType = parseType();
395 
396  // Parse an optional encoding attribute.
397  Attribute encoding;
398  if (consumeIf(Token::comma)) {
399  encoding = parseAttribute();
400  if (auto v = encoding.dyn_cast_or_null<VerifiableTensorEncoding>()) {
401  if (failed(v.verifyEncoding(dimensions, elementType,
402  [&] { return emitError(); })))
403  return nullptr;
404  }
405  }
406 
407  if (!elementType || parseToken(Token::greater, "expected '>' in tensor type"))
408  return nullptr;
409  if (!TensorType::isValidElementType(elementType))
410  return emitError(elementTypeLoc, "invalid tensor element type"), nullptr;
411 
412  if (isUnranked) {
413  if (encoding)
414  return emitError("cannot apply encoding to unranked tensor"), nullptr;
415  return UnrankedTensorType::get(elementType);
416  }
417  return RankedTensorType::get(dimensions, elementType, encoding);
418 }
419 
420 /// Parse a tuple type.
421 ///
422 /// tuple-type ::= `tuple` `<` (type (`,` type)*)? `>`
423 ///
425  consumeToken(Token::kw_tuple);
426 
427  // Parse the '<'.
428  if (parseToken(Token::less, "expected '<' in tuple type"))
429  return nullptr;
430 
431  // Check for an empty tuple by directly parsing '>'.
432  if (consumeIf(Token::greater))
433  return TupleType::get(getContext());
434 
435  // Parse the element types and the '>'.
436  SmallVector<Type, 4> types;
437  if (parseTypeListNoParens(types) ||
438  parseToken(Token::greater, "expected '>' in tuple type"))
439  return nullptr;
440 
441  return TupleType::get(getContext(), types);
442 }
443 
444 /// Parse a vector type.
445 ///
446 /// vector-type ::= `vector` `<` vector-dim-list vector-element-type `>`
447 /// vector-dim-list := (static-dim-list `x`)? (`[` static-dim-list `]` `x`)?
448 /// static-dim-list ::= decimal-literal (`x` decimal-literal)*
449 ///
451  consumeToken(Token::kw_vector);
452 
453  if (parseToken(Token::less, "expected '<' in vector type"))
454  return nullptr;
455 
456  SmallVector<int64_t, 4> dimensions;
457  unsigned numScalableDims;
458  if (parseVectorDimensionList(dimensions, numScalableDims))
459  return nullptr;
460  if (any_of(dimensions, [](int64_t i) { return i <= 0; }))
461  return emitError(getToken().getLoc(),
462  "vector types must have positive constant sizes"),
463  nullptr;
464 
465  // Parse the element type.
466  auto typeLoc = getToken().getLoc();
467  auto elementType = parseType();
468  if (!elementType || parseToken(Token::greater, "expected '>' in vector type"))
469  return nullptr;
470 
471  if (!VectorType::isValidElementType(elementType))
472  return emitError(typeLoc, "vector elements must be int/index/float type"),
473  nullptr;
474 
475  return VectorType::get(dimensions, elementType, numScalableDims);
476 }
477 
478 /// Parse a dimension list in a vector type. This populates the dimension list,
479 /// and returns the number of scalable dimensions in `numScalableDims`.
480 ///
481 /// vector-dim-list := (static-dim-list `x`)? (`[` static-dim-list `]` `x`)?
482 /// static-dim-list ::= decimal-literal (`x` decimal-literal)*
483 ///
486  unsigned &numScalableDims) {
487  numScalableDims = 0;
488  // If there is a set of fixed-length dimensions, consume it
489  while (getToken().is(Token::integer)) {
490  int64_t value;
491  if (parseIntegerInDimensionList(value))
492  return failure();
493  dimensions.push_back(value);
494  // Make sure we have an 'x' or something like 'xbf32'.
495  if (parseXInDimensionList())
496  return failure();
497  }
498  // If there is a set of scalable dimensions, consume it
499  if (consumeIf(Token::l_square)) {
500  while (getToken().is(Token::integer)) {
501  int64_t value;
502  if (parseIntegerInDimensionList(value))
503  return failure();
504  dimensions.push_back(value);
505  numScalableDims++;
506  // Check if we have reached the end of the scalable dimension list
507  if (consumeIf(Token::r_square)) {
508  // Make sure we have something like 'xbf32'.
509  if (parseXInDimensionList())
510  return failure();
511  return success();
512  }
513  // Make sure we have an 'x'
514  if (parseXInDimensionList())
515  return failure();
516  }
517  // If we make it here, we've finished parsing the dimension list
518  // without finding ']' closing the set of scalable dimensions
519  return emitError("missing ']' closing set of scalable dimensions");
520  }
521 
522  return success();
523 }
524 
525 /// Parse a dimension list of a tensor or memref type. This populates the
526 /// dimension list, using -1 for the `?` dimensions if `allowDynamic` is set and
527 /// errors out on `?` otherwise.
528 ///
529 /// dimension-list-ranked ::= (dimension `x`)*
530 /// dimension ::= `?` | decimal-literal
531 ///
532 /// When `allowDynamic` is not set, this is used to parse:
533 ///
534 /// static-dimension-list ::= (decimal-literal `x`)*
537  bool allowDynamic) {
538  while (getToken().isAny(Token::integer, Token::question)) {
539  if (consumeIf(Token::question)) {
540  if (!allowDynamic)
541  return emitError("expected static shape");
542  dimensions.push_back(-1);
543  } else {
544  int64_t value;
545  if (parseIntegerInDimensionList(value))
546  return failure();
547  dimensions.push_back(value);
548  }
549  // Make sure we have an 'x' or something like 'xbf32'.
550  if (parseXInDimensionList())
551  return failure();
552  }
553 
554  return success();
555 }
556 
558  // Hexadecimal integer literals (starting with `0x`) are not allowed in
559  // aggregate type declarations. Therefore, `0xf32` should be processed as
560  // a sequence of separate elements `0`, `x`, `f32`.
561  if (getTokenSpelling().size() > 1 && getTokenSpelling()[1] == 'x') {
562  // We can get here only if the token is an integer literal. Hexadecimal
563  // integer literals can only start with `0x` (`1x` wouldn't lex as a
564  // literal, just `1` would, at which point we don't get into this
565  // branch).
566  assert(getTokenSpelling()[0] == '0' && "invalid integer literal");
567  value = 0;
568  state.lex.resetPointer(getTokenSpelling().data() + 1);
569  consumeToken();
570  } else {
571  // Make sure this integer value is in bound and valid.
573  if (!dimension || *dimension > std::numeric_limits<int64_t>::max())
574  return emitError("invalid dimension");
575  value = (int64_t)dimension.getValue();
576  consumeToken(Token::integer);
577  }
578  return success();
579 }
580 
581 /// Parse an 'x' token in a dimension list, handling the case where the x is
582 /// juxtaposed with an element type, as in "xf32", leaving the "f32" as the next
583 /// token.
585  if (getToken().isNot(Token::bare_identifier) || getTokenSpelling()[0] != 'x')
586  return emitError("expected 'x' in dimension list");
587 
588  // If we had a prefix of 'x', lex the next token immediately after the 'x'.
589  if (getTokenSpelling().size() != 1)
590  state.lex.resetPointer(getTokenSpelling().data() + 1);
591 
592  // Consume the 'x'.
593  consumeToken(Token::bare_identifier);
594 
595  return success();
596 }
597 
598 // Parse a comma-separated list of dimensions, possibly empty:
599 // stride-list ::= `[` (dimension (`,` dimension)*)? `]`
603  [&]() -> ParseResult {
604  if (consumeIf(Token::question)) {
605  dimensions.push_back(MemRefType::getDynamicStrideOrOffset());
606  } else {
607  // This must be an integer value.
608  int64_t val;
609  if (getToken().getSpelling().getAsInteger(10, val))
610  return emitError("invalid integer value: ")
611  << getToken().getSpelling();
612  // Make sure it is not the one value for `?`.
613  if (ShapedType::isDynamic(val))
614  return emitError("invalid integer value: ")
615  << getToken().getSpelling()
616  << ", use `?` to specify a dynamic dimension";
617 
618  if (val == 0)
619  return emitError("invalid memref stride");
620 
621  dimensions.push_back(val);
622  consumeToken(Token::integer);
623  }
624  return success();
625  },
626  " in stride list");
627 }
Include the generated interface declarations.
U cast() const
Definition: Attributes.h:123
MLIRContext * getContext() const
Definition: Parser.h:35
ParseResult parseTypeListNoParens(SmallVectorImpl< Type > &elements)
Parse a list of types without an enclosing parenthesis.
Definition: TypeParser.cpp:79
U dyn_cast_or_null() const
Definition: Attributes.h:120
Type parseMemRefType()
Parse a memref type.
Definition: TypeParser.cpp:192
bool isa() const
Definition: Attributes.h:107
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Definition: LogicalResult.h:72
FloatType getF16Type()
Definition: Builders.cpp:38
Builder builder
Definition: Parser.h:29
bool consumeIf(Token::Kind kind)
If the current token has the specified kind, consume it and return true.
Definition: Parser.h:117
NoneType getNoneType()
Definition: Builders.cpp:75
ParseResult parseTypeListParens(SmallVectorImpl< Type > &elements)
Parse a parenthesized list of types.
Definition: TypeParser.cpp:94
FloatType getF32Type()
Definition: Builders.cpp:40
ParseResult parseStrideList(SmallVectorImpl< int64_t > &dimensions)
Definition: TypeParser.cpp:600
OptionalParseResult parseOptionalType(Type &type)
Optionally parse a type.
Definition: TypeParser.cpp:23
Type parseNonFunctionType()
Parse a non function type.
Definition: TypeParser.cpp:296
ParserState & state
The Parser is subclassed and reinstantiated.
Definition: Parser.h:305
Type parseTupleType()
Parse a tuple type.
Definition: TypeParser.cpp:424
static constexpr const bool value
Type parseFunctionType()
Parse a function type.
Definition: TypeParser.cpp:135
Attribute parseAttribute(Type type={})
Parse an arbitrary attribute with an optional type.
bool is(Kind k) const
Definition: Token.h:37
StringRef getTokenSpelling() const
Definition: Parser.h:113
ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())
Parse a list of comma-separated items with an optional delimiter.
Definition: Parser.cpp:43
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
VectorType parseVectorType()
Parse a vector type.
Definition: TypeParser.cpp:450
Optional< unsigned > getIntTypeBitwidth() const
For an inttype token, return its bitwidth.
Definition: Token.cpp:59
Type parseExtendedType()
Parse an extended type.
Attributes are known-constant values of operations.
Definition: Attributes.h:24
static Optional< uint64_t > getUInt64IntegerValue(StringRef spelling)
For an integer token, return its value as an uint64_t.
Definition: Token.cpp:40
FloatType getF128Type()
Definition: Builders.cpp:46
const Token & getToken() const
Return the current token the parser is inspecting.
Definition: Parser.h:112
ParseResult parseFunctionResultTypes(SmallVectorImpl< Type > &elements)
Parse a function result type.
Definition: TypeParser.cpp:63
ParseResult parseDimensionListRanked(SmallVectorImpl< int64_t > &dimensions, bool allowDynamic=true)
Parse a dimension list of a tensor or memref type.
Definition: TypeParser.cpp:536
A multi-dimensional affine map Affine map&#39;s are immutable like Type&#39;s, and they are uniqued...
Definition: AffineMap.h:38
Type parseTensorType()
Parse a tensor type.
Definition: TypeParser.cpp:370
FloatType getBF16Type()
Definition: Builders.cpp:36
void resetPointer(const char *newPointer)
Change the position of the lexer cursor.
Definition: Lexer.h:37
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
Optional< unsigned > getUnsignedIntegerValue() const
For an integer token, return its value as an unsigned.
Definition: Token.cpp:29
ParseResult parseIntegerInDimensionList(int64_t &value)
Definition: TypeParser.cpp:557
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:52
Type parseType()
Parse an arbitrary type.
Definition: TypeParser.cpp:52
StringRef getSpelling() const
Definition: Token.h:33
IndexType getIndexType()
Definition: Builders.cpp:48
void consumeToken()
Advance the current lexer onto the next token.
Definition: Parser.h:125
static bool isValidElementType(Type type)
Return true if the specified element type is ok in a memref.
Definition: BuiltinTypes.h:359
MLIRContext *const context
The context we&#39;re parsing into.
Definition: ParserState.h:68
ParseResult parseCommaSeparatedListUntil(Token::Kind rightToken, function_ref< ParseResult()> parseElement, bool allowEmptyList=true)
Parse a comma-separated list of elements up until the specified end token.
Definition: Parser.cpp:132
Lexer lex
The lexer for the source file we&#39;re parsing.
Definition: ParserState.h:71
FloatType getF64Type()
Definition: Builders.cpp:42
FloatType getF80Type()
Definition: Builders.cpp:44
ParseResult parseXInDimensionList()
Parse an &#39;x&#39; token in a dimension list, handling the case where the x is juxtaposed with an element t...
Definition: TypeParser.cpp:584
AffineMap makeStridedLinearLayoutMap(ArrayRef< int64_t > strides, int64_t offset, MLIRContext *context)
Given a list of strides (in which MemRefType::getDynamicStrideOrOffset() represents a dynamic value)...
ParseResult parseStridedLayout(int64_t &offset, SmallVectorImpl< int64_t > &strides)
Parse strided layout specification.
Definition: TypeParser.cpp:151
InFlightDiagnostic emitError(const Twine &message={})
Emit an error and return failure.
Definition: Parser.h:71
static bool isValidElementType(Type type)
Return true if the specified element type is ok in a tensor.
FunctionType getFunctionType(TypeRange inputs, TypeRange results)
Definition: Builders.cpp:67
llvm::SMLoc getLoc() const
Definition: Token.cpp:19
bool isa() const
Definition: Types.h:234
This class represents success/failure for operation parsing.
Definition: OpDefinition.h:36
ParseResult parseToken(Token::Kind expectedToken, const Twine &message)
Consume the specified token if present and return success.
Definition: Parser.cpp:163
Type parseComplexType()
Parse a complex type.
Definition: TypeParser.cpp:112
ParseResult parseVectorDimensionList(SmallVectorImpl< int64_t > &dimensions, unsigned &numScalableDims)
Parse a dimension list in a vector type.
Definition: TypeParser.cpp:485
Square brackets surrounding zero or more operands.
static Value max(ImplicitLocOpBuilder &builder, Value a, Value b)