MLIR  18.0.0git
LLVMTypes.cpp
Go to the documentation of this file.
1 //===- LLVMTypes.cpp - MLIR LLVM dialect types ------------------*- C++ -*-===//
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 types for the LLVM dialect in MLIR. These MLIR types
10 // correspond to the LLVM IR type system.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "TypeDetail.h"
15 
18 #include "mlir/IR/BuiltinTypes.h"
20 #include "mlir/IR/TypeSupport.h"
21 
22 #include "llvm/ADT/ScopeExit.h"
23 #include "llvm/ADT/TypeSwitch.h"
24 #include "llvm/Support/TypeSize.h"
25 #include <optional>
26 
27 using namespace mlir;
28 using namespace mlir::LLVM;
29 
30 constexpr const static unsigned kBitsInByte = 8;
31 
32 //===----------------------------------------------------------------------===//
33 // custom<FunctionTypes>
34 //===----------------------------------------------------------------------===//
35 
37  bool &isVarArg) {
38  isVarArg = false;
39  // `(` `)`
41  return success();
42 
43  // `(` `...` `)`
45  isVarArg = true;
46  return p.parseRParen();
47  }
48 
49  // type (`,` type)* (`,` `...`)?
50  Type type;
51  if (parsePrettyLLVMType(p, type))
52  return failure();
53  params.push_back(type);
54  while (succeeded(p.parseOptionalComma())) {
56  isVarArg = true;
57  return p.parseRParen();
58  }
59  if (parsePrettyLLVMType(p, type))
60  return failure();
61  params.push_back(type);
62  }
63  return p.parseRParen();
64 }
65 
67  bool isVarArg) {
68  llvm::interleaveComma(params, p,
69  [&](Type type) { printPrettyLLVMType(p, type); });
70  if (isVarArg) {
71  if (!params.empty())
72  p << ", ";
73  p << "...";
74  }
75  p << ')';
76 }
77 
78 //===----------------------------------------------------------------------===//
79 // custom<Pointer>
80 //===----------------------------------------------------------------------===//
81 
82 static ParseResult parsePointer(AsmParser &p, Type &elementType,
83  unsigned &addressSpace) {
84  // `<` addressSpace `>`
85  OptionalParseResult result = p.parseOptionalInteger(addressSpace);
86  if (result.has_value()) {
87  if (failed(result.value()))
88  return failure();
89  elementType = Type();
90  return success();
91  }
92 
93  if (parsePrettyLLVMType(p, elementType))
94  return failure();
96  return p.parseInteger(addressSpace);
97 
98  return success();
99 }
100 
101 static void printPointer(AsmPrinter &p, Type elementType,
102  unsigned addressSpace) {
103  if (elementType)
104  printPrettyLLVMType(p, elementType);
105  if (addressSpace != 0) {
106  if (elementType)
107  p << ", ";
108  p << addressSpace;
109  }
110 }
111 
112 //===----------------------------------------------------------------------===//
113 // custom<ExtTypeParams>
114 //===----------------------------------------------------------------------===//
115 
116 /// Parses the parameter list for a target extension type. The parameter list
117 /// contains an optional list of type parameters, followed by an optional list
118 /// of integer parameters. Type and integer parameters cannot be interleaved in
119 /// the list.
120 /// extTypeParams ::= typeList? | intList? | (typeList "," intList)
121 /// typeList ::= type ("," type)*
122 /// intList ::= integer ("," integer)*
123 static ParseResult
125  SmallVectorImpl<unsigned int> &intParams) {
126  bool parseType = true;
127  auto typeOrIntParser = [&]() -> ParseResult {
128  unsigned int i;
129  auto intResult = p.parseOptionalInteger(i);
130  if (intResult.has_value() && !failed(*intResult)) {
131  // Successfully parsed an integer.
132  intParams.push_back(i);
133  // After the first integer was successfully parsed, no
134  // more types can be parsed.
135  parseType = false;
136  return success();
137  }
138  if (parseType) {
139  Type t;
140  if (!parsePrettyLLVMType(p, t)) {
141  // Successfully parsed a type.
142  typeParams.push_back(t);
143  return success();
144  }
145  }
146  return failure();
147  };
148  if (p.parseCommaSeparatedList(typeOrIntParser)) {
150  "failed to parse parameter list for target extension type");
151  return failure();
152  }
153  return success();
154 }
155 
156 static void printExtTypeParams(AsmPrinter &p, ArrayRef<Type> typeParams,
157  ArrayRef<unsigned int> intParams) {
158  p << typeParams;
159  if (!typeParams.empty() && !intParams.empty())
160  p << ", ";
161 
162  p << intParams;
163 }
164 
165 //===----------------------------------------------------------------------===//
166 // ODS-Generated Definitions
167 //===----------------------------------------------------------------------===//
168 
169 /// These are unused for now.
170 /// TODO: Move over to these once more types have been migrated to TypeDef.
171 LLVM_ATTRIBUTE_UNUSED static OptionalParseResult
172 generatedTypeParser(AsmParser &parser, StringRef *mnemonic, Type &value);
173 LLVM_ATTRIBUTE_UNUSED static LogicalResult
175 
176 #include "mlir/Dialect/LLVMIR/LLVMTypeInterfaces.cpp.inc"
177 
178 #define GET_TYPEDEF_CLASSES
179 #include "mlir/Dialect/LLVMIR/LLVMTypes.cpp.inc"
180 
181 //===----------------------------------------------------------------------===//
182 // LLVMArrayType
183 //===----------------------------------------------------------------------===//
184 
185 bool LLVMArrayType::isValidElementType(Type type) {
186  return !llvm::isa<LLVMVoidType, LLVMLabelType, LLVMMetadataType,
187  LLVMFunctionType, LLVMTokenType, LLVMScalableVectorType>(
188  type);
189 }
190 
191 LLVMArrayType LLVMArrayType::get(Type elementType, unsigned numElements) {
192  assert(elementType && "expected non-null subtype");
193  return Base::get(elementType.getContext(), elementType, numElements);
194 }
195 
196 LLVMArrayType
197 LLVMArrayType::getChecked(function_ref<InFlightDiagnostic()> emitError,
198  Type elementType, unsigned numElements) {
199  assert(elementType && "expected non-null subtype");
200  return Base::getChecked(emitError, elementType.getContext(), elementType,
201  numElements);
202 }
203 
206  Type elementType, unsigned numElements) {
207  if (!isValidElementType(elementType))
208  return emitError() << "invalid array element type: " << elementType;
209  return success();
210 }
211 
212 //===----------------------------------------------------------------------===//
213 // DataLayoutTypeInterface
214 
215 unsigned LLVMArrayType::getTypeSizeInBits(const DataLayout &dataLayout,
216  DataLayoutEntryListRef params) const {
217  return kBitsInByte * getTypeSize(dataLayout, params);
218 }
219 
220 unsigned LLVMArrayType::getTypeSize(const DataLayout &dataLayout,
221  DataLayoutEntryListRef params) const {
222  return llvm::alignTo(dataLayout.getTypeSize(getElementType()),
223  dataLayout.getTypeABIAlignment(getElementType())) *
224  getNumElements();
225 }
226 
227 unsigned LLVMArrayType::getABIAlignment(const DataLayout &dataLayout,
228  DataLayoutEntryListRef params) const {
229  return dataLayout.getTypeABIAlignment(getElementType());
230 }
231 
232 unsigned
233 LLVMArrayType::getPreferredAlignment(const DataLayout &dataLayout,
234  DataLayoutEntryListRef params) const {
235  return dataLayout.getTypePreferredAlignment(getElementType());
236 }
237 
238 //===----------------------------------------------------------------------===//
239 // Function type.
240 //===----------------------------------------------------------------------===//
241 
242 bool LLVMFunctionType::isValidArgumentType(Type type) {
243  return !llvm::isa<LLVMVoidType, LLVMFunctionType>(type);
244 }
245 
246 bool LLVMFunctionType::isValidResultType(Type type) {
247  return !llvm::isa<LLVMFunctionType, LLVMMetadataType, LLVMLabelType>(type);
248 }
249 
250 LLVMFunctionType LLVMFunctionType::get(Type result, ArrayRef<Type> arguments,
251  bool isVarArg) {
252  assert(result && "expected non-null result");
253  return Base::get(result.getContext(), result, arguments, isVarArg);
254 }
255 
256 LLVMFunctionType
257 LLVMFunctionType::getChecked(function_ref<InFlightDiagnostic()> emitError,
258  Type result, ArrayRef<Type> arguments,
259  bool isVarArg) {
260  assert(result && "expected non-null result");
261  return Base::getChecked(emitError, result.getContext(), result, arguments,
262  isVarArg);
263 }
264 
265 LLVMFunctionType LLVMFunctionType::clone(TypeRange inputs,
266  TypeRange results) const {
267  assert(results.size() == 1 && "expected a single result type");
268  return get(results[0], llvm::to_vector(inputs), isVarArg());
269 }
270 
271 ArrayRef<Type> LLVMFunctionType::getReturnTypes() const {
272  return static_cast<detail::LLVMFunctionTypeStorage *>(getImpl())->returnType;
273 }
274 
277  Type result, ArrayRef<Type> arguments, bool) {
278  if (!isValidResultType(result))
279  return emitError() << "invalid function result type: " << result;
280 
281  for (Type arg : arguments)
282  if (!isValidArgumentType(arg))
283  return emitError() << "invalid function argument type: " << arg;
284 
285  return success();
286 }
287 
288 //===----------------------------------------------------------------------===//
289 // LLVMPointerType
290 //===----------------------------------------------------------------------===//
291 
292 bool LLVMPointerType::isValidElementType(Type type) {
293  if (!type)
294  return true;
295  return isCompatibleOuterType(type)
296  ? !llvm::isa<LLVMVoidType, LLVMTokenType, LLVMMetadataType,
297  LLVMLabelType>(type)
298  : llvm::isa<PointerElementTypeInterface>(type);
299 }
300 
301 LLVMPointerType LLVMPointerType::get(Type pointee, unsigned addressSpace) {
302  assert(pointee && "expected non-null subtype, pass the context instead if "
303  "the opaque pointer type is desired");
304  return Base::get(pointee.getContext(), pointee, addressSpace);
305 }
306 
309  Type pointee, unsigned) {
310  if (!isValidElementType(pointee))
311  return emitError() << "invalid pointer element type: " << pointee;
312  return success();
313 }
314 
315 //===----------------------------------------------------------------------===//
316 // DataLayoutTypeInterface
317 
318 constexpr const static unsigned kDefaultPointerSizeBits = 64;
319 constexpr const static unsigned kDefaultPointerAlignment = 8;
320 
321 std::optional<unsigned> mlir::LLVM::extractPointerSpecValue(Attribute attr,
322  PtrDLEntryPos pos) {
323  auto spec = llvm::cast<DenseIntElementsAttr>(attr);
324  auto idx = static_cast<unsigned>(pos);
325  if (idx >= spec.size())
326  return std::nullopt;
327  return spec.getValues<unsigned>()[idx];
328 }
329 
330 /// Returns the part of the data layout entry that corresponds to `pos` for the
331 /// given `type` by interpreting the list of entries `params`. For the pointer
332 /// type in the default address space, returns the default value if the entries
333 /// do not provide a custom one, for other address spaces returns std::nullopt.
334 static std::optional<unsigned>
336  PtrDLEntryPos pos) {
337  // First, look for the entry for the pointer in the current address space.
338  Attribute currentEntry;
339  for (DataLayoutEntryInterface entry : params) {
340  if (!entry.isTypeEntry())
341  continue;
342  if (llvm::cast<LLVMPointerType>(entry.getKey().get<Type>())
343  .getAddressSpace() == type.getAddressSpace()) {
344  currentEntry = entry.getValue();
345  break;
346  }
347  }
348  if (currentEntry) {
349  return *extractPointerSpecValue(currentEntry, pos) /
350  (pos == PtrDLEntryPos::Size ? 1 : kBitsInByte);
351  }
352 
353  // If not found, and this is the pointer to the default memory space, assume
354  // 64-bit pointers.
355  if (type.getAddressSpace() == 0) {
358  }
359 
360  return std::nullopt;
361 }
362 
363 unsigned
364 LLVMPointerType::getTypeSizeInBits(const DataLayout &dataLayout,
365  DataLayoutEntryListRef params) const {
366  if (std::optional<unsigned> size =
368  return *size;
369 
370  // For other memory spaces, use the size of the pointer to the default memory
371  // space.
372  if (isOpaque())
373  return dataLayout.getTypeSizeInBits(get(getContext()));
374  return dataLayout.getTypeSizeInBits(get(getElementType()));
375 }
376 
377 unsigned LLVMPointerType::getABIAlignment(const DataLayout &dataLayout,
378  DataLayoutEntryListRef params) const {
379  if (std::optional<unsigned> alignment =
381  return *alignment;
382 
383  if (isOpaque())
384  return dataLayout.getTypeABIAlignment(get(getContext()));
385  return dataLayout.getTypeABIAlignment(get(getElementType()));
386 }
387 
388 unsigned
389 LLVMPointerType::getPreferredAlignment(const DataLayout &dataLayout,
390  DataLayoutEntryListRef params) const {
391  if (std::optional<unsigned> alignment =
393  return *alignment;
394 
395  if (isOpaque())
396  return dataLayout.getTypePreferredAlignment(get(getContext()));
397  return dataLayout.getTypePreferredAlignment(get(getElementType()));
398 }
399 
400 bool LLVMPointerType::areCompatible(DataLayoutEntryListRef oldLayout,
401  DataLayoutEntryListRef newLayout) const {
402  for (DataLayoutEntryInterface newEntry : newLayout) {
403  if (!newEntry.isTypeEntry())
404  continue;
405  unsigned size = kDefaultPointerSizeBits;
406  unsigned abi = kDefaultPointerAlignment;
407  auto newType = llvm::cast<LLVMPointerType>(newEntry.getKey().get<Type>());
408  const auto *it =
409  llvm::find_if(oldLayout, [&](DataLayoutEntryInterface entry) {
410  if (auto type = llvm::dyn_cast_if_present<Type>(entry.getKey())) {
411  return llvm::cast<LLVMPointerType>(type).getAddressSpace() ==
412  newType.getAddressSpace();
413  }
414  return false;
415  });
416  if (it == oldLayout.end()) {
417  llvm::find_if(oldLayout, [&](DataLayoutEntryInterface entry) {
418  if (auto type = llvm::dyn_cast_if_present<Type>(entry.getKey())) {
419  return llvm::cast<LLVMPointerType>(type).getAddressSpace() == 0;
420  }
421  return false;
422  });
423  }
424  if (it != oldLayout.end()) {
427  }
428 
429  Attribute newSpec = llvm::cast<DenseIntElementsAttr>(newEntry.getValue());
430  unsigned newSize = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Size);
431  unsigned newAbi = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Abi);
432  if (size != newSize || abi < newAbi || abi % newAbi != 0)
433  return false;
434  }
435  return true;
436 }
437 
438 LogicalResult LLVMPointerType::verifyEntries(DataLayoutEntryListRef entries,
439  Location loc) const {
440  for (DataLayoutEntryInterface entry : entries) {
441  if (!entry.isTypeEntry())
442  continue;
443  auto key = llvm::cast<LLVMPointerType>(entry.getKey().get<Type>());
444  auto values = llvm::dyn_cast<DenseIntElementsAttr>(entry.getValue());
445  if (!values || (values.size() != 3 && values.size() != 4)) {
446  return emitError(loc)
447  << "expected layout attribute for " << entry.getKey().get<Type>()
448  << " to be a dense integer elements attribute with 3 or 4 "
449  "elements";
450  }
451  if (key.getElementType() && !key.getElementType().isInteger(8)) {
452  return emitError(loc) << "unexpected layout attribute for pointer to "
453  << key.getElementType();
454  }
457  return emitError(loc) << "preferred alignment is expected to be at least "
458  "as large as ABI alignment";
459  }
460  }
461  return success();
462 }
463 
464 //===----------------------------------------------------------------------===//
465 // Struct type.
466 //===----------------------------------------------------------------------===//
467 
469  return !llvm::isa<LLVMVoidType, LLVMLabelType, LLVMMetadataType,
470  LLVMFunctionType, LLVMTokenType, LLVMScalableVectorType>(
471  type);
472 }
473 
475  StringRef name) {
476  return Base::get(context, name, /*opaque=*/false);
477 }
478 
481  StringRef name) {
482  return Base::getChecked(emitError, context, name, /*opaque=*/false);
483 }
484 
486  StringRef name,
487  ArrayRef<Type> elements,
488  bool isPacked) {
489  std::string stringName = name.str();
490  unsigned counter = 0;
491  do {
492  auto type = LLVMStructType::getIdentified(context, stringName);
493  if (type.isInitialized() || failed(type.setBody(elements, isPacked))) {
494  counter += 1;
495  stringName = (Twine(name) + "." + std::to_string(counter)).str();
496  continue;
497  }
498  return type;
499  } while (true);
500 }
501 
503  ArrayRef<Type> types, bool isPacked) {
504  return Base::get(context, types, isPacked);
505 }
506 
509  MLIRContext *context, ArrayRef<Type> types,
510  bool isPacked) {
511  return Base::getChecked(emitError, context, types, isPacked);
512 }
513 
515  return Base::get(context, name, /*opaque=*/true);
516 }
517 
520  MLIRContext *context, StringRef name) {
521  return Base::getChecked(emitError, context, name, /*opaque=*/true);
522 }
523 
525  assert(isIdentified() && "can only set bodies of identified structs");
526  assert(llvm::all_of(types, LLVMStructType::isValidElementType) &&
527  "expected valid body types");
528  return Base::mutate(types, isPacked);
529 }
530 
531 bool LLVMStructType::isPacked() const { return getImpl()->isPacked(); }
532 bool LLVMStructType::isIdentified() const { return getImpl()->isIdentified(); }
534  return getImpl()->isIdentified() &&
535  (getImpl()->isOpaque() || !getImpl()->isInitialized());
536 }
537 bool LLVMStructType::isInitialized() { return getImpl()->isInitialized(); }
538 StringRef LLVMStructType::getName() { return getImpl()->getIdentifier(); }
540  return isIdentified() ? getImpl()->getIdentifiedStructBody()
541  : getImpl()->getTypeList();
542 }
543 
545  StringRef, bool) {
546  return success();
547 }
548 
551  ArrayRef<Type> types, bool) {
552  for (Type t : types)
553  if (!isValidElementType(t))
554  return emitError() << "invalid LLVM structure element type: " << t;
555 
556  return success();
557 }
558 
559 unsigned
561  DataLayoutEntryListRef params) const {
562  unsigned structSize = 0;
563  unsigned structAlignment = 1;
564  for (Type element : getBody()) {
565  unsigned elementAlignment =
566  isPacked() ? 1 : dataLayout.getTypeABIAlignment(element);
567  // Add padding to the struct size to align it to the abi alignment of the
568  // element type before than adding the size of the element
569  structSize = llvm::alignTo(structSize, elementAlignment);
570  structSize += dataLayout.getTypeSize(element);
571 
572  // The alignment requirement of a struct is equal to the strictest alignment
573  // requirement of its elements.
574  structAlignment = std::max(elementAlignment, structAlignment);
575  }
576  // At the end, add padding to the struct to satisfy its own alignment
577  // requirement. Otherwise structs inside of arrays would be misaligned.
578  structSize = llvm::alignTo(structSize, structAlignment);
579  return structSize * kBitsInByte;
580 }
581 
582 namespace {
583 enum class StructDLEntryPos { Abi = 0, Preferred = 1 };
584 } // namespace
585 
586 static std::optional<unsigned>
588  StructDLEntryPos pos) {
589  const auto *currentEntry =
590  llvm::find_if(params, [](DataLayoutEntryInterface entry) {
591  return entry.isTypeEntry();
592  });
593  if (currentEntry == params.end())
594  return std::nullopt;
595 
596  auto attr = llvm::cast<DenseIntElementsAttr>(currentEntry->getValue());
597  if (pos == StructDLEntryPos::Preferred &&
598  attr.size() <= static_cast<unsigned>(StructDLEntryPos::Preferred))
599  // If no preferred was specified, fall back to abi alignment
600  pos = StructDLEntryPos::Abi;
601 
602  return attr.getValues<unsigned>()[static_cast<unsigned>(pos)];
603 }
604 
605 static unsigned calculateStructAlignment(const DataLayout &dataLayout,
606  DataLayoutEntryListRef params,
607  LLVMStructType type,
608  StructDLEntryPos pos) {
609  // Packed structs always have an abi alignment of 1
610  if (pos == StructDLEntryPos::Abi && type.isPacked()) {
611  return 1;
612  }
613 
614  // The alignment requirement of a struct is equal to the strictest alignment
615  // requirement of its elements.
616  unsigned structAlignment = 1;
617  for (Type iter : type.getBody()) {
618  structAlignment =
619  std::max(dataLayout.getTypeABIAlignment(iter), structAlignment);
620  }
621 
622  // Entries are only allowed to be stricter than the required alignment
623  if (std::optional<unsigned> entryResult =
624  getStructDataLayoutEntry(params, type, pos))
625  return std::max(*entryResult / kBitsInByte, structAlignment);
626 
627  return structAlignment;
628 }
629 
630 unsigned LLVMStructType::getABIAlignment(const DataLayout &dataLayout,
631  DataLayoutEntryListRef params) const {
632  return calculateStructAlignment(dataLayout, params, *this,
633  StructDLEntryPos::Abi);
634 }
635 
636 unsigned
638  DataLayoutEntryListRef params) const {
639  return calculateStructAlignment(dataLayout, params, *this,
640  StructDLEntryPos::Preferred);
641 }
642 
643 static unsigned extractStructSpecValue(Attribute attr, StructDLEntryPos pos) {
644  return llvm::cast<DenseIntElementsAttr>(attr)
645  .getValues<unsigned>()[static_cast<unsigned>(pos)];
646 }
647 
649  DataLayoutEntryListRef newLayout) const {
650  for (DataLayoutEntryInterface newEntry : newLayout) {
651  if (!newEntry.isTypeEntry())
652  continue;
653 
654  const auto *previousEntry =
655  llvm::find_if(oldLayout, [](DataLayoutEntryInterface entry) {
656  return entry.isTypeEntry();
657  });
658  if (previousEntry == oldLayout.end())
659  continue;
660 
661  unsigned abi = extractStructSpecValue(previousEntry->getValue(),
662  StructDLEntryPos::Abi);
663  unsigned newAbi =
664  extractStructSpecValue(newEntry.getValue(), StructDLEntryPos::Abi);
665  if (abi < newAbi || abi % newAbi != 0)
666  return false;
667  }
668  return true;
669 }
670 
672  Location loc) const {
673  for (DataLayoutEntryInterface entry : entries) {
674  if (!entry.isTypeEntry())
675  continue;
676 
677  auto key = llvm::cast<LLVMStructType>(entry.getKey().get<Type>());
678  auto values = llvm::dyn_cast<DenseIntElementsAttr>(entry.getValue());
679  if (!values || (values.size() != 2 && values.size() != 1)) {
680  return emitError(loc)
681  << "expected layout attribute for " << entry.getKey().get<Type>()
682  << " to be a dense integer elements attribute of 1 or 2 elements";
683  }
684 
685  if (key.isIdentified() || !key.getBody().empty()) {
686  return emitError(loc) << "unexpected layout attribute for struct " << key;
687  }
688 
689  if (values.size() == 1)
690  continue;
691 
692  if (extractStructSpecValue(values, StructDLEntryPos::Abi) >
693  extractStructSpecValue(values, StructDLEntryPos::Preferred)) {
694  return emitError(loc) << "preferred alignment is expected to be at least "
695  "as large as ABI alignment";
696  }
697  }
698  return mlir::success();
699 }
700 
701 //===----------------------------------------------------------------------===//
702 // Vector types.
703 //===----------------------------------------------------------------------===//
704 
705 /// Verifies that the type about to be constructed is well-formed.
706 template <typename VecTy>
707 static LogicalResult
709  Type elementType, unsigned numElements) {
710  if (numElements == 0)
711  return emitError() << "the number of vector elements must be positive";
712 
713  if (!VecTy::isValidElementType(elementType))
714  return emitError() << "invalid vector element type";
715 
716  return success();
717 }
718 
719 LLVMFixedVectorType LLVMFixedVectorType::get(Type elementType,
720  unsigned numElements) {
721  assert(elementType && "expected non-null subtype");
722  return Base::get(elementType.getContext(), elementType, numElements);
723 }
724 
725 LLVMFixedVectorType
726 LLVMFixedVectorType::getChecked(function_ref<InFlightDiagnostic()> emitError,
727  Type elementType, unsigned numElements) {
728  assert(elementType && "expected non-null subtype");
729  return Base::getChecked(emitError, elementType.getContext(), elementType,
730  numElements);
731 }
732 
733 bool LLVMFixedVectorType::isValidElementType(Type type) {
734  return llvm::isa<LLVMPointerType, LLVMPPCFP128Type>(type);
735 }
736 
739  Type elementType, unsigned numElements) {
740  return verifyVectorConstructionInvariants<LLVMFixedVectorType>(
741  emitError, elementType, numElements);
742 }
743 
744 //===----------------------------------------------------------------------===//
745 // LLVMScalableVectorType.
746 //===----------------------------------------------------------------------===//
747 
748 LLVMScalableVectorType LLVMScalableVectorType::get(Type elementType,
749  unsigned minNumElements) {
750  assert(elementType && "expected non-null subtype");
751  return Base::get(elementType.getContext(), elementType, minNumElements);
752 }
753 
754 LLVMScalableVectorType
755 LLVMScalableVectorType::getChecked(function_ref<InFlightDiagnostic()> emitError,
756  Type elementType, unsigned minNumElements) {
757  assert(elementType && "expected non-null subtype");
758  return Base::getChecked(emitError, elementType.getContext(), elementType,
759  minNumElements);
760 }
761 
762 bool LLVMScalableVectorType::isValidElementType(Type type) {
763  if (auto intType = llvm::dyn_cast<IntegerType>(type))
764  return intType.isSignless();
765 
766  return isCompatibleFloatingPointType(type) ||
767  llvm::isa<LLVMPointerType>(type);
768 }
769 
772  Type elementType, unsigned numElements) {
773  return verifyVectorConstructionInvariants<LLVMScalableVectorType>(
774  emitError, elementType, numElements);
775 }
776 
777 //===----------------------------------------------------------------------===//
778 // LLVMTargetExtType.
779 //===----------------------------------------------------------------------===//
780 
781 static constexpr llvm::StringRef kSpirvPrefix = "spirv.";
782 static constexpr llvm::StringRef kArmSVCount = "aarch64.svcount";
783 
784 bool LLVM::LLVMTargetExtType::hasProperty(Property prop) const {
785  // See llvm/lib/IR/Type.cpp for reference.
786  uint64_t properties = 0;
787 
788  if (getExtTypeName().starts_with(kSpirvPrefix))
789  properties |=
790  (LLVMTargetExtType::HasZeroInit | LLVM::LLVMTargetExtType::CanBeGlobal);
791 
792  return (properties & prop) == prop;
793 }
794 
795 bool LLVM::LLVMTargetExtType::supportsMemOps() const {
796  // See llvm/lib/IR/Type.cpp for reference.
797  if (getExtTypeName().starts_with(kSpirvPrefix))
798  return true;
799 
800  if (getExtTypeName() == kArmSVCount)
801  return true;
802 
803  return false;
804 }
805 
806 //===----------------------------------------------------------------------===//
807 // Utility functions.
808 //===----------------------------------------------------------------------===//
809 
811  // clang-format off
812  if (llvm::isa<
813  BFloat16Type,
814  Float16Type,
815  Float32Type,
816  Float64Type,
817  Float80Type,
818  Float128Type,
819  Float8E4M3FNType,
820  Float8E5M2Type,
821  LLVMArrayType,
822  LLVMFunctionType,
823  LLVMLabelType,
824  LLVMMetadataType,
825  LLVMPPCFP128Type,
826  LLVMPointerType,
828  LLVMTokenType,
829  LLVMFixedVectorType,
830  LLVMScalableVectorType,
831  LLVMTargetExtType,
832  LLVMVoidType,
833  LLVMX86MMXType
834  >(type)) {
835  // clang-format on
836  return true;
837  }
838 
839  // Only signless integers are compatible.
840  if (auto intType = llvm::dyn_cast<IntegerType>(type))
841  return intType.isSignless();
842 
843  // 1D vector types are compatible.
844  if (auto vecType = llvm::dyn_cast<VectorType>(type))
845  return vecType.getRank() == 1;
846 
847  return false;
848 }
849 
850 static bool isCompatibleImpl(Type type, DenseSet<Type> &compatibleTypes) {
851  if (!compatibleTypes.insert(type).second)
852  return true;
853 
854  auto isCompatible = [&](Type type) {
855  return isCompatibleImpl(type, compatibleTypes);
856  };
857 
858  bool result =
860  .Case<LLVMStructType>([&](auto structType) {
861  return llvm::all_of(structType.getBody(), isCompatible);
862  })
863  .Case<LLVMFunctionType>([&](auto funcType) {
864  return isCompatible(funcType.getReturnType()) &&
865  llvm::all_of(funcType.getParams(), isCompatible);
866  })
867  .Case<IntegerType>([](auto intType) { return intType.isSignless(); })
868  .Case<VectorType>([&](auto vecType) {
869  return vecType.getRank() == 1 &&
870  isCompatible(vecType.getElementType());
871  })
872  .Case<LLVMPointerType>([&](auto pointerType) {
873  if (pointerType.isOpaque())
874  return true;
875  return isCompatible(pointerType.getElementType());
876  })
877  .Case<LLVMTargetExtType>([&](auto extType) {
878  return llvm::all_of(extType.getTypeParams(), isCompatible);
879  })
880  // clang-format off
881  .Case<
882  LLVMFixedVectorType,
883  LLVMScalableVectorType,
884  LLVMArrayType
885  >([&](auto containerType) {
886  return isCompatible(containerType.getElementType());
887  })
888  .Case<
889  BFloat16Type,
890  Float16Type,
891  Float32Type,
892  Float64Type,
893  Float80Type,
894  Float128Type,
895  Float8E4M3FNType,
896  Float8E5M2Type,
897  LLVMLabelType,
898  LLVMMetadataType,
899  LLVMPPCFP128Type,
900  LLVMTokenType,
901  LLVMVoidType,
902  LLVMX86MMXType
903  >([](Type) { return true; })
904  // clang-format on
905  .Default([](Type) { return false; });
906 
907  if (!result)
908  compatibleTypes.erase(type);
909 
910  return result;
911 }
912 
914  if (auto *llvmDialect =
915  type.getContext()->getLoadedDialect<LLVM::LLVMDialect>())
916  return isCompatibleImpl(type, llvmDialect->compatibleTypes.get());
917 
918  DenseSet<Type> localCompatibleTypes;
919  return isCompatibleImpl(type, localCompatibleTypes);
920 }
921 
923  return LLVMDialect::isCompatibleType(type);
924 }
925 
927  return llvm::isa<BFloat16Type, Float16Type, Float32Type, Float64Type,
928  Float80Type, Float128Type, LLVMPPCFP128Type>(type);
929 }
930 
932  if (llvm::isa<LLVMFixedVectorType, LLVMScalableVectorType>(type))
933  return true;
934 
935  if (auto vecType = llvm::dyn_cast<VectorType>(type)) {
936  if (vecType.getRank() != 1)
937  return false;
938  Type elementType = vecType.getElementType();
939  if (auto intType = llvm::dyn_cast<IntegerType>(elementType))
940  return intType.isSignless();
941  return llvm::isa<BFloat16Type, Float16Type, Float32Type, Float64Type,
942  Float80Type, Float128Type>(elementType);
943  }
944  return false;
945 }
946 
948  return llvm::TypeSwitch<Type, Type>(type)
949  .Case<LLVMFixedVectorType, LLVMScalableVectorType, VectorType>(
950  [](auto ty) { return ty.getElementType(); })
951  .Default([](Type) -> Type {
952  llvm_unreachable("incompatible with LLVM vector type");
953  });
954 }
955 
956 llvm::ElementCount mlir::LLVM::getVectorNumElements(Type type) {
958  .Case([](VectorType ty) {
959  if (ty.isScalable())
960  return llvm::ElementCount::getScalable(ty.getNumElements());
961  return llvm::ElementCount::getFixed(ty.getNumElements());
962  })
963  .Case([](LLVMFixedVectorType ty) {
964  return llvm::ElementCount::getFixed(ty.getNumElements());
965  })
966  .Case([](LLVMScalableVectorType ty) {
967  return llvm::ElementCount::getScalable(ty.getMinNumElements());
968  })
969  .Default([](Type) -> llvm::ElementCount {
970  llvm_unreachable("incompatible with LLVM vector type");
971  });
972 }
973 
975  assert((llvm::isa<LLVMFixedVectorType, LLVMScalableVectorType, VectorType>(
976  vectorType)) &&
977  "expected LLVM-compatible vector type");
978  return !llvm::isa<LLVMFixedVectorType>(vectorType) &&
979  (llvm::isa<LLVMScalableVectorType>(vectorType) ||
980  llvm::cast<VectorType>(vectorType).isScalable());
981 }
982 
983 Type mlir::LLVM::getVectorType(Type elementType, unsigned numElements,
984  bool isScalable) {
985  bool useLLVM = LLVMFixedVectorType::isValidElementType(elementType);
986  bool useBuiltIn = VectorType::isValidElementType(elementType);
987  (void)useBuiltIn;
988  assert((useLLVM ^ useBuiltIn) && "expected LLVM-compatible fixed-vector type "
989  "to be either builtin or LLVM dialect type");
990  if (useLLVM) {
991  if (isScalable)
992  return LLVMScalableVectorType::get(elementType, numElements);
993  return LLVMFixedVectorType::get(elementType, numElements);
994  }
995 
996  // LLVM vectors are always 1-D, hence only 1 bool is required to mark it as
997  // scalable/non-scalable.
998  return VectorType::get(numElements, elementType, {isScalable});
999 }
1000 
1002  const llvm::ElementCount &numElements) {
1003  if (numElements.isScalable())
1004  return getVectorType(elementType, numElements.getKnownMinValue(),
1005  /*isScalable=*/true);
1006  return getVectorType(elementType, numElements.getFixedValue(),
1007  /*isScalable=*/false);
1008 }
1009 
1010 Type mlir::LLVM::getFixedVectorType(Type elementType, unsigned numElements) {
1011  bool useLLVM = LLVMFixedVectorType::isValidElementType(elementType);
1012  bool useBuiltIn = VectorType::isValidElementType(elementType);
1013  (void)useBuiltIn;
1014  assert((useLLVM ^ useBuiltIn) && "expected LLVM-compatible fixed-vector type "
1015  "to be either builtin or LLVM dialect type");
1016  if (useLLVM)
1017  return LLVMFixedVectorType::get(elementType, numElements);
1018  return VectorType::get(numElements, elementType);
1019 }
1020 
1021 Type mlir::LLVM::getScalableVectorType(Type elementType, unsigned numElements) {
1022  bool useLLVM = LLVMScalableVectorType::isValidElementType(elementType);
1023  bool useBuiltIn = VectorType::isValidElementType(elementType);
1024  (void)useBuiltIn;
1025  assert((useLLVM ^ useBuiltIn) && "expected LLVM-compatible scalable-vector "
1026  "type to be either builtin or LLVM dialect "
1027  "type");
1028  if (useLLVM)
1029  return LLVMScalableVectorType::get(elementType, numElements);
1030 
1031  // LLVM vectors are always 1-D, hence only 1 bool is required to mark it as
1032  // scalable/non-scalable.
1033  return VectorType::get(numElements, elementType, /*scalableDims=*/true);
1034 }
1035 
1037  assert(isCompatibleType(type) &&
1038  "expected a type compatible with the LLVM dialect");
1039 
1041  .Case<BFloat16Type, Float16Type>(
1042  [](Type) { return llvm::TypeSize::Fixed(16); })
1043  .Case<Float32Type>([](Type) { return llvm::TypeSize::Fixed(32); })
1044  .Case<Float64Type, LLVMX86MMXType>(
1045  [](Type) { return llvm::TypeSize::Fixed(64); })
1046  .Case<Float80Type>([](Type) { return llvm::TypeSize::Fixed(80); })
1047  .Case<Float128Type>([](Type) { return llvm::TypeSize::Fixed(128); })
1048  .Case<IntegerType>([](IntegerType intTy) {
1049  return llvm::TypeSize::Fixed(intTy.getWidth());
1050  })
1051  .Case<LLVMPPCFP128Type>([](Type) { return llvm::TypeSize::Fixed(128); })
1052  .Case<LLVMFixedVectorType>([](LLVMFixedVectorType t) {
1053  llvm::TypeSize elementSize =
1054  getPrimitiveTypeSizeInBits(t.getElementType());
1055  return llvm::TypeSize(elementSize.getFixedValue() * t.getNumElements(),
1056  elementSize.isScalable());
1057  })
1058  .Case<VectorType>([](VectorType t) {
1059  assert(isCompatibleVectorType(t) &&
1060  "unexpected incompatible with LLVM vector type");
1061  llvm::TypeSize elementSize =
1062  getPrimitiveTypeSizeInBits(t.getElementType());
1063  return llvm::TypeSize(elementSize.getFixedValue() * t.getNumElements(),
1064  elementSize.isScalable());
1065  })
1066  .Default([](Type ty) {
1067  assert((llvm::isa<LLVMVoidType, LLVMLabelType, LLVMMetadataType,
1068  LLVMTokenType, LLVMStructType, LLVMArrayType,
1069  LLVMPointerType, LLVMFunctionType, LLVMTargetExtType>(
1070  ty)) &&
1071  "unexpected missing support for primitive type");
1072  return llvm::TypeSize::Fixed(0);
1073  });
1074 }
1075 
1076 //===----------------------------------------------------------------------===//
1077 // LLVMDialect
1078 //===----------------------------------------------------------------------===//
1079 
1080 void LLVMDialect::registerTypes() {
1081  addTypes<
1082 #define GET_TYPEDEF_LIST
1083 #include "mlir/Dialect/LLVMIR/LLVMTypes.cpp.inc"
1084  >();
1085 }
1086 
1088  return detail::parseType(parser);
1089 }
1090 
1091 void LLVMDialect::printType(Type type, DialectAsmPrinter &os) const {
1092  return detail::printType(type, os);
1093 }
static MLIRContext * getContext(OpFoldResult val)
static unsigned calculateStructAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params, LLVMStructType type, StructDLEntryPos pos)
Definition: LLVMTypes.cpp:605
static void printExtTypeParams(AsmPrinter &p, ArrayRef< Type > typeParams, ArrayRef< unsigned int > intParams)
Definition: LLVMTypes.cpp:156
static LLVM_ATTRIBUTE_UNUSED OptionalParseResult generatedTypeParser(AsmParser &parser, StringRef *mnemonic, Type &value)
These are unused for now.
constexpr static const unsigned kDefaultPointerAlignment
Definition: LLVMTypes.cpp:319
static void printFunctionTypes(AsmPrinter &p, ArrayRef< Type > params, bool isVarArg)
Definition: LLVMTypes.cpp:66
static bool isCompatibleImpl(Type type, DenseSet< Type > &compatibleTypes)
Definition: LLVMTypes.cpp:850
static void printPointer(AsmPrinter &p, Type elementType, unsigned addressSpace)
Definition: LLVMTypes.cpp:101
static ParseResult parseExtTypeParams(AsmParser &p, SmallVectorImpl< Type > &typeParams, SmallVectorImpl< unsigned int > &intParams)
Parses the parameter list for a target extension type.
Definition: LLVMTypes.cpp:124
static LLVM_ATTRIBUTE_UNUSED LogicalResult generatedTypePrinter(Type def, AsmPrinter &printer)
static constexpr llvm::StringRef kSpirvPrefix
Definition: LLVMTypes.cpp:781
static LogicalResult verifyVectorConstructionInvariants(function_ref< InFlightDiagnostic()> emitError, Type elementType, unsigned numElements)
Verifies that the type about to be constructed is well-formed.
Definition: LLVMTypes.cpp:708
static ParseResult parseFunctionTypes(AsmParser &p, SmallVector< Type > &params, bool &isVarArg)
Definition: LLVMTypes.cpp:36
static unsigned extractStructSpecValue(Attribute attr, StructDLEntryPos pos)
Definition: LLVMTypes.cpp:643
static constexpr llvm::StringRef kArmSVCount
Definition: LLVMTypes.cpp:782
constexpr static const unsigned kDefaultPointerSizeBits
Definition: LLVMTypes.cpp:318
static std::optional< unsigned > getPointerDataLayoutEntry(DataLayoutEntryListRef params, LLVMPointerType type, PtrDLEntryPos pos)
Returns the part of the data layout entry that corresponds to pos for the given type by interpreting ...
Definition: LLVMTypes.cpp:335
constexpr static const unsigned kBitsInByte
Definition: LLVMTypes.cpp:30
static std::optional< unsigned > getStructDataLayoutEntry(DataLayoutEntryListRef params, LLVMStructType type, StructDLEntryPos pos)
Definition: LLVMTypes.cpp:587
static ParseResult parsePointer(AsmParser &p, Type &elementType, unsigned &addressSpace)
Definition: LLVMTypes.cpp:82
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
static Type getElementType(Type type, ArrayRef< int32_t > indices, function_ref< InFlightDiagnostic(StringRef)> emitErrorFn)
Walks the given type hierarchy with the given indices, potentially down to component granularity,...
Definition: SPIRVOps.cpp:216
static int64_t getNumElements(ShapedType type)
Definition: TensorOps.cpp:1332
This base class exposes generic asm parser hooks, usable across the various derived parsers.
virtual OptionalParseResult parseOptionalInteger(APInt &result)=0
Parse an optional integer value from the stream.
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 parseRParen()=0
Parse a ) token.
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 ParseResult parseOptionalRParen()=0
Parse a ) token if present.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
virtual ParseResult parseOptionalComma()=0
Parse a , token if present.
virtual ParseResult parseOptionalEllipsis()=0
Parse a ... token if present;.
This base class exposes generic asm printer hooks, usable across the various derived printers.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
The main mechanism for performing data layout queries.
unsigned getTypeABIAlignment(Type t) const
Returns the required alignment of the given type in the current scope.
unsigned getTypeSizeInBits(Type t) const
Returns the size in bits of the given type in the current scope.
unsigned getTypePreferredAlignment(Type t) const
Returns the preferred of the given type in the current scope.
unsigned getTypeSize(Type t) const
Returns the size of the given type in the current scope.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:308
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:108
static LLVMStructType getLiteralChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, ArrayRef< Type > types, bool isPacked=false)
Definition: LLVMTypes.cpp:508
LogicalResult setBody(ArrayRef< Type > types, bool isPacked)
Set the body of an identified struct.
Definition: LLVMTypes.cpp:524
unsigned getTypeSizeInBits(const DataLayout &dataLayout, DataLayoutEntryListRef params) const
Hooks for DataLayoutTypeInterface.
Definition: LLVMTypes.cpp:560
static bool isValidElementType(Type type)
Checks if the given type can be contained in a structure type.
Definition: LLVMTypes.cpp:468
unsigned getPreferredAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params) const
Definition: LLVMTypes.cpp:637
StringRef getName()
Returns the name of an identified struct.
Definition: LLVMTypes.cpp:538
static LLVMStructType getOpaqueChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, StringRef name)
Definition: LLVMTypes.cpp:519
LogicalResult verifyEntries(DataLayoutEntryListRef entries, Location loc) const
Definition: LLVMTypes.cpp:671
bool isPacked() const
Checks if a struct is packed.
Definition: LLVMTypes.cpp:531
static LLVMStructType getIdentifiedChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, StringRef name)
Definition: LLVMTypes.cpp:479
ArrayRef< Type > getBody() const
Returns the list of element types contained in a non-opaque struct.
Definition: LLVMTypes.cpp:539
bool isInitialized()
Checks if a struct is initialized.
Definition: LLVMTypes.cpp:537
bool isOpaque()
Checks if a struct is opaque.
Definition: LLVMTypes.cpp:533
static LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, StringRef, bool)
Verifies that the type about to be constructed is well-formed.
Definition: LLVMTypes.cpp:544
bool areCompatible(DataLayoutEntryListRef oldLayout, DataLayoutEntryListRef newLayout) const
Definition: LLVMTypes.cpp:648
unsigned getABIAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params) const
Definition: LLVMTypes.cpp:630
static LLVMStructType getLiteral(MLIRContext *context, ArrayRef< Type > types, bool isPacked=false)
Gets or creates a literal struct with the given body in the provided context.
Definition: LLVMTypes.cpp:502
static LLVMStructType getNewIdentified(MLIRContext *context, StringRef name, ArrayRef< Type > elements, bool isPacked=false)
Gets a new identified struct with the given body.
Definition: LLVMTypes.cpp:485
static LLVMStructType getIdentified(MLIRContext *context, StringRef name)
Gets or creates an identified struct with the given name in the provided context.
Definition: LLVMTypes.cpp:474
static LLVMStructType getOpaque(StringRef name, MLIRContext *context)
Gets or creates an intentionally-opaque identified struct.
Definition: LLVMTypes.cpp:514
bool isIdentified() const
Checks if a struct is identified.
Definition: LLVMTypes.cpp:532
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Dialect * getLoadedDialect(StringRef name)
Get a registered IR dialect with the given namespace.
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:39
ParseResult value() const
Access the internal ParseResult value.
Definition: OpDefinition.h:52
bool has_value() const
Returns true if we contain a valid ParseResult value.
Definition: OpDefinition.h:49
This class represents success/failure for parsing-like operations that find it important to chain tog...
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:36
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
Definition: Types.cpp:35
ImplType * getImpl() const
Utility for easy access to the storage instance.
void printType(Type type, AsmPrinter &printer)
Prints an LLVM Dialect type.
Type parseType(DialectAsmParser &parser)
Parses an LLVM dialect type.
Type getVectorType(Type elementType, unsigned numElements, bool isScalable=false)
Creates an LLVM dialect-compatible vector type with the given element type and length.
Definition: LLVMTypes.cpp:983
llvm::TypeSize getPrimitiveTypeSizeInBits(Type type)
Returns the size of the given primitive LLVM dialect-compatible type (including vectors) in bits,...
Definition: LLVMTypes.cpp:1036
void printPrettyLLVMType(AsmPrinter &p, Type type)
Print any MLIR type or a concise syntax for LLVM types.
bool isScalableVectorType(Type vectorType)
Returns whether a vector type is scalable or not.
Definition: LLVMTypes.cpp:974
std::optional< unsigned > extractPointerSpecValue(Attribute attr, PtrDLEntryPos pos)
Returns the value that corresponds to named position pos from the data layout entry attr assuming it'...
Definition: LLVMTypes.cpp:321
ParseResult parsePrettyLLVMType(AsmParser &p, Type &type)
Parse any MLIR type or a concise syntax for LLVM types.
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:931
bool isCompatibleOuterType(Type type)
Returns true if the given outer type is compatible with the LLVM dialect without checking its potenti...
Definition: LLVMTypes.cpp:810
Type getFixedVectorType(Type elementType, unsigned numElements)
Creates an LLVM dialect-compatible type with the given element type and length.
Definition: LLVMTypes.cpp:1010
PtrDLEntryPos
The positions of different values in the data layout entry for pointers.
Definition: LLVMTypes.h:284
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:913
Type getScalableVectorType(Type elementType, unsigned numElements)
Creates an LLVM dialect-compatible type with the given element type and length.
Definition: LLVMTypes.cpp:1021
bool isCompatibleFloatingPointType(Type type)
Returns true if the given type is a floating-point type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:926
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
Definition: LLVMTypes.cpp:956
Type getVectorElementType(Type type)
Returns the element type of any vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:947
This header declares functions that assist transformations in the MemRef dialect.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
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
Operation * clone(OpBuilder &b, Operation *op, TypeRange newResultTypes, ValueRange newOperands)
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
Type parseType(llvm::StringRef typeStr, MLIRContext *context, size_t *numRead=nullptr, bool isKnownNullTerminated=false)
This parses a single MLIR type to an MLIR context if it was valid.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition: Verifier.cpp:421
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