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));
348bool RecordType::isLayoutIdentical(
const RecordType &other) {
349 if (
getImpl() == other.getImpl())
352 if (getPacked() != other.getPacked())
355 return getMembers() == other.getMembers();
363PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
364 ::mlir::DataLayoutEntryListRef params)
const {
367 return llvm::TypeSize::getFixed(64);
371PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
372 ::mlir::DataLayoutEntryListRef params)
const {
379RecordType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
380 mlir::DataLayoutEntryListRef params)
const {
382 mlir::Type largest = getLargestMember(dataLayout);
384 return llvm::TypeSize::getFixed(0);
385 return dataLayout.getTypeSizeInBits(largest);
388 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
389 return llvm::TypeSize::getFixed(recordSize * 8);
393RecordType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
394 ::mlir::DataLayoutEntryListRef params)
const {
396 mlir::Type largest = getLargestMember(dataLayout);
399 return dataLayout.getTypeABIAlignment(largest);
405 return computeStructAlignment(dataLayout);
409RecordType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
410 assert(isComplete() &&
"Cannot get layout of incomplete records");
413 unsigned recordSize = 0;
416 for (mlir::Type ty : getMembers()) {
420 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
424 recordSize = llvm::alignTo(recordSize, tyAlign);
425 recordSize += dataLayout.getTypeSize(ty);
429 recordAlignment = std::max(tyAlign, recordAlignment);
434 recordSize = llvm::alignTo(recordSize, recordAlignment);
439RecordType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
440 assert(isComplete() &&
"Cannot get layout of incomplete records");
447 auto members = getMembers();
448 unsigned numMembers =
449 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
450 unsigned recordSize = 0;
451 for (
unsigned i = 0; i < numMembers; ++i) {
452 mlir::Type ty = members[i];
454 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
455 recordSize = llvm::alignTo(recordSize, tyAlign);
456 recordSize += dataLayout.getTypeSize(ty);
466RecordType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
467 assert(isComplete() &&
"Cannot get layout of incomplete records");
471 for (mlir::Type ty : getMembers())
473 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
475 return recordAlignment;
478uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
479 unsigned idx)
const {
480 assert(idx < getMembers().size() &&
"access not valid");
483 if (isUnion() || idx == 0)
486 assert(isComplete() &&
"Cannot get layout of incomplete records");
487 assert(idx < getNumElements());
488 llvm::ArrayRef<mlir::Type> members = getMembers();
493 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
495 const llvm::Align tyAlign =
496 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
499 offset = llvm::alignTo(offset, tyAlign);
502 offset += dataLayout.getTypeSize(ty);
507 const llvm::Align tyAlign = llvm::Align(
508 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
509 offset = llvm::alignTo(offset, tyAlign);
518Type IntType::parse(mlir::AsmParser &parser) {
519 mlir::MLIRContext *context = parser.getBuilder().getContext();
520 llvm::SMLoc loc = parser.getCurrentLocation();
524 if (parser.parseLess())
528 llvm::StringRef
sign;
529 if (parser.parseKeyword(&
sign))
533 else if (
sign ==
"u")
536 parser.emitError(loc,
"expected 's' or 'u'");
540 if (parser.parseComma())
544 if (parser.parseInteger(width))
546 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
547 parser.emitError(loc,
"expected integer width to be from ")
548 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
552 bool isBitInt =
false;
553 if (succeeded(parser.parseOptionalComma())) {
555 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
556 parser.emitError(loc,
"expected 'bitint'");
562 if (parser.parseGreater())
565 return IntType::get(context, width, isSigned, isBitInt);
568void IntType::print(mlir::AsmPrinter &printer)
const {
569 char sign = isSigned() ?
's' :
'u';
570 printer <<
'<' <<
sign <<
", " << getWidth();
572 printer <<
", bitint";
577IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
578 mlir::DataLayoutEntryListRef params)
const {
579 return llvm::TypeSize::getFixed(getWidth());
582uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
583 mlir::DataLayoutEntryListRef params)
const {
584 unsigned width = getWidth();
589 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
590 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
592 return (uint64_t)(width / 8);
596IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
597 unsigned width,
bool isSigned,
bool isBitInt) {
598 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
599 return emitError() <<
"IntType only supports widths from "
600 << IntType::minBitwidth() <<
" up to "
601 << IntType::maxBitwidth();
602 return mlir::success();
606 return width == 8 || width == 16 || width == 32 || width == 64;
613const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
614 return llvm::APFloat::IEEEsingle();
618SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
619 mlir::DataLayoutEntryListRef params)
const {
620 return llvm::TypeSize::getFixed(getWidth());
624SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
625 mlir::DataLayoutEntryListRef params)
const {
626 return (uint64_t)(getWidth() / 8);
629const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
630 return llvm::APFloat::IEEEdouble();
634DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
635 mlir::DataLayoutEntryListRef params)
const {
636 return llvm::TypeSize::getFixed(getWidth());
640DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
641 mlir::DataLayoutEntryListRef params)
const {
642 return (uint64_t)(getWidth() / 8);
645const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
646 return llvm::APFloat::IEEEhalf();
650FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
651 mlir::DataLayoutEntryListRef params)
const {
652 return llvm::TypeSize::getFixed(getWidth());
655uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
656 mlir::DataLayoutEntryListRef params)
const {
657 return (uint64_t)(getWidth() / 8);
660const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
661 return llvm::APFloat::BFloat();
665BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
666 mlir::DataLayoutEntryListRef params)
const {
667 return llvm::TypeSize::getFixed(getWidth());
670uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
671 mlir::DataLayoutEntryListRef params)
const {
672 return (uint64_t)(getWidth() / 8);
675const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
676 return llvm::APFloat::x87DoubleExtended();
680FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
681 mlir::DataLayoutEntryListRef params)
const {
683 return llvm::TypeSize::getFixed(128);
686uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
687 mlir::DataLayoutEntryListRef params)
const {
691const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
692 return llvm::APFloat::IEEEquad();
696FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
697 mlir::DataLayoutEntryListRef params)
const {
698 return llvm::TypeSize::getFixed(getWidth());
701uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
702 mlir::DataLayoutEntryListRef params)
const {
706const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
707 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
711LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
712 mlir::DataLayoutEntryListRef params)
const {
713 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
714 .getTypeSizeInBits(dataLayout, params);
718LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
719 mlir::DataLayoutEntryListRef params)
const {
720 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
721 .getABIAlignment(dataLayout, params);
729cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
730 mlir::DataLayoutEntryListRef params)
const {
736 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
740cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
741 mlir::DataLayoutEntryListRef params)
const {
747 return dataLayout.getTypeABIAlignment(getElementType());
750FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
751 assert(results.size() == 1 &&
"expected exactly one result type");
752 return get(llvm::to_vector(inputs), results[0], isVarArg());
756static mlir::ParseResult
760 return p.parseCommaSeparatedList(
761 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
763 return p.emitError(p.getCurrentLocation(),
764 "variadic `...` must be the last parameter");
765 if (succeeded(p.parseOptionalEllipsis())) {
770 if (failed(p.parseType(type)))
772 params.push_back(type);
778 mlir::ArrayRef<mlir::Type> params,
781 llvm::interleaveComma(params, p,
782 [&p](mlir::Type type) { p.printType(type); });
793mlir::Type FuncType::getReturnType()
const {
795 return cir::VoidType::get(getContext());
796 return getOptionalReturnType();
802llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
808 return getImpl()->optionalReturnType;
812bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
815FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
816 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
818 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
820 <<
"!cir.func cannot have an explicit 'void' return type";
821 return mlir::success();
833 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
834 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
835 return cir::RecordType::get(ctx, fields,
false,
836 false, cir::RecordType::Struct);
840MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
841 mlir::DataLayoutEntryListRef params)
const {
846MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
847 mlir::DataLayoutEntryListRef params)
const {
849 .getABIAlignment(dataLayout, params);
857BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
858 ::mlir::DataLayoutEntryListRef params)
const {
859 return llvm::TypeSize::getFixed(8);
863BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
864 ::mlir::DataLayoutEntryListRef params)
const {
873DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
874 ::mlir::DataLayoutEntryListRef params)
const {
877 return llvm::TypeSize::getFixed(64);
881DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
882 ::mlir::DataLayoutEntryListRef params)
const {
893VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
894 mlir::DataLayoutEntryListRef params)
const {
896 return llvm::TypeSize::getFixed(64);
899uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
900 mlir::DataLayoutEntryListRef params)
const {
910ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
911 ::mlir::DataLayoutEntryListRef params)
const {
912 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
916ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
917 ::mlir::DataLayoutEntryListRef params)
const {
918 return dataLayout.getTypeABIAlignment(getElementType());
925llvm::TypeSize cir::VectorType::getTypeSizeInBits(
926 const ::mlir::DataLayout &dataLayout,
927 ::mlir::DataLayoutEntryListRef params)
const {
928 return llvm::TypeSize::getFixed(
929 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
933cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
934 ::mlir::DataLayoutEntryListRef params)
const {
935 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
938mlir::LogicalResult cir::VectorType::verify(
939 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
940 mlir::Type elementType, uint64_t size,
bool scalable) {
942 return emitError() <<
"the number of vector elements must be non-zero";
946mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
948 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
949 mlir::Builder odsBuilder(odsParser.getContext());
950 mlir::FailureOr<::mlir::Type> elementType;
951 mlir::FailureOr<uint64_t> size;
952 bool isScalabe =
false;
955 if (odsParser.parseLess())
959 if (odsParser.parseOptionalLSquare().succeeded())
963 size = mlir::FieldParser<uint64_t>::parse(odsParser);
964 if (mlir::failed(size)) {
965 odsParser.emitError(odsParser.getCurrentLocation(),
966 "failed to parse CIR_VectorType parameter 'size' which "
967 "is to be a `uint64_t`");
973 if (isScalabe && odsParser.parseRSquare().failed()) {
974 odsParser.emitError(odsParser.getCurrentLocation(),
975 "missing closing `]` for scalable dim size");
980 if (odsParser.parseKeyword(
"x"))
984 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
985 if (mlir::failed(elementType)) {
986 odsParser.emitError(odsParser.getCurrentLocation(),
987 "failed to parse CIR_VectorType parameter "
988 "'elementType' which is to be a `mlir::Type`");
993 if (odsParser.parseGreater())
995 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
996 mlir::Type((*elementType)),
1000void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
1001 mlir::Builder odsBuilder(getContext());
1003 if (this->getIsScalable())
1006 odsPrinter.printStrippedAttrOrType(getSize());
1007 if (this->getIsScalable())
1009 odsPrinter <<
' ' <<
"x";
1011 odsPrinter.printStrippedAttrOrType(getElementType());
1020 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1021 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1028 case LangAS::Default:
1029 return LangAddressSpace::Default;
1030 case LangAS::opencl_global:
1031 return LangAddressSpace::OffloadGlobal;
1032 case LangAS::opencl_local:
1033 case LangAS::cuda_shared:
1036 return LangAddressSpace::OffloadLocal;
1037 case LangAS::cuda_device:
1038 return LangAddressSpace::OffloadGlobal;
1039 case LangAS::opencl_constant:
1040 case LangAS::cuda_constant:
1041 return LangAddressSpace::OffloadConstant;
1042 case LangAS::opencl_private:
1043 return LangAddressSpace::OffloadPrivate;
1044 case LangAS::opencl_generic:
1045 return LangAddressSpace::OffloadGeneric;
1046 case LangAS::opencl_global_device:
1047 case LangAS::opencl_global_host:
1048 case LangAS::sycl_global:
1049 case LangAS::sycl_global_device:
1050 case LangAS::sycl_global_host:
1051 case LangAS::sycl_local:
1052 case LangAS::sycl_private:
1053 case LangAS::ptr32_sptr:
1054 case LangAS::ptr32_uptr:
1056 case LangAS::hlsl_groupshared:
1057 case LangAS::wasm_funcref:
1058 llvm_unreachable(
"NYI");
1060 llvm_unreachable(
"unknown/unsupported clang language address space");
1066 mlir::ptr::MemorySpaceAttrInterface &attr) {
1068 llvm::SMLoc loc = p.getCurrentLocation();
1072 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1074 if (p.parseLParen())
1075 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1077 if (p.parseInteger(val))
1078 return p.emitError(loc,
"expected target address space value");
1080 if (p.parseRParen())
1081 return p.emitError(loc,
"expected ')'");
1083 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1084 return mlir::success();
1088 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1089 if (p.parseLParen())
1090 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1092 mlir::FailureOr<cir::LangAddressSpace> result =
1093 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1094 if (mlir::failed(result))
1095 return mlir::failure();
1097 if (p.parseRParen())
1098 return p.emitError(loc,
"expected ')'");
1100 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1101 return mlir::success();
1104 llvm::StringRef keyword;
1105 if (p.parseOptionalKeyword(&keyword).succeeded())
1106 return p.emitError(loc,
"unknown address space specifier '")
1107 << keyword <<
"'; expected 'target_address_space' or "
1108 <<
"'lang_address_space'";
1110 return mlir::success();
1114 mlir::ptr::MemorySpaceAttrInterface attr) {
1118 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1119 p <<
"lang_address_space("
1120 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1124 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1125 p <<
"target_address_space(" << target.getValue() <<
')';
1129 llvm_unreachable(
"unexpected address-space attribute kind");
1132mlir::OptionalParseResult
1134 mlir::ptr::MemorySpaceAttrInterface &attr) {
1136 mlir::SMLoc loc = p.getCurrentLocation();
1138 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1139 return mlir::success();
1143 mlir::ptr::MemorySpaceAttrInterface attr) {
1148 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1150 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1151 if (langAS.getValue() == cir::LangAddressSpace::Default)
1156mlir::ptr::MemorySpaceAttrInterface
1160 if (langAS == LangAS::Default)
1161 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1165 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1178 return expected == cirAS;
1185mlir::LogicalResult cir::PointerType::verify(
1186 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1187 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1190 return emitError() <<
"unsupported address space attribute; expected "
1191 "'target_address_space' or 'lang_address_space'";
1202void CIRDialect::registerTypes() {
1205#define GET_TYPEDEF_LIST
1206#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()