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 return dataLayout.getTypeSize(getLargestMember(dataLayout));
384 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
385 return llvm::TypeSize::getFixed(recordSize * 8);
389RecordType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
390 ::mlir::DataLayoutEntryListRef params)
const {
392 return dataLayout.getTypeABIAlignment(getLargestMember(dataLayout));
397 return computeStructAlignment(dataLayout);
401RecordType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
402 assert(isComplete() &&
"Cannot get layout of incomplete records");
405 unsigned recordSize = 0;
408 for (mlir::Type ty : getMembers()) {
412 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
416 recordSize = llvm::alignTo(recordSize, tyAlign);
417 recordSize += dataLayout.getTypeSize(ty);
421 recordAlignment = std::max(tyAlign, recordAlignment);
426 recordSize = llvm::alignTo(recordSize, recordAlignment);
431RecordType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
432 assert(isComplete() &&
"Cannot get layout of incomplete records");
439 auto members = getMembers();
440 unsigned numMembers =
441 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
442 unsigned recordSize = 0;
443 for (
unsigned i = 0; i < numMembers; ++i) {
444 mlir::Type ty = members[i];
446 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
447 recordSize = llvm::alignTo(recordSize, tyAlign);
448 recordSize += dataLayout.getTypeSize(ty);
458RecordType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
459 assert(isComplete() &&
"Cannot get layout of incomplete records");
463 for (mlir::Type ty : getMembers())
465 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
467 return recordAlignment;
470uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
471 unsigned idx)
const {
472 assert(idx < getMembers().size() &&
"access not valid");
475 if (isUnion() || idx == 0)
478 assert(isComplete() &&
"Cannot get layout of incomplete records");
479 assert(idx < getNumElements());
480 llvm::ArrayRef<mlir::Type> members = getMembers();
485 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
487 const llvm::Align tyAlign =
488 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
491 offset = llvm::alignTo(offset, tyAlign);
494 offset += dataLayout.getTypeSize(ty);
499 const llvm::Align tyAlign = llvm::Align(
500 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
501 offset = llvm::alignTo(offset, tyAlign);
510Type IntType::parse(mlir::AsmParser &parser) {
511 mlir::MLIRContext *context = parser.getBuilder().getContext();
512 llvm::SMLoc loc = parser.getCurrentLocation();
516 if (parser.parseLess())
520 llvm::StringRef
sign;
521 if (parser.parseKeyword(&
sign))
525 else if (
sign ==
"u")
528 parser.emitError(loc,
"expected 's' or 'u'");
532 if (parser.parseComma())
536 if (parser.parseInteger(width))
538 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
539 parser.emitError(loc,
"expected integer width to be from ")
540 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
544 bool isBitInt =
false;
545 if (succeeded(parser.parseOptionalComma())) {
547 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
548 parser.emitError(loc,
"expected 'bitint'");
554 if (parser.parseGreater())
557 return IntType::get(context, width, isSigned, isBitInt);
560void IntType::print(mlir::AsmPrinter &printer)
const {
561 char sign = isSigned() ?
's' :
'u';
562 printer <<
'<' <<
sign <<
", " << getWidth();
564 printer <<
", bitint";
569IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
570 mlir::DataLayoutEntryListRef params)
const {
571 return llvm::TypeSize::getFixed(getWidth());
574uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
575 mlir::DataLayoutEntryListRef params)
const {
576 unsigned width = getWidth();
581 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
582 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
584 return (uint64_t)(width / 8);
588IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
589 unsigned width,
bool isSigned,
bool isBitInt) {
590 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
591 return emitError() <<
"IntType only supports widths from "
592 << IntType::minBitwidth() <<
" up to "
593 << IntType::maxBitwidth();
594 return mlir::success();
598 return width == 8 || width == 16 || width == 32 || width == 64;
605const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
606 return llvm::APFloat::IEEEsingle();
610SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
611 mlir::DataLayoutEntryListRef params)
const {
612 return llvm::TypeSize::getFixed(getWidth());
616SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
617 mlir::DataLayoutEntryListRef params)
const {
618 return (uint64_t)(getWidth() / 8);
621const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
622 return llvm::APFloat::IEEEdouble();
626DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
627 mlir::DataLayoutEntryListRef params)
const {
628 return llvm::TypeSize::getFixed(getWidth());
632DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
633 mlir::DataLayoutEntryListRef params)
const {
634 return (uint64_t)(getWidth() / 8);
637const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
638 return llvm::APFloat::IEEEhalf();
642FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
643 mlir::DataLayoutEntryListRef params)
const {
644 return llvm::TypeSize::getFixed(getWidth());
647uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
648 mlir::DataLayoutEntryListRef params)
const {
649 return (uint64_t)(getWidth() / 8);
652const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
653 return llvm::APFloat::BFloat();
657BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
658 mlir::DataLayoutEntryListRef params)
const {
659 return llvm::TypeSize::getFixed(getWidth());
662uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
663 mlir::DataLayoutEntryListRef params)
const {
664 return (uint64_t)(getWidth() / 8);
667const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
668 return llvm::APFloat::x87DoubleExtended();
672FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
673 mlir::DataLayoutEntryListRef params)
const {
675 return llvm::TypeSize::getFixed(128);
678uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
679 mlir::DataLayoutEntryListRef params)
const {
683const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
684 return llvm::APFloat::IEEEquad();
688FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
689 mlir::DataLayoutEntryListRef params)
const {
690 return llvm::TypeSize::getFixed(getWidth());
693uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
694 mlir::DataLayoutEntryListRef params)
const {
698const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
699 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
703LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
704 mlir::DataLayoutEntryListRef params)
const {
705 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
706 .getTypeSizeInBits(dataLayout, params);
710LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
711 mlir::DataLayoutEntryListRef params)
const {
712 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
713 .getABIAlignment(dataLayout, params);
721cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
722 mlir::DataLayoutEntryListRef params)
const {
728 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
732cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
733 mlir::DataLayoutEntryListRef params)
const {
739 return dataLayout.getTypeABIAlignment(getElementType());
742FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
743 assert(results.size() == 1 &&
"expected exactly one result type");
744 return get(llvm::to_vector(inputs), results[0], isVarArg());
748static mlir::ParseResult
752 return p.parseCommaSeparatedList(
753 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
755 return p.emitError(p.getCurrentLocation(),
756 "variadic `...` must be the last parameter");
757 if (succeeded(p.parseOptionalEllipsis())) {
762 if (failed(p.parseType(type)))
764 params.push_back(type);
770 mlir::ArrayRef<mlir::Type> params,
773 llvm::interleaveComma(params, p,
774 [&p](mlir::Type type) { p.printType(type); });
785mlir::Type FuncType::getReturnType()
const {
787 return cir::VoidType::get(getContext());
788 return getOptionalReturnType();
794llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
800 return getImpl()->optionalReturnType;
804bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
807FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
808 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
810 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
812 <<
"!cir.func cannot have an explicit 'void' return type";
813 return mlir::success();
825 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
826 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
827 return cir::RecordType::get(ctx, fields,
false,
828 false, cir::RecordType::Struct);
832MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
833 mlir::DataLayoutEntryListRef params)
const {
838MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
839 mlir::DataLayoutEntryListRef params)
const {
841 .getABIAlignment(dataLayout, params);
849BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
850 ::mlir::DataLayoutEntryListRef params)
const {
851 return llvm::TypeSize::getFixed(8);
855BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
856 ::mlir::DataLayoutEntryListRef params)
const {
865DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
866 ::mlir::DataLayoutEntryListRef params)
const {
869 return llvm::TypeSize::getFixed(64);
873DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
874 ::mlir::DataLayoutEntryListRef params)
const {
885VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
886 mlir::DataLayoutEntryListRef params)
const {
888 return llvm::TypeSize::getFixed(64);
891uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
892 mlir::DataLayoutEntryListRef params)
const {
902ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
903 ::mlir::DataLayoutEntryListRef params)
const {
904 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
908ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
909 ::mlir::DataLayoutEntryListRef params)
const {
910 return dataLayout.getTypeABIAlignment(getElementType());
917llvm::TypeSize cir::VectorType::getTypeSizeInBits(
918 const ::mlir::DataLayout &dataLayout,
919 ::mlir::DataLayoutEntryListRef params)
const {
920 return llvm::TypeSize::getFixed(
921 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
925cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
926 ::mlir::DataLayoutEntryListRef params)
const {
927 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
930mlir::LogicalResult cir::VectorType::verify(
931 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
932 mlir::Type elementType, uint64_t size,
bool scalable) {
934 return emitError() <<
"the number of vector elements must be non-zero";
938mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
940 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
941 mlir::Builder odsBuilder(odsParser.getContext());
942 mlir::FailureOr<::mlir::Type> elementType;
943 mlir::FailureOr<uint64_t> size;
944 bool isScalabe =
false;
947 if (odsParser.parseLess())
951 if (odsParser.parseOptionalLSquare().succeeded())
955 size = mlir::FieldParser<uint64_t>::parse(odsParser);
956 if (mlir::failed(size)) {
957 odsParser.emitError(odsParser.getCurrentLocation(),
958 "failed to parse CIR_VectorType parameter 'size' which "
959 "is to be a `uint64_t`");
965 if (isScalabe && odsParser.parseRSquare().failed()) {
966 odsParser.emitError(odsParser.getCurrentLocation(),
967 "missing closing `]` for scalable dim size");
972 if (odsParser.parseKeyword(
"x"))
976 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
977 if (mlir::failed(elementType)) {
978 odsParser.emitError(odsParser.getCurrentLocation(),
979 "failed to parse CIR_VectorType parameter "
980 "'elementType' which is to be a `mlir::Type`");
985 if (odsParser.parseGreater())
987 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
988 mlir::Type((*elementType)),
992void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
993 mlir::Builder odsBuilder(getContext());
995 if (this->getIsScalable())
998 odsPrinter.printStrippedAttrOrType(getSize());
999 if (this->getIsScalable())
1001 odsPrinter <<
' ' <<
"x";
1003 odsPrinter.printStrippedAttrOrType(getElementType());
1012 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1013 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1020 case LangAS::Default:
1021 return LangAddressSpace::Default;
1022 case LangAS::opencl_global:
1023 return LangAddressSpace::OffloadGlobal;
1024 case LangAS::opencl_local:
1025 case LangAS::cuda_shared:
1028 return LangAddressSpace::OffloadLocal;
1029 case LangAS::cuda_device:
1030 return LangAddressSpace::OffloadGlobal;
1031 case LangAS::opencl_constant:
1032 case LangAS::cuda_constant:
1033 return LangAddressSpace::OffloadConstant;
1034 case LangAS::opencl_private:
1035 return LangAddressSpace::OffloadPrivate;
1036 case LangAS::opencl_generic:
1037 return LangAddressSpace::OffloadGeneric;
1038 case LangAS::opencl_global_device:
1039 case LangAS::opencl_global_host:
1040 case LangAS::sycl_global:
1041 case LangAS::sycl_global_device:
1042 case LangAS::sycl_global_host:
1043 case LangAS::sycl_local:
1044 case LangAS::sycl_private:
1045 case LangAS::ptr32_sptr:
1046 case LangAS::ptr32_uptr:
1048 case LangAS::hlsl_groupshared:
1049 case LangAS::wasm_funcref:
1050 llvm_unreachable(
"NYI");
1052 llvm_unreachable(
"unknown/unsupported clang language address space");
1058 mlir::ptr::MemorySpaceAttrInterface &attr) {
1060 llvm::SMLoc loc = p.getCurrentLocation();
1064 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1066 if (p.parseLParen())
1067 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1069 if (p.parseInteger(val))
1070 return p.emitError(loc,
"expected target address space value");
1072 if (p.parseRParen())
1073 return p.emitError(loc,
"expected ')'");
1075 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1076 return mlir::success();
1080 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1081 if (p.parseLParen())
1082 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1084 mlir::FailureOr<cir::LangAddressSpace> result =
1085 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1086 if (mlir::failed(result))
1087 return mlir::failure();
1089 if (p.parseRParen())
1090 return p.emitError(loc,
"expected ')'");
1092 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1093 return mlir::success();
1096 llvm::StringRef keyword;
1097 if (p.parseOptionalKeyword(&keyword).succeeded())
1098 return p.emitError(loc,
"unknown address space specifier '")
1099 << keyword <<
"'; expected 'target_address_space' or "
1100 <<
"'lang_address_space'";
1102 return mlir::success();
1106 mlir::ptr::MemorySpaceAttrInterface attr) {
1110 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1111 p <<
"lang_address_space("
1112 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1116 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1117 p <<
"target_address_space(" << target.getValue() <<
')';
1121 llvm_unreachable(
"unexpected address-space attribute kind");
1124mlir::OptionalParseResult
1126 mlir::ptr::MemorySpaceAttrInterface &attr) {
1128 mlir::SMLoc loc = p.getCurrentLocation();
1130 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1131 return mlir::success();
1135 mlir::ptr::MemorySpaceAttrInterface attr) {
1140 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1142 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1143 if (langAS.getValue() == cir::LangAddressSpace::Default)
1148mlir::ptr::MemorySpaceAttrInterface
1152 if (langAS == LangAS::Default)
1153 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1157 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1170 return expected == cirAS;
1177mlir::LogicalResult cir::PointerType::verify(
1178 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1179 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1182 return emitError() <<
"unsupported address space attribute; expected "
1183 "'target_address_space' or 'lang_address_space'";
1194void CIRDialect::registerTypes() {
1197#define GET_TYPEDEF_LIST
1198#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()