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(
340 members.begin(), endIt, [&](Type lhs, Type rhs) {
341 return dataLayout.getTypeABIAlignment(lhs) <
342 dataLayout.getTypeABIAlignment(rhs) ||
343 (dataLayout.getTypeABIAlignment(lhs) ==
344 dataLayout.getTypeABIAlignment(rhs) &&
345 dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
349bool RecordType::isLayoutIdentical(
const RecordType &other) {
350 if (
getImpl() == other.getImpl())
353 if (getPacked() != other.getPacked())
356 return getMembers() == other.getMembers();
364PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
365 ::mlir::DataLayoutEntryListRef params)
const {
368 return llvm::TypeSize::getFixed(64);
372PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
373 ::mlir::DataLayoutEntryListRef params)
const {
380RecordType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
381 mlir::DataLayoutEntryListRef params)
const {
383 return dataLayout.getTypeSize(getLargestMember(dataLayout));
385 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
386 return llvm::TypeSize::getFixed(recordSize * 8);
390RecordType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
391 ::mlir::DataLayoutEntryListRef params)
const {
393 return dataLayout.getTypeABIAlignment(getLargestMember(dataLayout));
398 return computeStructAlignment(dataLayout);
402RecordType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
403 assert(isComplete() &&
"Cannot get layout of incomplete records");
406 unsigned recordSize = 0;
409 for (mlir::Type ty : getMembers()) {
413 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
417 recordSize = llvm::alignTo(recordSize, tyAlign);
418 recordSize += dataLayout.getTypeSize(ty);
422 recordAlignment = std::max(tyAlign, recordAlignment);
427 recordSize = llvm::alignTo(recordSize, recordAlignment);
432RecordType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
433 assert(isComplete() &&
"Cannot get layout of incomplete records");
440 auto members = getMembers();
441 unsigned numMembers =
442 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
443 unsigned recordSize = 0;
444 for (
unsigned i = 0; i < numMembers; ++i) {
445 mlir::Type ty = members[i];
447 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
448 recordSize = llvm::alignTo(recordSize, tyAlign);
449 recordSize += dataLayout.getTypeSize(ty);
459RecordType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
460 assert(isComplete() &&
"Cannot get layout of incomplete records");
464 for (mlir::Type ty : getMembers())
466 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
468 return recordAlignment;
471uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
472 unsigned idx)
const {
473 assert(idx < getMembers().size() &&
"access not valid");
476 if (isUnion() || idx == 0)
479 assert(isComplete() &&
"Cannot get layout of incomplete records");
480 assert(idx < getNumElements());
481 llvm::ArrayRef<mlir::Type> members = getMembers();
486 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
488 const llvm::Align tyAlign =
489 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
492 offset = llvm::alignTo(offset, tyAlign);
495 offset += dataLayout.getTypeSize(ty);
500 const llvm::Align tyAlign = llvm::Align(
501 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
502 offset = llvm::alignTo(offset, tyAlign);
511Type IntType::parse(mlir::AsmParser &parser) {
512 mlir::MLIRContext *context = parser.getBuilder().getContext();
513 llvm::SMLoc loc = parser.getCurrentLocation();
517 if (parser.parseLess())
521 llvm::StringRef
sign;
522 if (parser.parseKeyword(&
sign))
526 else if (
sign ==
"u")
529 parser.emitError(loc,
"expected 's' or 'u'");
533 if (parser.parseComma())
537 if (parser.parseInteger(width))
539 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
540 parser.emitError(loc,
"expected integer width to be from ")
541 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
545 bool isBitInt =
false;
546 if (succeeded(parser.parseOptionalComma())) {
548 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
549 parser.emitError(loc,
"expected 'bitint'");
555 if (parser.parseGreater())
558 return IntType::get(context, width, isSigned, isBitInt);
561void IntType::print(mlir::AsmPrinter &printer)
const {
562 char sign = isSigned() ?
's' :
'u';
563 printer <<
'<' <<
sign <<
", " << getWidth();
565 printer <<
", bitint";
570IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
571 mlir::DataLayoutEntryListRef params)
const {
572 return llvm::TypeSize::getFixed(getWidth());
575uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
576 mlir::DataLayoutEntryListRef params)
const {
577 unsigned width = getWidth();
582 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
583 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
585 return (uint64_t)(width / 8);
589IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
590 unsigned width,
bool isSigned,
bool isBitInt) {
591 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
592 return emitError() <<
"IntType only supports widths from "
593 << IntType::minBitwidth() <<
" up to "
594 << IntType::maxBitwidth();
595 return mlir::success();
599 return width == 8 || width == 16 || width == 32 || width == 64;
606const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
607 return llvm::APFloat::IEEEsingle();
611SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
612 mlir::DataLayoutEntryListRef params)
const {
613 return llvm::TypeSize::getFixed(getWidth());
617SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
618 mlir::DataLayoutEntryListRef params)
const {
619 return (uint64_t)(getWidth() / 8);
622const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
623 return llvm::APFloat::IEEEdouble();
627DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
628 mlir::DataLayoutEntryListRef params)
const {
629 return llvm::TypeSize::getFixed(getWidth());
633DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
634 mlir::DataLayoutEntryListRef params)
const {
635 return (uint64_t)(getWidth() / 8);
638const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
639 return llvm::APFloat::IEEEhalf();
643FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
644 mlir::DataLayoutEntryListRef params)
const {
645 return llvm::TypeSize::getFixed(getWidth());
648uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
649 mlir::DataLayoutEntryListRef params)
const {
650 return (uint64_t)(getWidth() / 8);
653const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
654 return llvm::APFloat::BFloat();
658BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
659 mlir::DataLayoutEntryListRef params)
const {
660 return llvm::TypeSize::getFixed(getWidth());
663uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
664 mlir::DataLayoutEntryListRef params)
const {
665 return (uint64_t)(getWidth() / 8);
668const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
669 return llvm::APFloat::x87DoubleExtended();
673FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
674 mlir::DataLayoutEntryListRef params)
const {
676 return llvm::TypeSize::getFixed(128);
679uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
680 mlir::DataLayoutEntryListRef params)
const {
684const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
685 return llvm::APFloat::IEEEquad();
689FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
690 mlir::DataLayoutEntryListRef params)
const {
691 return llvm::TypeSize::getFixed(getWidth());
694uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
695 mlir::DataLayoutEntryListRef params)
const {
699const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
700 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
704LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
705 mlir::DataLayoutEntryListRef params)
const {
706 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
707 .getTypeSizeInBits(dataLayout, params);
711LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
712 mlir::DataLayoutEntryListRef params)
const {
713 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
714 .getABIAlignment(dataLayout, params);
722cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
723 mlir::DataLayoutEntryListRef params)
const {
729 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
733cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
734 mlir::DataLayoutEntryListRef params)
const {
740 return dataLayout.getTypeABIAlignment(getElementType());
743FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
744 assert(results.size() == 1 &&
"expected exactly one result type");
745 return get(llvm::to_vector(inputs), results[0], isVarArg());
749static mlir::ParseResult
753 return p.parseCommaSeparatedList(
754 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
756 return p.emitError(p.getCurrentLocation(),
757 "variadic `...` must be the last parameter");
758 if (succeeded(p.parseOptionalEllipsis())) {
763 if (failed(p.parseType(type)))
765 params.push_back(type);
771 mlir::ArrayRef<mlir::Type> params,
774 llvm::interleaveComma(params, p,
775 [&p](mlir::Type type) { p.printType(type); });
786mlir::Type FuncType::getReturnType()
const {
788 return cir::VoidType::get(getContext());
789 return getOptionalReturnType();
795llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
801 return getImpl()->optionalReturnType;
805bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
808FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
809 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
811 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
813 <<
"!cir.func cannot have an explicit 'void' return type";
814 return mlir::success();
826 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
827 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
828 return cir::RecordType::get(ctx, fields,
false,
829 false, cir::RecordType::Struct);
833MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
834 mlir::DataLayoutEntryListRef params)
const {
839MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
840 mlir::DataLayoutEntryListRef params)
const {
842 .getABIAlignment(dataLayout, params);
850BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
851 ::mlir::DataLayoutEntryListRef params)
const {
852 return llvm::TypeSize::getFixed(8);
856BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
857 ::mlir::DataLayoutEntryListRef params)
const {
866DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
867 ::mlir::DataLayoutEntryListRef params)
const {
870 return llvm::TypeSize::getFixed(64);
874DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
875 ::mlir::DataLayoutEntryListRef params)
const {
886VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
887 mlir::DataLayoutEntryListRef params)
const {
889 return llvm::TypeSize::getFixed(64);
892uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
893 mlir::DataLayoutEntryListRef params)
const {
903ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
904 ::mlir::DataLayoutEntryListRef params)
const {
905 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
909ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
910 ::mlir::DataLayoutEntryListRef params)
const {
911 return dataLayout.getTypeABIAlignment(getElementType());
918llvm::TypeSize cir::VectorType::getTypeSizeInBits(
919 const ::mlir::DataLayout &dataLayout,
920 ::mlir::DataLayoutEntryListRef params)
const {
921 return llvm::TypeSize::getFixed(
922 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
926cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
927 ::mlir::DataLayoutEntryListRef params)
const {
928 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
931mlir::LogicalResult cir::VectorType::verify(
932 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
933 mlir::Type elementType, uint64_t size,
bool scalable) {
935 return emitError() <<
"the number of vector elements must be non-zero";
939mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
941 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
942 mlir::Builder odsBuilder(odsParser.getContext());
943 mlir::FailureOr<::mlir::Type> elementType;
944 mlir::FailureOr<uint64_t> size;
945 bool isScalabe =
false;
948 if (odsParser.parseLess())
952 if (odsParser.parseOptionalLSquare().succeeded())
956 size = mlir::FieldParser<uint64_t>::parse(odsParser);
957 if (mlir::failed(size)) {
958 odsParser.emitError(odsParser.getCurrentLocation(),
959 "failed to parse CIR_VectorType parameter 'size' which "
960 "is to be a `uint64_t`");
966 if (isScalabe && odsParser.parseRSquare().failed()) {
967 odsParser.emitError(odsParser.getCurrentLocation(),
968 "missing closing `]` for scalable dim size");
973 if (odsParser.parseKeyword(
"x"))
977 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
978 if (mlir::failed(elementType)) {
979 odsParser.emitError(odsParser.getCurrentLocation(),
980 "failed to parse CIR_VectorType parameter "
981 "'elementType' which is to be a `mlir::Type`");
986 if (odsParser.parseGreater())
988 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
989 mlir::Type((*elementType)),
993void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
994 mlir::Builder odsBuilder(getContext());
996 if (this->getIsScalable())
999 odsPrinter.printStrippedAttrOrType(getSize());
1000 if (this->getIsScalable())
1002 odsPrinter <<
' ' <<
"x";
1004 odsPrinter.printStrippedAttrOrType(getElementType());
1013 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1014 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1021 case LangAS::Default:
1022 return LangAddressSpace::Default;
1023 case LangAS::opencl_global:
1024 return LangAddressSpace::OffloadGlobal;
1025 case LangAS::opencl_local:
1026 case LangAS::cuda_shared:
1029 return LangAddressSpace::OffloadLocal;
1030 case LangAS::cuda_device:
1031 return LangAddressSpace::OffloadGlobal;
1032 case LangAS::opencl_constant:
1033 case LangAS::cuda_constant:
1034 return LangAddressSpace::OffloadConstant;
1035 case LangAS::opencl_private:
1036 return LangAddressSpace::OffloadPrivate;
1037 case LangAS::opencl_generic:
1038 return LangAddressSpace::OffloadGeneric;
1039 case LangAS::opencl_global_device:
1040 case LangAS::opencl_global_host:
1041 case LangAS::sycl_global:
1042 case LangAS::sycl_global_device:
1043 case LangAS::sycl_global_host:
1044 case LangAS::sycl_local:
1045 case LangAS::sycl_private:
1046 case LangAS::ptr32_sptr:
1047 case LangAS::ptr32_uptr:
1049 case LangAS::hlsl_groupshared:
1050 case LangAS::wasm_funcref:
1051 llvm_unreachable(
"NYI");
1053 llvm_unreachable(
"unknown/unsupported clang language address space");
1059 mlir::ptr::MemorySpaceAttrInterface &attr) {
1061 llvm::SMLoc loc = p.getCurrentLocation();
1065 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1067 if (p.parseLParen())
1068 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1070 if (p.parseInteger(val))
1071 return p.emitError(loc,
"expected target address space value");
1073 if (p.parseRParen())
1074 return p.emitError(loc,
"expected ')'");
1076 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1077 return mlir::success();
1081 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1082 if (p.parseLParen())
1083 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1085 mlir::FailureOr<cir::LangAddressSpace> result =
1086 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1087 if (mlir::failed(result))
1088 return mlir::failure();
1090 if (p.parseRParen())
1091 return p.emitError(loc,
"expected ')'");
1093 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1094 return mlir::success();
1097 llvm::StringRef keyword;
1098 if (p.parseOptionalKeyword(&keyword).succeeded())
1099 return p.emitError(loc,
"unknown address space specifier '")
1100 << keyword <<
"'; expected 'target_address_space' or "
1101 <<
"'lang_address_space'";
1103 return mlir::success();
1107 mlir::ptr::MemorySpaceAttrInterface attr) {
1111 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1112 p <<
"lang_address_space("
1113 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1117 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1118 p <<
"target_address_space(" << target.getValue() <<
')';
1122 llvm_unreachable(
"unexpected address-space attribute kind");
1125mlir::OptionalParseResult
1127 mlir::ptr::MemorySpaceAttrInterface &attr) {
1129 mlir::SMLoc loc = p.getCurrentLocation();
1131 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1132 return mlir::success();
1136 mlir::ptr::MemorySpaceAttrInterface attr) {
1141 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1143 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1144 if (langAS.getValue() == cir::LangAddressSpace::Default)
1149mlir::ptr::MemorySpaceAttrInterface
1153 if (langAS == LangAS::Default)
1154 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1158 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1171 return expected == cirAS;
1178mlir::LogicalResult cir::PointerType::verify(
1179 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1180 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1183 return emitError() <<
"unsupported address space attribute; expected "
1184 "'target_address_space' or 'lang_address_space'";
1195void CIRDialect::registerTypes() {
1198#define GET_TYPEDEF_LIST
1199#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()