23#include "llvm/ADT/TypeSwitch.h"
24#include "llvm/Support/TypeSize.h"
53 params.push_back(type);
61 params.push_back(type);
68 llvm::interleaveComma(params, p,
93 auto typeOrIntParser = [&]() -> ParseResult {
96 if (intResult.has_value() && !failed(*intResult)) {
98 intParams.push_back(i);
108 typeParams.push_back(t);
116 "failed to parse parameter list for target extension type");
125 if (!typeParams.empty() && !intParams.empty())
142#include "mlir/Dialect/LLVMIR/LLVMTypeInterfaces.cpp.inc"
144#define GET_TYPEDEF_CLASSES
145#include "mlir/Dialect/LLVMIR/LLVMTypes.cpp.inc"
151bool LLVMArrayType::isValidElementType(
Type type) {
152 return !llvm::isa<LLVMVoidType, LLVMLabelType, LLVMMetadataType,
153 LLVMFunctionType, TokenType>(type);
156LLVMArrayType LLVMArrayType::get(
Type elementType, uint64_t numElements) {
157 assert(elementType &&
"expected non-null subtype");
158 return Base::get(elementType.
getContext(), elementType, numElements);
163 Type elementType, uint64_t numElements) {
164 assert(elementType &&
"expected non-null subtype");
171 Type elementType, uint64_t numElements) {
172 if (!isValidElementType(elementType))
173 return emitError() <<
"invalid array element type: " << elementType;
182LLVMArrayType::getTypeSizeInBits(
const DataLayout &dataLayout,
185 getTypeSize(dataLayout, params));
188llvm::TypeSize LLVMArrayType::getTypeSize(
const DataLayout &dataLayout,
195uint64_t LLVMArrayType::getABIAlignment(
const DataLayout &dataLayout,
201LLVMArrayType::getPreferredAlignment(
const DataLayout &dataLayout,
211LLVMByteType::getTypeSizeInBits(
const DataLayout &dataLayout,
216uint64_t LLVMByteType::getABIAlignment(
const DataLayout &dataLayout,
224 return emitError() <<
"bitwidth must be greater than 0";
227 constexpr unsigned kMaxBitWidth = 1 << 23;
228 if (bitWidth >= kMaxBitWidth)
229 return emitError() <<
"bitwidth must be less than " << kMaxBitWidth
230 <<
", but got " << bitWidth;
238bool LLVMFunctionType::isValidArgumentType(
Type type) {
239 if (
auto structType = dyn_cast<LLVMStructType>(type))
240 return !structType.isOpaque();
242 return !llvm::isa<LLVMVoidType, LLVMFunctionType>(type);
245bool LLVMFunctionType::isValidResultType(Type type) {
246 return !llvm::isa<LLVMFunctionType, LLVMMetadataType, LLVMLabelType>(type);
249LLVMFunctionType LLVMFunctionType::get(Type
result, ArrayRef<Type> arguments,
251 assert(
result &&
"expected non-null result");
252 return Base::get(
result.getContext(),
result, arguments, isVarArg);
257 Type
result, ArrayRef<Type> arguments,
259 assert(
result &&
"expected non-null result");
264LLVMFunctionType LLVMFunctionType::clone(
TypeRange inputs,
269 if (results.size() > 1)
272 results.empty() ? LLVMVoidType::get(
getContext()) : results[0];
273 if (!isValidResultType(resultType))
275 if (!llvm::all_of(inputs, isValidArgumentType))
277 return get(resultType, llvm::to_vector(inputs), isVarArg());
280ArrayRef<Type> LLVMFunctionType::getReturnTypes()
const {
281 return static_cast<detail::LLVMFunctionTypeStorage *
>(getImpl())->returnType;
286 Type
result, ArrayRef<Type> arguments,
bool) {
287 if (!isValidResultType(
result))
290 for (Type arg : arguments)
291 if (!isValidArgumentType(arg))
292 return emitError() <<
"invalid function argument type: " << arg;
306 auto spec = cast<DenseIntElementsAttr>(attr);
307 auto idx =
static_cast<int64_t>(pos);
308 if (idx >= spec.size())
310 return spec.getValues<uint64_t>()[idx];
317static std::optional<uint64_t>
322 for (DataLayoutEntryInterface entry : params) {
323 if (!entry.isTypeEntry())
325 if (cast<LLVMPointerType>(cast<Type>(entry.getKey())).getAddressSpace() ==
326 type.getAddressSpace()) {
327 currentEntry = entry.getValue();
344 if (type.getAddressSpace() == 0) {
354LLVMPointerType::getTypeSizeInBits(
const DataLayout &dataLayout,
356 if (std::optional<uint64_t> size =
358 return llvm::TypeSize::getFixed(*size);
365uint64_t LLVMPointerType::getABIAlignment(
const DataLayout &dataLayout,
367 if (std::optional<uint64_t> alignment =
375LLVMPointerType::getPreferredAlignment(
const DataLayout &dataLayout,
377 if (std::optional<uint64_t> alignment =
384std::optional<uint64_t>
385LLVMPointerType::getIndexBitwidth(
const DataLayout &dataLayout,
387 if (std::optional<uint64_t> indexBitwidth =
389 return *indexBitwidth;
394bool LLVMPointerType::areCompatible(
396 DataLayoutSpecInterface newSpec,
398 for (DataLayoutEntryInterface newEntry : newLayout) {
399 if (!newEntry.isTypeEntry())
404 llvm::cast<LLVMPointerType>(llvm::cast<Type>(newEntry.getKey()));
406 llvm::find_if(oldLayout, [&](DataLayoutEntryInterface entry) {
407 if (
auto type = llvm::dyn_cast_if_present<Type>(entry.getKey())) {
408 return llvm::cast<LLVMPointerType>(type).getAddressSpace() ==
409 newType.getAddressSpace();
413 if (it == oldLayout.end()) {
414 llvm::find_if(oldLayout, [&](DataLayoutEntryInterface entry) {
415 if (
auto type = llvm::dyn_cast_if_present<Type>(entry.getKey())) {
416 return llvm::cast<LLVMPointerType>(type).getAddressSpace() == 0;
421 if (it != oldLayout.end()) {
426 Attribute newSpec = llvm::cast<DenseIntElementsAttr>(newEntry.getValue());
429 if (size != newSize || abi < newAbi || abi % newAbi != 0)
436 Location loc)
const {
437 for (DataLayoutEntryInterface entry : entries) {
438 if (!entry.isTypeEntry())
440 auto key = llvm::cast<Type>(entry.getKey());
441 auto values = llvm::dyn_cast<DenseIntElementsAttr>(entry.getValue());
442 if (!values || (values.size() != 3 && values.size() != 4)) {
444 <<
"expected layout attribute for " << key
445 <<
" to be a dense integer elements attribute with 3 or 4 "
448 if (!values.getElementType().isInteger(64))
449 return emitError(loc) <<
"expected i64 parameters for " << key;
453 return emitError(loc) <<
"preferred alignment is expected to be at least "
454 "as large as ABI alignment";
464bool LLVMStructType::isValidElementType(Type type) {
465 return !llvm::isa<LLVMVoidType, LLVMLabelType, LLVMMetadataType,
466 LLVMFunctionType, TokenType>(type);
469LLVMStructType LLVMStructType::getIdentified(MLIRContext *context,
471 return Base::get(context, name,
false);
474LLVMStructType LLVMStructType::getIdentifiedChecked(
477 return Base::getChecked(
emitError, context, name,
false);
480LLVMStructType LLVMStructType::getNewIdentified(MLIRContext *context,
482 ArrayRef<Type> elements,
484 std::string stringName = name.str();
485 unsigned counter = 0;
487 auto type = LLVMStructType::getIdentified(context, stringName);
488 if (type.isInitialized() ||
failed(type.setBody(elements, isPacked))) {
490 stringName = (Twine(name) +
"." + std::to_string(counter)).str();
497LLVMStructType LLVMStructType::getLiteral(MLIRContext *context,
498 ArrayRef<Type> types,
bool isPacked) {
499 return Base::get(context, types, isPacked);
504 MLIRContext *context, ArrayRef<Type> types,
506 return Base::getChecked(
emitError, context, types, isPacked);
509LLVMStructType LLVMStructType::getOpaque(StringRef name, MLIRContext *context) {
510 return Base::get(context, name,
true);
515 MLIRContext *context, StringRef name) {
516 return Base::getChecked(
emitError, context, name,
true);
519LogicalResult LLVMStructType::setBody(ArrayRef<Type> types,
bool isPacked) {
520 assert(isIdentified() &&
"can only set bodies of identified structs");
521 assert(llvm::all_of(types, LLVMStructType::isValidElementType) &&
522 "expected valid body types");
523 return Base::mutate(types, isPacked);
526bool LLVMStructType::isPacked()
const {
return getImpl()->isPacked(); }
527bool LLVMStructType::isIdentified()
const {
return getImpl()->isIdentified(); }
528bool LLVMStructType::isOpaque()
const {
529 return getImpl()->isIdentified() &&
530 (getImpl()->isOpaque() || !getImpl()->isInitialized());
532bool LLVMStructType::isInitialized() {
return getImpl()->isInitialized(); }
533StringRef LLVMStructType::getName()
const {
return getImpl()->getIdentifier(); }
534ArrayRef<Type> LLVMStructType::getBody()
const {
535 return isIdentified() ? getImpl()->getIdentifiedStructBody()
536 : getImpl()->getTypeList();
540LLVMStructType::verifyInvariants(
function_ref<InFlightDiagnostic()>, StringRef,
547 ArrayRef<Type> types,
bool) {
549 if (!isValidElementType(t))
550 return emitError() <<
"invalid LLVM structure element type: " << t;
556LLVMStructType::getTypeSizeInBits(
const DataLayout &dataLayout,
558 auto structSize = llvm::TypeSize::getFixed(0);
559 uint64_t structAlignment = 1;
560 for (Type element : getBody()) {
561 uint64_t elementAlignment =
565 structSize = llvm::alignTo(structSize, elementAlignment);
570 structAlignment = std::max(elementAlignment, structAlignment);
574 structSize = llvm::alignTo(structSize, structAlignment);
582static std::optional<uint64_t>
584 StructDLEntryPos pos) {
585 const auto *currentEntry =
586 llvm::find_if(params, [](DataLayoutEntryInterface entry) {
587 return entry.isTypeEntry();
589 if (currentEntry == params.end())
592 auto attr = llvm::cast<DenseIntElementsAttr>(currentEntry->getValue());
593 if (pos == StructDLEntryPos::Preferred &&
594 attr.size() <=
static_cast<int64_t>(StructDLEntryPos::Preferred))
596 pos = StructDLEntryPos::Abi;
598 return attr.getValues<uint64_t>()[
static_cast<size_t>(pos)];
604 StructDLEntryPos pos) {
606 if (pos == StructDLEntryPos::Abi && type.isPacked()) {
612 uint64_t structAlignment = 1;
613 for (
Type iter : type.getBody()) {
619 if (std::optional<uint64_t> entryResult =
621 return std::max(*entryResult /
kBitsInByte, structAlignment);
623 return structAlignment;
626uint64_t LLVMStructType::getABIAlignment(
const DataLayout &dataLayout,
629 StructDLEntryPos::Abi);
633LLVMStructType::getPreferredAlignment(
const DataLayout &dataLayout,
636 StructDLEntryPos::Preferred);
640 return llvm::cast<DenseIntElementsAttr>(attr)
641 .getValues<uint64_t>()[
static_cast<size_t>(pos)];
644bool LLVMStructType::areCompatible(
646 DataLayoutSpecInterface newSpec,
648 for (DataLayoutEntryInterface newEntry : newLayout) {
649 if (!newEntry.isTypeEntry())
652 const auto *previousEntry =
653 llvm::find_if(oldLayout, [](DataLayoutEntryInterface entry) {
654 return entry.isTypeEntry();
656 if (previousEntry == oldLayout.end())
660 StructDLEntryPos::Abi);
663 if (abi < newAbi || abi % newAbi != 0)
670 Location loc)
const {
671 for (DataLayoutEntryInterface entry : entries) {
672 if (!entry.isTypeEntry())
675 auto key = llvm::cast<LLVMStructType>(llvm::cast<Type>(entry.getKey()));
676 auto values = llvm::dyn_cast<DenseIntElementsAttr>(entry.getValue());
677 if (!values || (values.size() != 2 && values.size() != 1)) {
679 <<
"expected layout attribute for "
680 << llvm::cast<Type>(entry.getKey())
681 <<
" to be a dense integer elements attribute of 1 or 2 elements";
683 if (!values.getElementType().isInteger(64))
684 return emitError(loc) <<
"expected i64 entries for " << key;
686 if (key.isIdentified() || !key.getBody().empty()) {
687 return emitError(loc) <<
"unexpected layout attribute for struct " << key;
690 if (values.size() == 1)
695 return emitError(loc) <<
"preferred alignment is expected to be at least "
696 "as large as ABI alignment";
699 return mlir::success();
710bool LLVM::LLVMTargetExtType::hasProperty(Property prop)
const {
712 uint64_t properties = 0;
716 (LLVMTargetExtType::HasZeroInit | LLVM::LLVMTargetExtType::CanBeGlobal);
719 properties |= LLVMTargetExtType::CanBeGlobal;
721 return (properties & prop) == prop;
724bool LLVM::LLVMTargetExtType::supportsMemOps()
const {
739const llvm::fltSemantics &LLVMPPCFP128Type::getFloatSemantics()
const {
740 return APFloat::PPCDoubleDouble();
751 auto ptrTy = dyn_cast<PtrLikeTypeInterface>(type);
754 return !ptrTy.hasPtrMetadata() && ptrTy.getElementType() ==
nullptr &&
755 isa<LLVMAddrSpaceAttrInterface>(ptrTy.getMemorySpace());
785 if (
auto intType = llvm::dyn_cast<IntegerType>(type))
786 return intType.isSignless();
789 if (
auto vecType = llvm::dyn_cast<VectorType>(type))
790 return vecType.getRank() == 1;
796 if (!compatibleTypes.insert(type).second)
799 auto isCompatible = [&](
Type type) {
805 .Case([&](LLVMStructType structType) {
806 return llvm::all_of(structType.getBody(), isCompatible);
808 .Case([&](LLVMFunctionType funcType) {
809 return isCompatible(funcType.getReturnType()) &&
810 llvm::all_of(funcType.getParams(), isCompatible);
812 .Case([](IntegerType intType) {
return intType.isSignless(); })
813 .Case([&](VectorType vecType) {
814 return vecType.getRank() == 1 &&
815 isCompatible(vecType.getElementType());
817 .Case([&](LLVMPointerType pointerType) {
return true; })
818 .Case([&](LLVMTargetExtType extType) {
819 return llvm::all_of(extType.getTypeParams(), isCompatible);
822 .Case([&](LLVMArrayType containerType) {
823 return isCompatible(containerType.getElementType());
839 >([](
Type) {
return true; })
841 .Case<PtrLikeTypeInterface>(
846 compatibleTypes.erase(type);
851bool LLVMDialect::isCompatibleType(
Type type) {
852 if (
auto *llvmDialect =
861 return LLVMDialect::isCompatibleType(type);
867 !isa<LLVM::LLVMVoidType, LLVM::LLVMFunctionType>(type)) &&
869 !(isa<LLVM::LLVMStructType>(type) &&
870 cast<LLVM::LLVMStructType>(type).isOpaque()) &&
872 !(isa<LLVM::LLVMTargetExtType>(type) &&
873 !cast<LLVM::LLVMTargetExtType>(type).supportsMemOps());
877 return llvm::isa<BFloat16Type, Float16Type, Float32Type, Float64Type,
878 Float80Type, Float128Type, LLVMPPCFP128Type>(type);
882 if (
auto vecType = llvm::dyn_cast<VectorType>(type)) {
883 if (vecType.getRank() != 1)
885 Type elementType = vecType.getElementType();
886 if (
auto intType = llvm::dyn_cast<IntegerType>(elementType))
887 return intType.isSignless();
888 return llvm::isa<BFloat16Type, Float16Type, Float32Type, Float64Type,
889 Float80Type, Float128Type, LLVMByteType, LLVMPointerType>(
897 auto vecTy = dyn_cast<VectorType>(type);
898 assert(vecTy &&
"incompatible with LLVM vector type");
899 if (vecTy.isScalable())
900 return llvm::ElementCount::getScalable(vecTy.getNumElements());
901 return llvm::ElementCount::getFixed(vecTy.getNumElements());
905 assert(llvm::isa<VectorType>(vectorType) &&
906 "expected LLVM-compatible vector type");
907 return llvm::cast<VectorType>(vectorType).isScalable();
912 assert(VectorType::isValidElementType(elementType) &&
913 "incompatible element type");
914 return VectorType::get(numElements, elementType, {isScalable});
918 const llvm::ElementCount &numElements) {
919 if (numElements.isScalable())
920 return getVectorType(elementType, numElements.getKnownMinValue(),
922 return getVectorType(elementType, numElements.getFixedValue(),
928 "expected a type compatible with the LLVM dialect");
931 .Case<BFloat16Type, Float16Type>(
932 [](
Type) {
return llvm::TypeSize::getFixed(16); })
933 .Case<Float32Type>([](
Type) {
return llvm::TypeSize::getFixed(32); })
934 .Case<Float64Type>([](
Type) {
return llvm::TypeSize::getFixed(64); })
935 .Case<Float80Type>([](
Type) {
return llvm::TypeSize::getFixed(80); })
936 .Case<Float128Type>([](
Type) {
return llvm::TypeSize::getFixed(128); })
937 .Case([](IntegerType intTy) {
938 return llvm::TypeSize::getFixed(intTy.getWidth());
940 .Case([](LLVMByteType byteTy) {
941 return llvm::TypeSize::getFixed(byteTy.getBitWidth());
943 .Case<LLVMPPCFP128Type>(
944 [](
Type) {
return llvm::TypeSize::getFixed(128); })
945 .Case([](VectorType t) {
947 "unexpected incompatible with LLVM vector type");
948 llvm::TypeSize elementSize =
950 return llvm::TypeSize(elementSize.getFixedValue() * t.getNumElements(),
951 elementSize.isScalable());
953 .Default([](
Type ty) {
955 (llvm::isa<LLVMVoidType, LLVMLabelType, LLVMMetadataType, TokenType,
956 LLVMStructType, LLVMArrayType, LLVMPointerType,
957 LLVMFunctionType, LLVMTargetExtType>(ty)) &&
958 "unexpected missing support for primitive type");
959 return llvm::TypeSize::getFixed(0);
967void LLVMDialect::registerTypes() {
969#define GET_TYPEDEF_LIST
970#include "mlir/Dialect/LLVMIR/LLVMTypes.cpp.inc"
979void LLVMDialect::printType(Type type, DialectAsmPrinter &os)
const {
static unsigned getBitWidth(Type type)
static Type getElementType(Type type)
Determine the element type of type.
static int64_t getNumElements(Type t)
Compute the total number of elements in the given type, also taking into account nested types.
constexpr static const uint64_t kDefaultPointerAlignment
static void printExtTypeParams(AsmPrinter &p, ArrayRef< Type > typeParams, ArrayRef< unsigned int > intParams)
constexpr static const uint64_t kDefaultPointerSizeBits
static void printFunctionTypes(AsmPrinter &p, ArrayRef< Type > params, bool isVarArg)
static bool isCompatibleImpl(Type type, DenseSet< Type > &compatibleTypes)
static ParseResult parseExtTypeParams(AsmParser &p, SmallVectorImpl< Type > &typeParams, SmallVectorImpl< unsigned int > &intParams)
Parses the parameter list for a target extension type.
static constexpr llvm::StringRef kSpirvPrefix
static std::optional< uint64_t > 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 ...
static bool isCompatiblePtrType(Type type)
Check whether type is a compatible ptr type.
static OptionalParseResult generatedTypeParser(AsmParser &parser, StringRef *mnemonic, Type &value)
These are unused for now.
static ParseResult parseFunctionTypes(AsmParser &p, SmallVector< Type > ¶ms, bool &isVarArg)
constexpr static const uint64_t kBitsInByte
static constexpr llvm::StringRef kArmSVCount
static constexpr llvm::StringRef kAMDGCNNamedBarrier
static LogicalResult generatedTypePrinter(Type def, AsmPrinter &printer)
static std::optional< uint64_t > getStructDataLayoutEntry(DataLayoutEntryListRef params, LLVMStructType type, StructDLEntryPos pos)
static uint64_t extractStructSpecValue(Attribute attr, StructDLEntryPos pos)
static uint64_t calculateStructAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params, LLVMStructType type, StructDLEntryPos pos)
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.
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.
The main mechanism for performing data layout queries.
std::optional< uint64_t > getTypeIndexBitwidth(Type t) const
Returns the bitwidth that should be used when performing index computations for the given pointer-lik...
llvm::TypeSize getTypeSize(Type t) const
Returns the size of the given type in the current scope.
uint64_t getTypePreferredAlignment(Type t) const
Returns the preferred of the given type in the current scope.
uint64_t getTypeABIAlignment(Type t) const
Returns the required alignment of the given type in the current scope.
llvm::TypeSize getTypeSizeInBits(Type t) const
Returns the size in bits of the given type in the current scope.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
This class represents a diagnostic that is inflight and set to be reported.
Dialect * getLoadedDialect(StringRef name)
Get a registered IR dialect with the given namespace.
This class implements Optional functionality for ParseResult.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
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.
llvm::TypeSize getPrimitiveTypeSizeInBits(Type type)
Returns the size of the given primitive LLVM dialect-compatible type (including vectors) in bits,...
void printPrettyLLVMType(AsmPrinter &p, Type type)
Print any MLIR type or a concise syntax for LLVM types.
bool isLoadableType(Type type)
Returns true if the given type is a loadable type compatible with the LLVM dialect.
bool isScalableVectorType(Type vectorType)
Returns whether a vector type is scalable or not.
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.
bool isCompatibleOuterType(Type type)
Returns true if the given outer type is compatible with the LLVM dialect without checking its potenti...
PtrDLEntryPos
The positions of different values in the data layout entry for pointers.
std::optional< uint64_t > extractPointerSpecValue(Attribute attr, PtrDLEntryPos pos)
Returns the value that corresponds to named position pos from the data layout entry attr assuming it'...
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
bool isCompatibleFloatingPointType(Type type)
Returns true if the given type is a floating-point type compatible with the LLVM dialect.
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
Include the generated interface declarations.
llvm::DenseSet< ValueT, ValueInfoT > DenseSet
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
::llvm::MapVector<::mlir::StringAttr, ::mlir::DataLayoutEntryInterface > DataLayoutIdentifiedEntryMap
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.
llvm::ArrayRef< DataLayoutEntryInterface > DataLayoutEntryListRef
llvm::function_ref< Fn > function_ref