15#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
16#include "mlir/IR/BuiltinAttributes.h"
17#include "mlir/IR/DialectImplementation.h"
18#include "mlir/IR/MLIRContext.h"
19#include "mlir/Support/LLVM.h"
26#include "llvm/ADT/APInt.h"
27#include "llvm/ADT/APSInt.h"
28#include "llvm/ADT/TypeSwitch.h"
29#include "llvm/Support/MathExtras.h"
35 if (
auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
36 return sizedTy.isSized();
45static mlir::ParseResult
49 mlir::ArrayRef<mlir::Type> params,
55static mlir::ParseResult
60 mlir::ArrayRef<mlir::Type> params,
69 mlir::ptr::MemorySpaceAttrInterface &attr);
72 mlir::ptr::MemorySpaceAttrInterface attr);
76 cir::TargetAddressSpaceAttr &attr);
79 cir::TargetAddressSpaceAttr attr);
87#include "clang/CIR/Dialect/IR/CIRTypeConstraints.cpp.inc"
91#define GET_TYPEDEF_CLASSES
92#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
101Type CIRDialect::parseType(DialectAsmParser &parser)
const {
102 llvm::SMLoc typeLoc = parser.getCurrentLocation();
103 llvm::StringRef mnemonic;
107 OptionalParseResult parseResult =
108 generatedTypeParser(parser, &mnemonic, genType);
109 if (parseResult.has_value())
113 return StringSwitch<function_ref<Type()>>(mnemonic)
114 .Case(
"record", [&] {
return RecordType::parse(parser); })
116 parser.emitError(typeLoc) <<
"unknown CIR type: " << mnemonic;
121void CIRDialect::printType(Type type, DialectAsmPrinter &os)
const {
123 if (generatedTypePrinter(type, os).succeeded())
127 llvm::report_fatal_error(
"printer is missing a handler for this type");
134Type RecordType::parse(mlir::AsmParser &parser) {
135 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
136 const llvm::SMLoc loc = parser.getCurrentLocation();
137 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
141 mlir::MLIRContext *context = parser.getContext();
143 if (parser.parseLess())
148 if (parser.parseOptionalKeyword(
"struct").succeeded())
149 kind = RecordKind::Struct;
150 else if (parser.parseOptionalKeyword(
"union").succeeded())
151 kind = RecordKind::Union;
152 else if (parser.parseOptionalKeyword(
"class").succeeded())
153 kind = RecordKind::Class;
155 parser.emitError(loc,
"unknown record type");
159 mlir::StringAttr
name;
160 parser.parseOptionalAttribute(name);
163 if (name && parser.parseOptionalGreater().succeeded()) {
164 RecordType
type = getChecked(eLoc, context, name,
kind);
165 if (succeeded(parser.tryStartCyclicParse(type))) {
166 parser.emitError(loc,
"invalid self-reference within record");
174 RecordType
type = getChecked(eLoc, context, name,
kind);
175 cyclicParseGuard = parser.tryStartCyclicParse(type);
176 if (failed(cyclicParseGuard)) {
177 parser.emitError(loc,
"record already defined");
182 if (parser.parseOptionalKeyword(
"packed").succeeded())
185 if (parser.parseOptionalKeyword(
"padded").succeeded())
189 bool incomplete =
true;
190 llvm::SmallVector<mlir::Type> members;
191 if (parser.parseOptionalKeyword(
"incomplete").failed()) {
193 const auto delimiter = AsmParser::Delimiter::Braces;
194 const auto parseElementFn = [&parser, &members]() {
195 return parser.parseType(members.emplace_back());
197 if (parser.parseCommaSeparatedList(delimiter, parseElementFn).failed())
201 if (parser.parseGreater())
205 ArrayRef<mlir::Type> membersRef(members);
206 mlir::Type
type = {};
207 if (name && incomplete) {
208 type = getChecked(eLoc, context, name,
kind);
209 }
else if (!name && !incomplete) {
210 type = getChecked(eLoc, context, membersRef, packed, padded,
kind);
211 }
else if (!incomplete) {
212 type = getChecked(eLoc, context, membersRef, name, packed, padded,
kind);
215 if (mlir::cast<RecordType>(type).isIncomplete())
216 mlir::cast<RecordType>(type).complete(membersRef, packed, padded);
219 parser.emitError(loc,
"anonymous records must be complete");
226void RecordType::print(mlir::AsmPrinter &printer)
const {
227 FailureOr<AsmPrinter::CyclicPrintReset> cyclicPrintGuard;
231 case RecordKind::Struct:
232 printer <<
"struct ";
234 case RecordKind::Union:
237 case RecordKind::Class:
246 cyclicPrintGuard = printer.tryStartCyclicPrint(*
this);
247 if (failed(cyclicPrintGuard)) {
256 printer <<
"packed ";
259 printer <<
"padded ";
261 if (isIncomplete()) {
262 printer <<
"incomplete";
265 llvm::interleaveComma(getMembers(), printer);
273RecordType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
274 llvm::ArrayRef<mlir::Type> members, mlir::StringAttr name,
275 bool incomplete,
bool packed,
bool padded,
276 RecordType::RecordKind
kind) {
277 if (name &&
name.getValue().empty())
278 return emitError() <<
"identified records cannot have an empty name";
279 return mlir::success();
282::llvm::ArrayRef<mlir::Type> RecordType::getMembers()
const {
286bool RecordType::isIncomplete()
const {
return getImpl()->incomplete; }
288mlir::StringAttr RecordType::getName()
const {
return getImpl()->name; }
290bool RecordType::getIncomplete()
const {
return getImpl()->incomplete; }
292bool RecordType::getPacked()
const {
return getImpl()->packed; }
294bool RecordType::getPadded()
const {
return getImpl()->padded; }
296cir::RecordType::RecordKind RecordType::getKind()
const {
299bool RecordType::isABIConvertedRecord()
const {
300 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
303mlir::StringAttr RecordType::getABIConvertedName()
const {
304 assert(!isABIConvertedRecord());
306 return StringAttr::get(getContext(),
307 abi_conversion_prefix +
getName().getValue());
310void RecordType::removeABIConversionNamePrefix() {
311 mlir::StringAttr recordName =
getName();
313 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
314 getImpl()->name = mlir::StringAttr::get(
315 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
316 recordName.getType());
319void RecordType::complete(ArrayRef<Type> members,
bool packed,
bool padded) {
321 if (mutate(members, packed, padded).failed())
322 llvm_unreachable(
"failed to complete record");
328Type RecordType::getLargestMember(const ::mlir::DataLayout &dataLayout)
const {
329 assert(isUnion() &&
"Only call getLargestMember on unions");
330 llvm::ArrayRef<Type> members = getMembers();
336 auto endIt = getPadded() ? std::prev(members.end()) : members.end();
337 if (endIt == members.begin())
339 return *std::max_element(members.begin(), endIt, [&](Type lhs, Type rhs) {
340 return dataLayout.getTypeABIAlignment(lhs) <
341 dataLayout.getTypeABIAlignment(rhs) ||
342 (dataLayout.getTypeABIAlignment(lhs) ==
343 dataLayout.getTypeABIAlignment(rhs) &&
344 dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
348mlir::Type RecordType::getPadding()
const {
351 llvm::ArrayRef<mlir::Type> members = getMembers();
354 return members.back();
357bool RecordType::isLayoutIdentical(
const RecordType &other) {
358 if (
getImpl() == other.getImpl())
361 if (getPacked() != other.getPacked())
364 return getMembers() == other.getMembers();
372PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
373 ::mlir::DataLayoutEntryListRef params)
const {
376 return llvm::TypeSize::getFixed(64);
380PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
381 ::mlir::DataLayoutEntryListRef params)
const {
388RecordType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
389 mlir::DataLayoutEntryListRef params)
const {
391 mlir::Type largest = getLargestMember(dataLayout);
393 return llvm::TypeSize::getFixed(0);
407 llvm::TypeSize size = dataLayout.getTypeSizeInBits(largest);
408 if (mlir::Type tailPad = getPadding())
409 size += dataLayout.getTypeSizeInBits(tailPad);
413 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
414 return llvm::TypeSize::getFixed(recordSize * 8);
418RecordType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
419 ::mlir::DataLayoutEntryListRef params)
const {
421 mlir::Type largest = getLargestMember(dataLayout);
424 return dataLayout.getTypeABIAlignment(largest);
430 return computeStructAlignment(dataLayout);
434RecordType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
435 assert(isComplete() &&
"Cannot get layout of incomplete records");
438 unsigned recordSize = 0;
441 for (mlir::Type ty : getMembers()) {
445 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
449 recordSize = llvm::alignTo(recordSize, tyAlign);
450 recordSize += dataLayout.getTypeSize(ty);
454 recordAlignment = std::max(tyAlign, recordAlignment);
459 recordSize = llvm::alignTo(recordSize, recordAlignment);
464RecordType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
465 assert(isComplete() &&
"Cannot get layout of incomplete records");
472 auto members = getMembers();
473 unsigned numMembers =
474 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
475 unsigned recordSize = 0;
476 for (
unsigned i = 0; i < numMembers; ++i) {
477 mlir::Type ty = members[i];
479 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
480 recordSize = llvm::alignTo(recordSize, tyAlign);
481 recordSize += dataLayout.getTypeSize(ty);
491RecordType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
492 assert(isComplete() &&
"Cannot get layout of incomplete records");
496 for (mlir::Type ty : getMembers())
498 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
500 return recordAlignment;
503uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
504 unsigned idx)
const {
505 assert(idx < getMembers().size() &&
"access not valid");
508 if (isUnion() || idx == 0)
511 assert(isComplete() &&
"Cannot get layout of incomplete records");
512 assert(idx < getNumElements());
513 llvm::ArrayRef<mlir::Type> members = getMembers();
518 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
520 const llvm::Align tyAlign =
521 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
524 offset = llvm::alignTo(offset, tyAlign);
527 offset += dataLayout.getTypeSize(ty);
532 const llvm::Align tyAlign = llvm::Align(
533 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
534 offset = llvm::alignTo(offset, tyAlign);
543Type IntType::parse(mlir::AsmParser &parser) {
544 mlir::MLIRContext *context = parser.getBuilder().getContext();
545 llvm::SMLoc loc = parser.getCurrentLocation();
549 if (parser.parseLess())
553 llvm::StringRef
sign;
554 if (parser.parseKeyword(&
sign))
558 else if (
sign ==
"u")
561 parser.emitError(loc,
"expected 's' or 'u'");
565 if (parser.parseComma())
569 if (parser.parseInteger(width))
571 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
572 parser.emitError(loc,
"expected integer width to be from ")
573 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
577 bool isBitInt =
false;
578 if (succeeded(parser.parseOptionalComma())) {
580 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
581 parser.emitError(loc,
"expected 'bitint'");
587 if (parser.parseGreater())
590 return IntType::get(context, width, isSigned, isBitInt);
593void IntType::print(mlir::AsmPrinter &printer)
const {
594 char sign = isSigned() ?
's' :
'u';
595 printer <<
'<' <<
sign <<
", " << getWidth();
597 printer <<
", bitint";
602IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
603 mlir::DataLayoutEntryListRef params)
const {
604 return llvm::TypeSize::getFixed(getWidth());
607uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
608 mlir::DataLayoutEntryListRef params)
const {
609 unsigned width = getWidth();
614 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
615 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
617 return (uint64_t)(width / 8);
621IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
622 unsigned width,
bool isSigned,
bool isBitInt) {
623 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
624 return emitError() <<
"IntType only supports widths from "
625 << IntType::minBitwidth() <<
" up to "
626 << IntType::maxBitwidth();
627 return mlir::success();
631 return width == 8 || width == 16 || width == 32 || width == 64;
638const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
639 return llvm::APFloat::IEEEsingle();
643SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
644 mlir::DataLayoutEntryListRef params)
const {
645 return llvm::TypeSize::getFixed(getWidth());
649SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
650 mlir::DataLayoutEntryListRef params)
const {
651 return (uint64_t)(getWidth() / 8);
654const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
655 return llvm::APFloat::IEEEdouble();
659DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
660 mlir::DataLayoutEntryListRef params)
const {
661 return llvm::TypeSize::getFixed(getWidth());
665DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
666 mlir::DataLayoutEntryListRef params)
const {
667 return (uint64_t)(getWidth() / 8);
670const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
671 return llvm::APFloat::IEEEhalf();
675FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
676 mlir::DataLayoutEntryListRef params)
const {
677 return llvm::TypeSize::getFixed(getWidth());
680uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
681 mlir::DataLayoutEntryListRef params)
const {
682 return (uint64_t)(getWidth() / 8);
685const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
686 return llvm::APFloat::BFloat();
690BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
691 mlir::DataLayoutEntryListRef params)
const {
692 return llvm::TypeSize::getFixed(getWidth());
695uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
696 mlir::DataLayoutEntryListRef params)
const {
697 return (uint64_t)(getWidth() / 8);
700const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
701 return llvm::APFloat::x87DoubleExtended();
705FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
706 mlir::DataLayoutEntryListRef params)
const {
708 return llvm::TypeSize::getFixed(128);
711uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
712 mlir::DataLayoutEntryListRef params)
const {
716const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
717 return llvm::APFloat::IEEEquad();
721FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
722 mlir::DataLayoutEntryListRef params)
const {
723 return llvm::TypeSize::getFixed(getWidth());
726uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
727 mlir::DataLayoutEntryListRef params)
const {
731const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
732 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
736LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
737 mlir::DataLayoutEntryListRef params)
const {
738 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
739 .getTypeSizeInBits(dataLayout, params);
743LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
744 mlir::DataLayoutEntryListRef params)
const {
745 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
746 .getABIAlignment(dataLayout, params);
754cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
755 mlir::DataLayoutEntryListRef params)
const {
761 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
765cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
766 mlir::DataLayoutEntryListRef params)
const {
772 return dataLayout.getTypeABIAlignment(getElementType());
775FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
776 assert(results.size() == 1 &&
"expected exactly one result type");
777 return get(llvm::to_vector(inputs), results[0], isVarArg());
781static mlir::ParseResult
785 return p.parseCommaSeparatedList(
786 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
788 return p.emitError(p.getCurrentLocation(),
789 "variadic `...` must be the last parameter");
790 if (succeeded(p.parseOptionalEllipsis())) {
795 if (failed(p.parseType(type)))
797 params.push_back(type);
803 mlir::ArrayRef<mlir::Type> params,
806 llvm::interleaveComma(params, p,
807 [&p](mlir::Type type) { p.printType(type); });
818mlir::Type FuncType::getReturnType()
const {
820 return cir::VoidType::get(getContext());
821 return getOptionalReturnType();
827llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
833 return getImpl()->optionalReturnType;
837bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
840FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
841 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
843 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
845 <<
"!cir.func cannot have an explicit 'void' return type";
846 return mlir::success();
858 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
859 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
860 return cir::RecordType::get(ctx, fields,
false,
861 false, cir::RecordType::Struct);
865MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
866 mlir::DataLayoutEntryListRef params)
const {
871MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
872 mlir::DataLayoutEntryListRef params)
const {
874 .getABIAlignment(dataLayout, params);
882BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
883 ::mlir::DataLayoutEntryListRef params)
const {
884 return llvm::TypeSize::getFixed(8);
888BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
889 ::mlir::DataLayoutEntryListRef params)
const {
898DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
899 ::mlir::DataLayoutEntryListRef params)
const {
902 return llvm::TypeSize::getFixed(64);
906DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
907 ::mlir::DataLayoutEntryListRef params)
const {
918VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
919 mlir::DataLayoutEntryListRef params)
const {
921 return llvm::TypeSize::getFixed(64);
924uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
925 mlir::DataLayoutEntryListRef params)
const {
935ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
936 ::mlir::DataLayoutEntryListRef params)
const {
937 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
941ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
942 ::mlir::DataLayoutEntryListRef params)
const {
943 return dataLayout.getTypeABIAlignment(getElementType());
950llvm::TypeSize cir::VectorType::getTypeSizeInBits(
951 const ::mlir::DataLayout &dataLayout,
952 ::mlir::DataLayoutEntryListRef params)
const {
953 return llvm::TypeSize::getFixed(
954 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
958cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
959 ::mlir::DataLayoutEntryListRef params)
const {
960 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
963mlir::LogicalResult cir::VectorType::verify(
964 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
965 mlir::Type elementType, uint64_t size,
bool scalable) {
967 return emitError() <<
"the number of vector elements must be non-zero";
971mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
973 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
974 mlir::Builder odsBuilder(odsParser.getContext());
975 mlir::FailureOr<::mlir::Type> elementType;
976 mlir::FailureOr<uint64_t> size;
977 bool isScalabe =
false;
980 if (odsParser.parseLess())
984 if (odsParser.parseOptionalLSquare().succeeded())
988 size = mlir::FieldParser<uint64_t>::parse(odsParser);
989 if (mlir::failed(size)) {
990 odsParser.emitError(odsParser.getCurrentLocation(),
991 "failed to parse CIR_VectorType parameter 'size' which "
992 "is to be a `uint64_t`");
998 if (isScalabe && odsParser.parseRSquare().failed()) {
999 odsParser.emitError(odsParser.getCurrentLocation(),
1000 "missing closing `]` for scalable dim size");
1005 if (odsParser.parseKeyword(
"x"))
1009 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
1010 if (mlir::failed(elementType)) {
1011 odsParser.emitError(odsParser.getCurrentLocation(),
1012 "failed to parse CIR_VectorType parameter "
1013 "'elementType' which is to be a `mlir::Type`");
1018 if (odsParser.parseGreater())
1020 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
1021 mlir::Type((*elementType)),
1025void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
1026 mlir::Builder odsBuilder(getContext());
1028 if (this->getIsScalable())
1031 odsPrinter.printStrippedAttrOrType(getSize());
1032 if (this->getIsScalable())
1034 odsPrinter <<
' ' <<
"x";
1036 odsPrinter.printStrippedAttrOrType(getElementType());
1045 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1046 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1053 case LangAS::Default:
1054 return LangAddressSpace::Default;
1055 case LangAS::opencl_global:
1056 return LangAddressSpace::OffloadGlobal;
1057 case LangAS::opencl_local:
1058 case LangAS::cuda_shared:
1061 return LangAddressSpace::OffloadLocal;
1062 case LangAS::cuda_device:
1063 return LangAddressSpace::OffloadGlobal;
1064 case LangAS::opencl_constant:
1065 case LangAS::cuda_constant:
1066 return LangAddressSpace::OffloadConstant;
1067 case LangAS::opencl_private:
1068 return LangAddressSpace::OffloadPrivate;
1069 case LangAS::opencl_generic:
1070 return LangAddressSpace::OffloadGeneric;
1071 case LangAS::opencl_global_device:
1072 case LangAS::opencl_global_host:
1073 case LangAS::sycl_global:
1074 case LangAS::sycl_global_device:
1075 case LangAS::sycl_global_host:
1076 case LangAS::sycl_local:
1077 case LangAS::sycl_private:
1078 case LangAS::ptr32_sptr:
1079 case LangAS::ptr32_uptr:
1081 case LangAS::hlsl_groupshared:
1082 case LangAS::wasm_funcref:
1083 llvm_unreachable(
"NYI");
1085 llvm_unreachable(
"unknown/unsupported clang language address space");
1091 mlir::ptr::MemorySpaceAttrInterface &attr) {
1093 llvm::SMLoc loc = p.getCurrentLocation();
1097 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1099 if (p.parseLParen())
1100 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1102 if (p.parseInteger(val))
1103 return p.emitError(loc,
"expected target address space value");
1105 if (p.parseRParen())
1106 return p.emitError(loc,
"expected ')'");
1108 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1109 return mlir::success();
1113 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1114 if (p.parseLParen())
1115 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1117 mlir::FailureOr<cir::LangAddressSpace> result =
1118 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1119 if (mlir::failed(result))
1120 return mlir::failure();
1122 if (p.parseRParen())
1123 return p.emitError(loc,
"expected ')'");
1125 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1126 return mlir::success();
1129 llvm::StringRef keyword;
1130 if (p.parseOptionalKeyword(&keyword).succeeded())
1131 return p.emitError(loc,
"unknown address space specifier '")
1132 << keyword <<
"'; expected 'target_address_space' or "
1133 <<
"'lang_address_space'";
1135 return mlir::success();
1139 mlir::ptr::MemorySpaceAttrInterface attr) {
1143 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1144 p <<
"lang_address_space("
1145 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1149 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1150 p <<
"target_address_space(" << target.getValue() <<
')';
1154 llvm_unreachable(
"unexpected address-space attribute kind");
1157mlir::OptionalParseResult
1159 mlir::ptr::MemorySpaceAttrInterface &attr) {
1161 mlir::SMLoc loc = p.getCurrentLocation();
1163 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1164 return mlir::success();
1168 mlir::ptr::MemorySpaceAttrInterface attr) {
1173 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1175 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1176 if (langAS.getValue() == cir::LangAddressSpace::Default)
1181mlir::ptr::MemorySpaceAttrInterface
1185 if (langAS == LangAS::Default)
1186 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1190 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1203 return expected == cirAS;
1210mlir::LogicalResult cir::PointerType::verify(
1211 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1212 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1215 return emitError() <<
"unsupported address space attribute; expected "
1216 "'target_address_space' or 'lang_address_space'";
1227void CIRDialect::registerTypes() {
1230#define GET_TYPEDEF_LIST
1231#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
Provides definitions for the various language-specific address spaces.
void printAddressSpaceValue(mlir::AsmPrinter &p, cir::LangAddressSpace addrSpace)
mlir::ParseResult parseAddressSpaceValue(mlir::AsmParser &p, cir::LangAddressSpace &addrSpace)
void printGlobalAddressSpaceValue(mlir::AsmPrinter &printer, cir::GlobalOp op, mlir::ptr::MemorySpaceAttrInterface attr)
mlir::OptionalParseResult parseGlobalAddressSpaceValue(mlir::AsmParser &p, mlir::ptr::MemorySpaceAttrInterface &attr)
void printAddressSpaceValue(mlir::AsmPrinter &printer, mlir::ptr::MemorySpaceAttrInterface attr)
mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p, cir::TargetAddressSpaceAttr &attr)
mlir::ParseResult parseAddressSpaceValue(mlir::AsmParser &p, mlir::ptr::MemorySpaceAttrInterface &attr)
static mlir::ParseResult parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector< mlir::Type > ¶ms, bool &isVarArg)
static mlir::Type getMethodLayoutType(mlir::MLIRContext *ctx)
static void printFuncTypeParams(mlir::AsmPrinter &p, mlir::ArrayRef< mlir::Type > params, bool isVarArg)
void printTargetAddressSpace(mlir::AsmPrinter &p, cir::TargetAddressSpaceAttr attr)
static Decl::Kind getKind(const Decl *D)
static LiveVariablesImpl & getImpl(void *x)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS)
bool isValidFundamentalIntWidth(unsigned width)
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
mlir::ptr::MemorySpaceAttrInterface normalizeDefaultAddressSpace(mlir::ptr::MemorySpaceAttrInterface addrSpace)
Normalize LangAddressSpace::Default to null (empty attribute).
bool isSized(mlir::Type ty)
Returns true if the type is a CIR sized type.
bool isSupportedCIRMemorySpaceAttr(mlir::ptr::MemorySpaceAttrInterface memorySpace)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
StringRef getName(const HeaderType T)
bool isTargetAddressSpace(LangAS AS)
unsigned toTargetAddressSpace(LangAS AS)
LangAS
Defines the address space values used by the address space qualifier of QualType.
float __ovld __cnfn sign(float)
Returns 1.0 if x > 0, -0.0 if x = -0.0, +0.0 if x = +0.0, or -1.0 if x < 0.
static bool unsizedTypes()
static bool dataLayoutPtrHandlingBasedOnLangAS()
static bool astRecordDeclAttr()