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 return dataLayout.getTypeABIAlignment(getLargestMember(dataLayout));
401 return computeStructAlignment(dataLayout);
405RecordType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
406 assert(isComplete() &&
"Cannot get layout of incomplete records");
409 unsigned recordSize = 0;
412 for (mlir::Type ty : getMembers()) {
416 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
420 recordSize = llvm::alignTo(recordSize, tyAlign);
421 recordSize += dataLayout.getTypeSize(ty);
425 recordAlignment = std::max(tyAlign, recordAlignment);
430 recordSize = llvm::alignTo(recordSize, recordAlignment);
435RecordType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
436 assert(isComplete() &&
"Cannot get layout of incomplete records");
443 auto members = getMembers();
444 unsigned numMembers =
445 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
446 unsigned recordSize = 0;
447 for (
unsigned i = 0; i < numMembers; ++i) {
448 mlir::Type ty = members[i];
450 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
451 recordSize = llvm::alignTo(recordSize, tyAlign);
452 recordSize += dataLayout.getTypeSize(ty);
462RecordType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
463 assert(isComplete() &&
"Cannot get layout of incomplete records");
467 for (mlir::Type ty : getMembers())
469 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
471 return recordAlignment;
474uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
475 unsigned idx)
const {
476 assert(idx < getMembers().size() &&
"access not valid");
479 if (isUnion() || idx == 0)
482 assert(isComplete() &&
"Cannot get layout of incomplete records");
483 assert(idx < getNumElements());
484 llvm::ArrayRef<mlir::Type> members = getMembers();
489 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
491 const llvm::Align tyAlign =
492 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
495 offset = llvm::alignTo(offset, tyAlign);
498 offset += dataLayout.getTypeSize(ty);
503 const llvm::Align tyAlign = llvm::Align(
504 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
505 offset = llvm::alignTo(offset, tyAlign);
514Type IntType::parse(mlir::AsmParser &parser) {
515 mlir::MLIRContext *context = parser.getBuilder().getContext();
516 llvm::SMLoc loc = parser.getCurrentLocation();
520 if (parser.parseLess())
524 llvm::StringRef
sign;
525 if (parser.parseKeyword(&
sign))
529 else if (
sign ==
"u")
532 parser.emitError(loc,
"expected 's' or 'u'");
536 if (parser.parseComma())
540 if (parser.parseInteger(width))
542 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
543 parser.emitError(loc,
"expected integer width to be from ")
544 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
548 bool isBitInt =
false;
549 if (succeeded(parser.parseOptionalComma())) {
551 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
552 parser.emitError(loc,
"expected 'bitint'");
558 if (parser.parseGreater())
561 return IntType::get(context, width, isSigned, isBitInt);
564void IntType::print(mlir::AsmPrinter &printer)
const {
565 char sign = isSigned() ?
's' :
'u';
566 printer <<
'<' <<
sign <<
", " << getWidth();
568 printer <<
", bitint";
573IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
574 mlir::DataLayoutEntryListRef params)
const {
575 return llvm::TypeSize::getFixed(getWidth());
578uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
579 mlir::DataLayoutEntryListRef params)
const {
580 unsigned width = getWidth();
585 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
586 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
588 return (uint64_t)(width / 8);
592IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
593 unsigned width,
bool isSigned,
bool isBitInt) {
594 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
595 return emitError() <<
"IntType only supports widths from "
596 << IntType::minBitwidth() <<
" up to "
597 << IntType::maxBitwidth();
598 return mlir::success();
602 return width == 8 || width == 16 || width == 32 || width == 64;
609const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
610 return llvm::APFloat::IEEEsingle();
614SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
615 mlir::DataLayoutEntryListRef params)
const {
616 return llvm::TypeSize::getFixed(getWidth());
620SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
621 mlir::DataLayoutEntryListRef params)
const {
622 return (uint64_t)(getWidth() / 8);
625const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
626 return llvm::APFloat::IEEEdouble();
630DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
631 mlir::DataLayoutEntryListRef params)
const {
632 return llvm::TypeSize::getFixed(getWidth());
636DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
637 mlir::DataLayoutEntryListRef params)
const {
638 return (uint64_t)(getWidth() / 8);
641const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
642 return llvm::APFloat::IEEEhalf();
646FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
647 mlir::DataLayoutEntryListRef params)
const {
648 return llvm::TypeSize::getFixed(getWidth());
651uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
652 mlir::DataLayoutEntryListRef params)
const {
653 return (uint64_t)(getWidth() / 8);
656const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
657 return llvm::APFloat::BFloat();
661BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
662 mlir::DataLayoutEntryListRef params)
const {
663 return llvm::TypeSize::getFixed(getWidth());
666uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
667 mlir::DataLayoutEntryListRef params)
const {
668 return (uint64_t)(getWidth() / 8);
671const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
672 return llvm::APFloat::x87DoubleExtended();
676FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
677 mlir::DataLayoutEntryListRef params)
const {
679 return llvm::TypeSize::getFixed(128);
682uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
683 mlir::DataLayoutEntryListRef params)
const {
687const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
688 return llvm::APFloat::IEEEquad();
692FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
693 mlir::DataLayoutEntryListRef params)
const {
694 return llvm::TypeSize::getFixed(getWidth());
697uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
698 mlir::DataLayoutEntryListRef params)
const {
702const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
703 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
707LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
708 mlir::DataLayoutEntryListRef params)
const {
709 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
710 .getTypeSizeInBits(dataLayout, params);
714LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
715 mlir::DataLayoutEntryListRef params)
const {
716 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
717 .getABIAlignment(dataLayout, params);
725cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
726 mlir::DataLayoutEntryListRef params)
const {
732 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
736cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
737 mlir::DataLayoutEntryListRef params)
const {
743 return dataLayout.getTypeABIAlignment(getElementType());
746FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
747 assert(results.size() == 1 &&
"expected exactly one result type");
748 return get(llvm::to_vector(inputs), results[0], isVarArg());
752static mlir::ParseResult
756 return p.parseCommaSeparatedList(
757 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
759 return p.emitError(p.getCurrentLocation(),
760 "variadic `...` must be the last parameter");
761 if (succeeded(p.parseOptionalEllipsis())) {
766 if (failed(p.parseType(type)))
768 params.push_back(type);
774 mlir::ArrayRef<mlir::Type> params,
777 llvm::interleaveComma(params, p,
778 [&p](mlir::Type type) { p.printType(type); });
789mlir::Type FuncType::getReturnType()
const {
791 return cir::VoidType::get(getContext());
792 return getOptionalReturnType();
798llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
804 return getImpl()->optionalReturnType;
808bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
811FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
812 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
814 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
816 <<
"!cir.func cannot have an explicit 'void' return type";
817 return mlir::success();
829 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
830 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
831 return cir::RecordType::get(ctx, fields,
false,
832 false, cir::RecordType::Struct);
836MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
837 mlir::DataLayoutEntryListRef params)
const {
842MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
843 mlir::DataLayoutEntryListRef params)
const {
845 .getABIAlignment(dataLayout, params);
853BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
854 ::mlir::DataLayoutEntryListRef params)
const {
855 return llvm::TypeSize::getFixed(8);
859BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
860 ::mlir::DataLayoutEntryListRef params)
const {
869DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
870 ::mlir::DataLayoutEntryListRef params)
const {
873 return llvm::TypeSize::getFixed(64);
877DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
878 ::mlir::DataLayoutEntryListRef params)
const {
889VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
890 mlir::DataLayoutEntryListRef params)
const {
892 return llvm::TypeSize::getFixed(64);
895uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
896 mlir::DataLayoutEntryListRef params)
const {
906ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
907 ::mlir::DataLayoutEntryListRef params)
const {
908 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
912ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
913 ::mlir::DataLayoutEntryListRef params)
const {
914 return dataLayout.getTypeABIAlignment(getElementType());
921llvm::TypeSize cir::VectorType::getTypeSizeInBits(
922 const ::mlir::DataLayout &dataLayout,
923 ::mlir::DataLayoutEntryListRef params)
const {
924 return llvm::TypeSize::getFixed(
925 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
929cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
930 ::mlir::DataLayoutEntryListRef params)
const {
931 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
934mlir::LogicalResult cir::VectorType::verify(
935 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
936 mlir::Type elementType, uint64_t size,
bool scalable) {
938 return emitError() <<
"the number of vector elements must be non-zero";
942mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
944 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
945 mlir::Builder odsBuilder(odsParser.getContext());
946 mlir::FailureOr<::mlir::Type> elementType;
947 mlir::FailureOr<uint64_t> size;
948 bool isScalabe =
false;
951 if (odsParser.parseLess())
955 if (odsParser.parseOptionalLSquare().succeeded())
959 size = mlir::FieldParser<uint64_t>::parse(odsParser);
960 if (mlir::failed(size)) {
961 odsParser.emitError(odsParser.getCurrentLocation(),
962 "failed to parse CIR_VectorType parameter 'size' which "
963 "is to be a `uint64_t`");
969 if (isScalabe && odsParser.parseRSquare().failed()) {
970 odsParser.emitError(odsParser.getCurrentLocation(),
971 "missing closing `]` for scalable dim size");
976 if (odsParser.parseKeyword(
"x"))
980 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
981 if (mlir::failed(elementType)) {
982 odsParser.emitError(odsParser.getCurrentLocation(),
983 "failed to parse CIR_VectorType parameter "
984 "'elementType' which is to be a `mlir::Type`");
989 if (odsParser.parseGreater())
991 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
992 mlir::Type((*elementType)),
996void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
997 mlir::Builder odsBuilder(getContext());
999 if (this->getIsScalable())
1002 odsPrinter.printStrippedAttrOrType(getSize());
1003 if (this->getIsScalable())
1005 odsPrinter <<
' ' <<
"x";
1007 odsPrinter.printStrippedAttrOrType(getElementType());
1016 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1017 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1024 case LangAS::Default:
1025 return LangAddressSpace::Default;
1026 case LangAS::opencl_global:
1027 return LangAddressSpace::OffloadGlobal;
1028 case LangAS::opencl_local:
1029 case LangAS::cuda_shared:
1032 return LangAddressSpace::OffloadLocal;
1033 case LangAS::cuda_device:
1034 return LangAddressSpace::OffloadGlobal;
1035 case LangAS::opencl_constant:
1036 case LangAS::cuda_constant:
1037 return LangAddressSpace::OffloadConstant;
1038 case LangAS::opencl_private:
1039 return LangAddressSpace::OffloadPrivate;
1040 case LangAS::opencl_generic:
1041 return LangAddressSpace::OffloadGeneric;
1042 case LangAS::opencl_global_device:
1043 case LangAS::opencl_global_host:
1044 case LangAS::sycl_global:
1045 case LangAS::sycl_global_device:
1046 case LangAS::sycl_global_host:
1047 case LangAS::sycl_local:
1048 case LangAS::sycl_private:
1049 case LangAS::ptr32_sptr:
1050 case LangAS::ptr32_uptr:
1052 case LangAS::hlsl_groupshared:
1053 case LangAS::wasm_funcref:
1054 llvm_unreachable(
"NYI");
1056 llvm_unreachable(
"unknown/unsupported clang language address space");
1062 mlir::ptr::MemorySpaceAttrInterface &attr) {
1064 llvm::SMLoc loc = p.getCurrentLocation();
1068 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1070 if (p.parseLParen())
1071 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1073 if (p.parseInteger(val))
1074 return p.emitError(loc,
"expected target address space value");
1076 if (p.parseRParen())
1077 return p.emitError(loc,
"expected ')'");
1079 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1080 return mlir::success();
1084 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1085 if (p.parseLParen())
1086 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1088 mlir::FailureOr<cir::LangAddressSpace> result =
1089 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1090 if (mlir::failed(result))
1091 return mlir::failure();
1093 if (p.parseRParen())
1094 return p.emitError(loc,
"expected ')'");
1096 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1097 return mlir::success();
1100 llvm::StringRef keyword;
1101 if (p.parseOptionalKeyword(&keyword).succeeded())
1102 return p.emitError(loc,
"unknown address space specifier '")
1103 << keyword <<
"'; expected 'target_address_space' or "
1104 <<
"'lang_address_space'";
1106 return mlir::success();
1110 mlir::ptr::MemorySpaceAttrInterface attr) {
1114 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1115 p <<
"lang_address_space("
1116 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1120 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1121 p <<
"target_address_space(" << target.getValue() <<
')';
1125 llvm_unreachable(
"unexpected address-space attribute kind");
1128mlir::OptionalParseResult
1130 mlir::ptr::MemorySpaceAttrInterface &attr) {
1132 mlir::SMLoc loc = p.getCurrentLocation();
1134 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1135 return mlir::success();
1139 mlir::ptr::MemorySpaceAttrInterface attr) {
1144 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1146 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1147 if (langAS.getValue() == cir::LangAddressSpace::Default)
1152mlir::ptr::MemorySpaceAttrInterface
1156 if (langAS == LangAS::Default)
1157 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1161 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1174 return expected == cirAS;
1181mlir::LogicalResult cir::PointerType::verify(
1182 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1183 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1186 return emitError() <<
"unsupported address space attribute; expected "
1187 "'target_address_space' or 'lang_address_space'";
1198void CIRDialect::registerTypes() {
1201#define GET_TYPEDEF_LIST
1202#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()