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/APFloat.h"
27#include "llvm/ADT/APInt.h"
28#include "llvm/ADT/APSInt.h"
29#include "llvm/ADT/TypeSwitch.h"
30#include "llvm/Support/MathExtras.h"
36 if (
auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
37 return sizedTy.isSized();
43 mlir::MLIRContext *ctx) {
44 switch (llvm::APFloat::SemanticsToEnum(sem)) {
45 case llvm::APFloat::S_IEEEhalf:
46 return cir::FP16Type::get(ctx);
47 case llvm::APFloat::S_BFloat:
48 return cir::BF16Type::get(ctx);
49 case llvm::APFloat::S_IEEEsingle:
50 return cir::SingleType::get(ctx);
51 case llvm::APFloat::S_IEEEdouble:
52 return cir::DoubleType::get(ctx);
53 case llvm::APFloat::S_x87DoubleExtended:
54 return cir::FP80Type::get(ctx);
55 case llvm::APFloat::S_IEEEquad:
56 return cir::FP128Type::get(ctx);
68static mlir::ParseResult
72 mlir::ArrayRef<mlir::Type> params,
78static mlir::ParseResult
83 mlir::ArrayRef<mlir::Type> params,
93 mlir::ptr::MemorySpaceAttrInterface &attr);
96 mlir::ptr::MemorySpaceAttrInterface attr);
104#include "clang/CIR/Dialect/IR/CIRTypeConstraints.cpp.inc"
108#define GET_TYPEDEF_CLASSES
109#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
118Type CIRDialect::parseType(DialectAsmParser &parser)
const {
119 llvm::SMLoc typeLoc = parser.getCurrentLocation();
120 llvm::StringRef mnemonic;
124 OptionalParseResult parseResult =
125 generatedTypeParser(parser, &mnemonic, genType);
126 if (parseResult.has_value())
130 parser.emitError(typeLoc) <<
"unknown CIR type: " << mnemonic;
134void CIRDialect::printType(Type type, DialectAsmPrinter &os)
const {
136 if (generatedTypePrinter(type, os).succeeded())
140 llvm::report_fatal_error(
"printer is missing a handler for this type");
152 RecordMemberKind::Data);
157static mlir::LogicalResult
161 if (memberKinds.size() != numMembers)
162 return emitError() <<
"expected " << numMembers <<
" member kinds, got "
163 << memberKinds.size();
164 return mlir::success();
168static mlir::LogicalResult
171 for (
auto [idx, memberTy] : llvm::enumerate(members)) {
172 if (!cir::isCIRType(memberTy))
173 return emitError() <<
"record member at index " << idx
174 <<
" must be a CIR type, got " << memberTy;
175 if (mlir::isa<cir::VoidType>(memberTy))
176 return emitError() <<
"record member at index " << idx
177 <<
" cannot be void";
179 return mlir::success();
187static std::optional<RecordMemberKind>
189 llvm::StringRef keyword;
190 const llvm::SMLoc loc = parser.getCurrentLocation();
191 if (parser.parseKeyword(&keyword).failed())
193 std::optional<RecordMemberKind>
kind = symbolizeRecordMemberKind(keyword);
195 parser.emitError(loc,
"expected a record member kind");
202static mlir::ParseResult
206 assert(incomplete &&
"caller must pre-initialize incomplete to true");
207 if (parser.parseOptionalKeyword(
"incomplete").succeeded())
208 return mlir::success();
210 return parser.parseCommaSeparatedList(
211 AsmParser::Delimiter::Braces,
212 [&parser, &members, &memberKinds]() -> mlir::ParseResult {
215 return mlir::failure();
216 memberKinds.push_back(*
kind);
217 return parser.parseType(members.emplace_back());
225template <
typename RecordTy>
228 bool hasClassPrefix,
bool isPacked,
bool isIncomplete,
237 FailureOr<AsmPrinter::CyclicPrintReset> cyclicPrintGuard =
238 printer.tryStartCyclicPrint(self);
239 if (failed(cyclicPrintGuard)) {
244 if (hasClassPrefix || name)
247 printer <<
"packed ";
249 printer <<
"incomplete";
252 for (
auto [idx, member] : llvm::enumerate(members)) {
255 printer << stringifyRecordMemberKind(memberKinds[idx]) <<
' ';
256 printer.printType(member);
260 printer <<
", padding = {";
261 printer.printType(padding);
269Type StructType::parse(mlir::AsmParser &parser) {
270 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
271 const llvm::SMLoc loc = parser.getCurrentLocation();
272 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
274 mlir::MLIRContext *context = parser.getContext();
276 if (parser.parseLess())
280 bool is_class = parser.parseOptionalKeyword(
"class").succeeded();
282 mlir::StringAttr
name;
283 parser.parseOptionalAttribute(name);
286 if (name && parser.parseOptionalGreater().succeeded()) {
287 StructType
type = StructType::getChecked(eLoc, context, name, is_class);
288 if (succeeded(parser.tryStartCyclicParse(type))) {
289 parser.emitError(loc,
"invalid self-reference within record");
297 StructType
type = StructType::getChecked(eLoc, context, name, is_class);
298 cyclicParseGuard = parser.tryStartCyclicParse(type);
299 if (failed(cyclicParseGuard)) {
300 parser.emitError(loc,
"record already defined");
305 if (parser.parseOptionalKeyword(
"packed").succeeded())
308 bool incomplete =
true;
309 llvm::SmallVector<mlir::Type> members;
310 llvm::SmallVector<RecordMemberKind> memberKinds;
311 if (
parseRecordBody(parser, incomplete, members, memberKinds).failed())
314 if (parser.parseGreater())
317 ArrayRef<mlir::Type> membersRef(members);
318 ArrayRef<RecordMemberKind> kindsRef(memberKinds);
319 mlir::Type
type = {};
320 if (name && incomplete) {
321 type = StructType::getChecked(eLoc, context, name, is_class);
322 }
else if (!name && !incomplete) {
323 type = StructType::getChecked(eLoc, context, membersRef, packed, is_class,
327 }
else if (!incomplete) {
328 type = StructType::getChecked(eLoc, context, membersRef, name, packed,
332 if (
auto structTy = mlir::dyn_cast<StructType>(type)) {
333 if (failed(structTy.mutate(membersRef, packed, kindsRef))) {
334 parser.emitError(loc,
"record '")
335 <<
name.getValue() <<
"' redefined with a different body";
341 parser.emitError(loc,
"anonymous records must be complete");
348void StructType::print(mlir::AsmPrinter &printer)
const {
350 isIncomplete(), getMembers(), {},
354mlir::LogicalResult StructType::verify(
355 function_ref<mlir::InFlightDiagnostic()> emitError,
356 llvm::ArrayRef<mlir::Type> members, mlir::StringAttr name,
bool incomplete,
357 bool packed, llvm::ArrayRef<RecordMemberKind> member_kinds,
bool is_class) {
358 if (name &&
name.getValue().empty())
359 return emitError() <<
"identified records cannot have an empty name";
361 return mlir::failure();
367llvm::ArrayRef<mlir::Type> StructType::getMembers()
const {
370mlir::StringAttr StructType::getName()
const {
return getImpl()->name; }
371bool StructType::isIncomplete()
const {
return getImpl()->incomplete; }
372bool StructType::getIncomplete()
const {
return getImpl()->incomplete; }
373bool StructType::getPacked()
const {
return getImpl()->packed; }
374llvm::ArrayRef<RecordMemberKind> StructType::getMemberKinds()
const {
375 return getImpl()->member_kinds;
377bool StructType::getIsClass()
const {
return getImpl()->is_class; }
379bool StructType::getPadded()
const {
380 return llvm::is_contained(getMemberKinds(), RecordMemberKind::Pad);
383bool StructType::isABIConvertedRecord()
const {
384 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
387mlir::StringAttr StructType::getABIConvertedName()
const {
388 assert(!isABIConvertedRecord());
389 return StringAttr::get(getContext(),
390 abi_conversion_prefix +
getName().getValue());
393void StructType::removeABIConversionNamePrefix() {
394 mlir::StringAttr recordName =
getName();
395 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
396 getImpl()->name = mlir::StringAttr::get(
397 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
398 recordName.getType());
401void StructType::complete(ArrayRef<Type> members,
bool packed,
402 ArrayRef<RecordMemberKind> memberKinds) {
406 succeeded(verifyInvariants(
407 mlir::detail::getDefaultDiagnosticEmitFn(getContext()), members,
408 getName(),
false, packed, memberKinds, isClass())) &&
409 "invalid struct completion");
410 if (mutate(members, packed, memberKinds).failed())
411 llvm_unreachable(
"failed to complete struct");
414bool StructType::isLayoutIdentical(
const StructType &other) {
415 if (
getImpl() == other.getImpl())
417 if (getPacked() != other.getPacked())
419 return getMembers() == other.getMembers();
426Type UnionType::parse(mlir::AsmParser &parser) {
427 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
428 const llvm::SMLoc loc = parser.getCurrentLocation();
429 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
432 mlir::MLIRContext *context = parser.getContext();
434 if (parser.parseLess())
437 mlir::StringAttr
name;
438 parser.parseOptionalAttribute(name);
441 if (name && parser.parseOptionalGreater().succeeded()) {
442 UnionType
type = UnionType::getChecked(eLoc, context, name);
443 if (succeeded(parser.tryStartCyclicParse(type))) {
444 parser.emitError(loc,
"invalid self-reference within record");
452 UnionType
type = UnionType::getChecked(eLoc, context, name);
453 cyclicParseGuard = parser.tryStartCyclicParse(type);
454 if (failed(cyclicParseGuard)) {
455 parser.emitError(loc,
"record already defined");
460 if (parser.parseOptionalKeyword(
"packed").succeeded())
463 bool incomplete =
true;
464 llvm::SmallVector<mlir::Type> members;
465 llvm::SmallVector<RecordMemberKind> memberKinds;
466 if (
parseRecordBody(parser, incomplete, members, memberKinds).failed())
471 if (!incomplete && parser.parseOptionalComma().succeeded()) {
472 if (parser.parseKeyword(
"padding").failed())
474 if (parser.parseEqual().failed())
476 if (parser.parseLBrace().failed())
478 const llvm::SMLoc paddingLoc = parser.getCurrentLocation();
479 llvm::StringRef paddingKeyword;
482 parser.emitError(paddingLoc,
"a union's tail padding takes no kind mark");
485 if (parser.parseType(padding).failed())
487 if (parser.parseRBrace().failed())
491 if (parser.parseGreater())
494 ArrayRef<mlir::Type> membersRef(members);
495 ArrayRef<RecordMemberKind> kindsRef(memberKinds);
496 mlir::Type
type = {};
497 if (name && incomplete) {
498 type = UnionType::getChecked(eLoc, context, name);
499 }
else if (!name && !incomplete) {
500 type = UnionType::getChecked(eLoc, context, membersRef, packed, padding,
504 }
else if (!incomplete) {
505 type = UnionType::getChecked(eLoc, context, membersRef, name, packed,
509 if (
auto unionTy = mlir::dyn_cast<UnionType>(type)) {
510 if (failed(unionTy.mutate(membersRef, packed, padding, kindsRef))) {
511 parser.emitError(loc,
"record '")
512 <<
name.getValue() <<
"' redefined with a different body";
518 parser.emitError(loc,
"anonymous records must be complete");
525void UnionType::print(mlir::AsmPrinter &printer)
const {
527 getPacked(), isIncomplete(), getMembers(), getPadding(),
532UnionType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
533 llvm::ArrayRef<mlir::Type> members, mlir::StringAttr name,
534 bool incomplete,
bool packed, mlir::Type padding,
535 llvm::ArrayRef<RecordMemberKind> member_kinds) {
536 if (name &&
name.getValue().empty())
537 return emitError() <<
"identified records cannot have an empty name";
541 if (llvm::is_contained(member_kinds, RecordMemberKind::Pad))
542 return emitError() <<
"a union member cannot be marked pad";
544 return mlir::failure();
547 mlir::Type charTy = padding;
548 if (
auto arrTy = mlir::dyn_cast<cir::ArrayType>(padding))
549 charTy = arrTy.getElementType();
550 auto intTy = mlir::dyn_cast<cir::IntType>(charTy);
551 if (!intTy || intTy.getWidth() != 8 || intTy.isSigned() || intTy.isBitInt())
553 <<
"union padding must be !u8i or an array of !u8i, got "
559 for (
auto [idx, memberTy] : llvm::enumerate(members))
560 if (
auto bfTy = mlir::dyn_cast<cir::BitFieldType>(memberTy);
561 bfTy && !bfTy.ownsBytes())
562 return emitError() <<
"union bit-field member at index " << idx
563 <<
" must own its access unit storage";
568llvm::ArrayRef<mlir::Type> UnionType::getMembers()
const {
571mlir::StringAttr UnionType::getName()
const {
return getImpl()->name; }
572bool UnionType::isIncomplete()
const {
return getImpl()->incomplete; }
573bool UnionType::getIncomplete()
const {
return getImpl()->incomplete; }
574bool UnionType::getPacked()
const {
return getImpl()->packed; }
575bool UnionType::getPadded()
const {
return getPadding() ?
true :
false; }
576mlir::Type UnionType::getPadding()
const {
return getImpl()->padding; }
577llvm::ArrayRef<RecordMemberKind> UnionType::getMemberKinds()
const {
578 return getImpl()->member_kinds;
581bool UnionType::isABIConvertedRecord()
const {
582 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
585mlir::StringAttr UnionType::getABIConvertedName()
const {
586 assert(!isABIConvertedRecord());
587 return StringAttr::get(getContext(),
588 abi_conversion_prefix +
getName().getValue());
591void UnionType::removeABIConversionNamePrefix() {
592 mlir::StringAttr recordName =
getName();
593 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
594 getImpl()->name = mlir::StringAttr::get(
595 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
596 recordName.getType());
599void UnionType::complete(ArrayRef<Type> members,
bool packed,
601 ArrayRef<RecordMemberKind> memberKinds) {
604 assert(succeeded(verifyInvariants(
605 mlir::detail::getDefaultDiagnosticEmitFn(getContext()), members,
606 getName(),
false, packed, padding, memberKinds)) &&
607 "invalid union completion");
608 if (mutate(members, packed, padding, memberKinds).failed())
609 llvm_unreachable(
"failed to complete union");
613UnionType::getUnionStorageType(
const mlir::DataLayout &dataLayout)
const {
614 return getUnionStorageType(dataLayout, getMembers());
617mlir::Type UnionType::getUnionStorageType(
const mlir::DataLayout &dataLayout,
618 llvm::ArrayRef<mlir::Type> members) {
621 mlir::Type largest = *std::max_element(
622 members.begin(), members.end(), [&](mlir::Type lhs, mlir::Type rhs) {
623 return dataLayout.getTypeABIAlignment(lhs) <
624 dataLayout.getTypeABIAlignment(rhs) ||
625 (dataLayout.getTypeABIAlignment(lhs) ==
626 dataLayout.getTypeABIAlignment(rhs) &&
627 dataLayout.getTypeAllocSize(lhs) <
628 dataLayout.getTypeAllocSize(rhs));
636bool UnionType::isLayoutIdentical(
const UnionType &other) {
637 if (
getImpl() == other.getImpl())
639 return getMembers() == other.getMembers() &&
640 getPadding() == other.getPadding();
648 if (
auto s = mlir::dyn_cast<StructType>(*
this))
649 return s.getMembers();
650 return mlir::cast<UnionType>(*this).getMembers();
653 if (
auto s = mlir::dyn_cast<StructType>(*
this))
655 return mlir::cast<UnionType>(*this).getName();
658 if (
auto s = mlir::dyn_cast<StructType>(*
this))
659 return s.isIncomplete();
660 return mlir::cast<UnionType>(*this).isIncomplete();
663 if (
auto s = mlir::dyn_cast<StructType>(*
this))
664 return s.getPacked();
665 return mlir::cast<UnionType>(*this).getPacked();
668 if (
auto s = mlir::dyn_cast<StructType>(*
this))
669 return s.getPadded();
670 return mlir::cast<UnionType>(*this).getPadded();
673 if (
auto s = mlir::dyn_cast<StructType>(*
this))
674 return s.getMemberKinds();
675 return mlir::cast<UnionType>(*this).getMemberKinds();
678 if (
auto s = mlir::dyn_cast<StructType>(*
this))
683 if (
auto s = mlir::dyn_cast<StructType>(*
this))
688 if (mlir::isa<UnionType>(*
this))
690 return mlir::cast<StructType>(*this).getKindAsStr();
698 if (
auto s = mlir::dyn_cast<StructType>(*
this)) {
699 assert(!padding &&
"only a union takes a separate padding slot");
700 return s.complete(members, packed, memberKinds);
702 return mlir::cast<UnionType>(*this).complete(members, packed, padding,
706 unsigned idx)
const {
707 if (mlir::isa<UnionType>(*
this))
709 return mlir::cast<StructType>(*this).getElementOffset(dataLayout, idx);
712 if (
auto s = mlir::dyn_cast<StructType>(*
this)) {
713 if (
auto so = mlir::dyn_cast<StructType>(other))
714 return s.isLayoutIdentical(so);
717 if (
auto u = mlir::dyn_cast<UnionType>(*
this)) {
718 if (
auto uo = mlir::dyn_cast<UnionType>(other))
719 return u.isLayoutIdentical(uo);
725 if (
auto s = mlir::dyn_cast<StructType>(*
this))
726 return s.isABIConvertedRecord();
727 return mlir::cast<UnionType>(*this).isABIConvertedRecord();
730 if (
auto s = mlir::dyn_cast<StructType>(*
this))
731 return s.getABIConvertedName();
732 return mlir::cast<UnionType>(*this).getABIConvertedName();
735 if (
auto s = mlir::dyn_cast<StructType>(*
this))
736 return s.removeABIConversionNamePrefix();
737 return mlir::cast<UnionType>(*this).removeABIConversionNamePrefix();
751 return llvm::none_of(
getMembers(), [](mlir::Type memberTy) {
752 auto bfTy = mlir::dyn_cast<cir::BitFieldType>(memberTy);
753 return bfTy && bfTy.ownsBytes();
764constexpr static uint64_t kBitsInByte = 8;
767constexpr static uint64_t kDefaultPointerSizeBits = 64;
768constexpr static uint64_t kDefaultPointerAlignment = 8;
772cir::PtrSpecAttr getPointerSpec(mlir::DataLayoutEntryListRef params,
773 cir::PointerType type) {
776 for (mlir::DataLayoutEntryInterface entry : params) {
777 if (!entry.isTypeEntry())
780 mlir::cast<cir::PointerType>(mlir::cast<mlir::Type>(entry.getKey()));
781 if (key.getAddrSpace())
783 if (
auto spec = mlir::dyn_cast<cir::PtrSpecAttr>(entry.getValue()))
786 return cir::PtrSpecAttr::get(type.getContext(), kDefaultPointerSizeBits,
787 kDefaultPointerAlignment * kBitsInByte,
788 kDefaultPointerAlignment * kBitsInByte,
789 kDefaultPointerSizeBits);
794PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
795 ::mlir::DataLayoutEntryListRef params)
const {
796 return llvm::TypeSize::getFixed(getPointerSpec(params, *
this).getSize());
800PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
801 ::mlir::DataLayoutEntryListRef params)
const {
802 return getPointerSpec(params, *
this).getAbi() / kBitsInByte;
805uint64_t PointerType::getPreferredAlignment(
806 const ::mlir::DataLayout &dataLayout,
807 ::mlir::DataLayoutEntryListRef params)
const {
808 return getPointerSpec(params, *
this).getPreferred() / kBitsInByte;
811std::optional<uint64_t>
812PointerType::getIndexBitwidth(const ::mlir::DataLayout &dataLayout,
813 ::mlir::DataLayoutEntryListRef params)
const {
814 cir::PtrSpecAttr spec = getPointerSpec(params, *
this);
815 if (spec.getIndex() == cir::PtrSpecAttr::kOptionalSpecValue)
816 return spec.getSize();
817 return spec.getIndex();
821PointerType::verifyEntries(mlir::DataLayoutEntryListRef entries,
822 mlir::Location loc)
const {
823 for (mlir::DataLayoutEntryInterface entry : entries) {
824 if (!entry.isTypeEntry())
826 auto key = mlir::cast<PointerType>(mlir::cast<mlir::Type>(entry.getKey()));
827 if (!mlir::isa<cir::PtrSpecAttr>(entry.getValue()))
828 return mlir::emitError(loc) <<
"expected layout attribute for " << key
829 <<
" to be a #cir.ptr_spec attribute";
830 if (!mlir::isa<cir::VoidType>(key.getPointee()))
831 return mlir::emitError(loc) <<
"expected !cir.ptr data layout entry for "
832 << key <<
" to use !cir.void as pointee";
834 if (key.getAddrSpace())
835 return mlir::emitError(loc)
836 <<
"!cir.ptr data layout entries are currently limited to the "
837 "default address space";
839 return mlir::success();
842bool PointerType::areCompatible(
843 mlir::DataLayoutEntryListRef oldLayout,
844 mlir::DataLayoutEntryListRef newLayout, mlir::DataLayoutSpecInterface,
845 const mlir::DataLayoutIdentifiedEntryMap &)
const {
848 cir::PtrSpecAttr oldSpec = getPointerSpec(oldLayout, *
this);
851 for (mlir::DataLayoutEntryInterface newEntry : newLayout) {
852 if (!newEntry.isTypeEntry())
854 auto newSpec = mlir::cast<cir::PtrSpecAttr>(newEntry.getValue());
855 if (size != newSpec.getSize() || abi < newSpec.getAbi() ||
856 abi % newSpec.getAbi() != 0)
863StructType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
864 mlir::DataLayoutEntryListRef params)
const {
865 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
866 return llvm::TypeSize::getFixed(recordSize * 8);
870StructType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
871 ::mlir::DataLayoutEntryListRef params)
const {
875 return computeStructAlignment(dataLayout);
883UnionType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
884 mlir::DataLayoutEntryListRef params)
const {
885 llvm::TypeSize size = llvm::TypeSize::getFixed(0);
886 if (mlir::Type storage = getUnionStorageType(dataLayout))
887 size += dataLayout.getTypeAllocSize(storage) * 8;
888 if (mlir::Type pad = getPadding())
889 size += dataLayout.getTypeSizeInBits(pad);
894UnionType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
895 ::mlir::DataLayoutEntryListRef params)
const {
898 mlir::Type storage = getUnionStorageType(dataLayout);
901 return dataLayout.getTypeABIAlignment(storage);
905StructType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
906 assert(isComplete() &&
"Cannot get layout of incomplete records");
911 unsigned recordSize = 0;
914 for (mlir::Type ty : getMembers()) {
918 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
922 recordSize = llvm::alignTo(recordSize, tyAlign);
923 recordSize += dataLayout.getTypeAllocSize(ty);
927 recordAlignment = std::max(tyAlign, recordAlignment);
932 recordSize = llvm::alignTo(recordSize, recordAlignment);
937StructType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
938 assert(isComplete() &&
"Cannot get layout of incomplete records");
943 llvm::ArrayRef<mlir::Type> members = getMembers();
944 llvm::ArrayRef<RecordMemberKind> kinds = getMemberKinds();
945 assert(kinds.size() == members.size() &&
946 "the two drop_back calls below must stay in step");
947 while (!kinds.empty() && (kinds.back() == RecordMemberKind::Pad ||
949 kinds = kinds.drop_back();
950 members = members.drop_back();
953 unsigned recordSize = 0;
954 for (mlir::Type ty : members) {
956 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
957 recordSize = llvm::alignTo(recordSize, tyAlign);
958 recordSize += dataLayout.getTypeAllocSize(ty);
968StructType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
969 assert(isComplete() &&
"Cannot get layout of incomplete records");
972 for (mlir::Type ty : getMembers())
974 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
975 return recordAlignment;
978unsigned StructType::getLLVMFieldIndex(
unsigned idx)
const {
979 llvm::ArrayRef<mlir::Type> members = getMembers();
980 assert(idx < members.size() &&
"access not valid");
982 "a member that owns no bytes has no LLVM field");
984 unsigned llvmIdx = 0;
985 for (
unsigned i = 0; i != idx; ++i)
991uint64_t StructType::getElementOffset(const ::mlir::DataLayout &dataLayout,
992 unsigned idx)
const {
993 assert(idx < getMembers().size() &&
"access not valid");
997 assert(isComplete() &&
"Cannot get layout of incomplete records");
998 llvm::ArrayRef<mlir::Type> members = getMembers();
1003 unsigned offset = 0;
1004 for (
unsigned i = 0; i != idx; ++i) {
1005 const llvm::Align tyAlign = llvm::Align(
1006 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[i]));
1007 offset = llvm::alignTo(offset, tyAlign);
1008 offset += dataLayout.getTypeAllocSize(members[i]);
1011 const llvm::Align tyAlign = llvm::Align(
1012 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
1013 return llvm::alignTo(offset, tyAlign);
1020Type IntType::parse(mlir::AsmParser &parser) {
1021 mlir::MLIRContext *context = parser.getBuilder().getContext();
1022 llvm::SMLoc loc = parser.getCurrentLocation();
1026 if (parser.parseLess())
1030 llvm::StringRef
sign;
1031 if (parser.parseKeyword(&
sign))
1035 else if (
sign ==
"u")
1038 parser.emitError(loc,
"expected 's' or 'u'");
1042 if (parser.parseComma())
1046 if (parser.parseInteger(width))
1048 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
1049 parser.emitError(loc,
"expected integer width to be from ")
1050 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
1054 bool isBitInt =
false;
1055 if (succeeded(parser.parseOptionalComma())) {
1057 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
1058 parser.emitError(loc,
"expected 'bitint'");
1064 if (parser.parseGreater())
1067 return IntType::get(context, width, isSigned, isBitInt);
1070void IntType::print(mlir::AsmPrinter &printer)
const {
1071 char sign = isSigned() ?
's' :
'u';
1072 printer <<
'<' <<
sign <<
", " << getWidth();
1074 printer <<
", bitint";
1079IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1080 mlir::DataLayoutEntryListRef params)
const {
1081 return llvm::TypeSize::getFixed(getStorageTypeWidth(dataLayout));
1085IntType::getStorageTypeWidth(
const mlir::DataLayout &dataLayout)
const {
1088 uint64_t alignBits = getABIAlignment(dataLayout, {}) * 8;
1089 return static_cast<unsigned>(llvm::alignTo(getWidth(), alignBits));
1093IntType::getStorageTypeAlignment(
const mlir::DataLayout &dataLayout)
const {
1095 return getABIAlignment(dataLayout, {});
1097 mlir::IntegerType::get(getContext(), getStorageTypeWidth(dataLayout));
1098 return dataLayout.getTypeABIAlignment(storageTy);
1101uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1102 mlir::DataLayoutEntryListRef params)
const {
1103 unsigned width = getWidth();
1108 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
1109 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
1116 uint64_t alignBits = llvm::PowerOf2Ceil(width);
1117 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
1121IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1122 unsigned width,
bool isSigned,
bool isBitInt) {
1123 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
1124 return emitError() <<
"IntType only supports widths from "
1125 << IntType::minBitwidth() <<
" up to "
1126 << IntType::maxBitwidth();
1127 return mlir::success();
1131 return width == 8 || width == 16 || width == 32 || width == 64;
1138const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
1139 return llvm::APFloat::IEEEsingle();
1143SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1144 mlir::DataLayoutEntryListRef params)
const {
1145 return llvm::TypeSize::getFixed(getWidth());
1149SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1150 mlir::DataLayoutEntryListRef params)
const {
1151 return (uint64_t)(getWidth() / 8);
1154const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
1155 return llvm::APFloat::IEEEdouble();
1159DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1160 mlir::DataLayoutEntryListRef params)
const {
1161 return llvm::TypeSize::getFixed(getWidth());
1165DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1166 mlir::DataLayoutEntryListRef params)
const {
1167 return (uint64_t)(getWidth() / 8);
1170const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
1171 return llvm::APFloat::IEEEhalf();
1175FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1176 mlir::DataLayoutEntryListRef params)
const {
1177 return llvm::TypeSize::getFixed(getWidth());
1180uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1181 mlir::DataLayoutEntryListRef params)
const {
1182 return (uint64_t)(getWidth() / 8);
1185const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
1186 return llvm::APFloat::BFloat();
1190BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1191 mlir::DataLayoutEntryListRef params)
const {
1192 return llvm::TypeSize::getFixed(getWidth());
1195uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1196 mlir::DataLayoutEntryListRef params)
const {
1197 return (uint64_t)(getWidth() / 8);
1200const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
1201 return llvm::APFloat::x87DoubleExtended();
1205FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1206 mlir::DataLayoutEntryListRef params)
const {
1208 return llvm::TypeSize::getFixed(128);
1211uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1212 mlir::DataLayoutEntryListRef params)
const {
1216const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
1217 return llvm::APFloat::IEEEquad();
1221FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1222 mlir::DataLayoutEntryListRef params)
const {
1223 return llvm::TypeSize::getFixed(getWidth());
1226uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1227 mlir::DataLayoutEntryListRef params)
const {
1231const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
1232 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
1236LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1237 mlir::DataLayoutEntryListRef params)
const {
1238 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
1239 .getTypeSizeInBits(dataLayout, params);
1243LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1244 mlir::DataLayoutEntryListRef params)
const {
1245 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
1246 .getABIAlignment(dataLayout, params);
1254cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1255 mlir::DataLayoutEntryListRef params)
const {
1261 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
1265cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1266 mlir::DataLayoutEntryListRef params)
const {
1272 return dataLayout.getTypeABIAlignment(getElementType());
1275FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
1276 assert(results.size() == 1 &&
"expected exactly one result type");
1277 return get(llvm::to_vector(inputs), results[0], isVarArg());
1281static mlir::ParseResult
1285 return p.parseCommaSeparatedList(
1286 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
1288 return p.emitError(p.getCurrentLocation(),
1289 "variadic `...` must be the last parameter");
1290 if (succeeded(p.parseOptionalEllipsis())) {
1295 if (failed(p.parseType(type)))
1297 params.push_back(type);
1303 mlir::ArrayRef<mlir::Type> params,
1306 llvm::interleaveComma(params, p,
1307 [&p](mlir::Type type) { p.printType(type); });
1309 if (!params.empty())
1318mlir::Type FuncType::getReturnType()
const {
1319 if (hasVoidReturn())
1320 return cir::VoidType::get(getContext());
1321 return getOptionalReturnType();
1327llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
1328 if (hasVoidReturn())
1333 return getImpl()->optionalReturnType;
1337bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
1340FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1341 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
1343 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
1345 <<
"!cir.func cannot have an explicit 'void' return type";
1350 if (!llvm::all_of(argTypes, cir::isCIRType) ||
1351 (returnType && !cir::isCIRType(returnType)))
1353 <<
"expected all types in the function signature to be CIR types";
1355 return mlir::success();
1367 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
1368 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
1369 return cir::StructType::get(ctx, fields,
false,
1375MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1376 mlir::DataLayoutEntryListRef params)
const {
1381MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1382 mlir::DataLayoutEntryListRef params)
const {
1384 .getABIAlignment(dataLayout, params);
1392BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1393 ::mlir::DataLayoutEntryListRef params)
const {
1394 return llvm::TypeSize::getFixed(8);
1398BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1399 ::mlir::DataLayoutEntryListRef params)
const {
1408 mlir::MLIRContext *ctx) {
1412 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
1413 uint64_t width = dataLayout.getTypeIndexBitwidth(voidPtrTy).value_or(
1414 dataLayout.getTypeSizeInBits(voidPtrTy).getFixedValue());
1415 return cir::IntType::get(ctx, width,
true);
1419DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1420 ::mlir::DataLayoutEntryListRef params)
const {
1422 return dataLayout.getTypeSizeInBits(
1427DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1428 ::mlir::DataLayoutEntryListRef params)
const {
1430 return dataLayout.getTypeABIAlignment(
1439VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1440 mlir::DataLayoutEntryListRef params)
const {
1442 return dataLayout.getTypeSizeInBits(
1443 cir::PointerType::get(cir::VoidType::get(getContext())));
1446uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1447 mlir::DataLayoutEntryListRef params)
const {
1448 return dataLayout.getTypeABIAlignment(
1449 cir::PointerType::get(cir::VoidType::get(getContext())));
1457ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1458 ::mlir::DataLayoutEntryListRef params)
const {
1459 return getSize() * dataLayout.getTypeAllocSize(getElementType()) * 8;
1463ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1464 ::mlir::DataLayoutEntryListRef params)
const {
1465 return dataLayout.getTypeABIAlignment(getElementType());
1473BitFieldType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1474 mlir::Type storageType,
1475 llvm::ArrayRef<cir::BitFieldDeclAttr> fields) {
1477 return emitError() <<
"bit-field member must hold at least one bit-field";
1482 if (fields.size() != 1 || fields.front().getWidth() != 0)
1483 return emitError() <<
"a bit-field member without storage must hold a "
1484 "single zero-width bit-field";
1485 return mlir::success();
1488 if (!cir::isCIRType(storageType))
1489 return emitError() <<
"bit-field access unit storage must be a CIR type, "
1493 if (mlir::isa<cir::BitFieldType>(storageType))
1494 return emitError() <<
"bit-field access unit storage cannot itself be a "
1498 return emitError() <<
"bit-field access unit storage must be sized, got "
1503 if (llvm::any_of(fields, [](cir::BitFieldDeclAttr decl) {
1504 return decl.getWidth() == 0;
1506 return emitError() <<
"a zero-width bit-field cannot occupy an access unit";
1508 return mlir::success();
1512BitFieldType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1513 mlir::DataLayoutEntryListRef params)
const {
1516 if (mlir::Type storage = getStorageType())
1517 return dataLayout.getTypeSizeInBits(storage);
1518 return llvm::TypeSize::getFixed(0);
1522BitFieldType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1523 mlir::DataLayoutEntryListRef params)
const {
1526 if (mlir::Type storage = getStorageType())
1527 return dataLayout.getTypeABIAlignment(storage);
1535llvm::TypeSize cir::VectorType::getTypeSizeInBits(
1536 const ::mlir::DataLayout &dataLayout,
1537 ::mlir::DataLayoutEntryListRef params)
const {
1540 if (mlir::isa<cir::BoolType>(getElementType()) && getSize().isFixed()) {
1542 return llvm::TypeSize::getFixed(llvm::PowerOf2Ceil(getBoolStorageWidth()));
1545 llvm::TypeSize elementSize = dataLayout.getTypeSizeInBits(getElementType());
1546 return llvm::TypeSize::get(
1547 getSize().getKnownMinValue() * elementSize.getFixedValue(), isScalable());
1550uint64_t cir::VectorType::getBoolStorageWidth()
const {
1551 assert(mlir::isa<cir::BoolType>(getElementType()) &&
1552 "only a bool vector is stored as an integer");
1553 return std::max<uint64_t>(getFixedSize(), 8);
1557cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1558 ::mlir::DataLayoutEntryListRef params)
const {
1560 return llvm::PowerOf2Ceil(llvm::divideCeil(
1561 dataLayout.getTypeSizeInBits(*this).getKnownMinValue(), uint64_t{8}));
1564mlir::LogicalResult cir::VectorType::verify(
1565 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1566 mlir::Type elementType, llvm::ElementCount size) {
1568 return emitError() <<
"the number of vector elements must be non-zero";
1572mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
1574 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
1575 mlir::Builder odsBuilder(odsParser.getContext());
1576 mlir::FailureOr<::mlir::Type> elementType;
1577 mlir::FailureOr<uint64_t> size;
1578 bool isScalable =
false;
1581 if (odsParser.parseLess())
1585 if (odsParser.parseOptionalLSquare().succeeded())
1589 size = mlir::FieldParser<uint64_t>::parse(odsParser);
1590 if (mlir::failed(size)) {
1591 odsParser.emitError(odsParser.getCurrentLocation(),
1592 "failed to parse CIR_VectorType parameter 'size' which "
1593 "is to be a `uint64_t`");
1599 if (isScalable && odsParser.parseRSquare().failed()) {
1600 odsParser.emitError(odsParser.getCurrentLocation(),
1601 "missing closing `]` for scalable dim size");
1606 if (odsParser.parseKeyword(
"x"))
1610 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
1611 if (mlir::failed(elementType)) {
1612 odsParser.emitError(odsParser.getCurrentLocation(),
1613 "failed to parse CIR_VectorType parameter "
1614 "'elementType' which is to be a `mlir::Type`");
1619 if (odsParser.parseGreater())
1621 return odsParser.getChecked<VectorType>(
1622 odsLoc, odsParser.getContext(), mlir::Type((*elementType)),
1623 llvm::ElementCount::get(*size, isScalable));
1626void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
1627 mlir::Builder odsBuilder(getContext());
1632 odsPrinter.printStrippedAttrOrType(getSize().getKnownMinValue());
1635 odsPrinter <<
' ' <<
"x";
1637 odsPrinter.printStrippedAttrOrType(getElementType());
1645llvm::TypeSize cir::MatrixType::getTypeSizeInBits(
1646 const ::mlir::DataLayout &dataLayout,
1647 ::mlir::DataLayoutEntryListRef params)
const {
1648 return llvm::TypeSize::getFixed(
1649 getNumRows() * getNumColumns() *
1650 dataLayout.getTypeSizeInBits(getElementType()));
1654cir::MatrixType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1655 ::mlir::DataLayoutEntryListRef params)
const {
1656 return dataLayout.getTypeABIAlignment(getElementType());
1659mlir::LogicalResult cir::MatrixType::verify(
1660 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1661 mlir::Type elementType, uint64_t row, uint64_t column) {
1663 return emitError() <<
"the number of matrix rows must be non-zero";
1665 return emitError() <<
"the number of matrix columns must be non-zero";
1674 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1675 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1682 case LangAS::Default:
1683 return LangAddressSpace::Default;
1684 case LangAS::opencl_global:
1685 case LangAS::sycl_global:
1686 return LangAddressSpace::OffloadGlobal;
1687 case LangAS::opencl_local:
1688 case LangAS::cuda_shared:
1689 case LangAS::sycl_local:
1692 return LangAddressSpace::OffloadLocal;
1693 case LangAS::cuda_device:
1694 return LangAddressSpace::OffloadGlobal;
1695 case LangAS::opencl_constant:
1696 case LangAS::cuda_constant:
1697 case LangAS::sycl_constant:
1698 return LangAddressSpace::OffloadConstant;
1699 case LangAS::opencl_private:
1700 case LangAS::sycl_private:
1701 return LangAddressSpace::OffloadPrivate;
1702 case LangAS::opencl_generic:
1703 case LangAS::sycl_generic:
1704 return LangAddressSpace::OffloadGeneric;
1705 case LangAS::opencl_global_device:
1706 case LangAS::sycl_global_device:
1707 return LangAddressSpace::OffloadGlobalDevice;
1708 case LangAS::opencl_global_host:
1709 case LangAS::sycl_global_host:
1710 return LangAddressSpace::OffloadGlobalHost;
1711 case LangAS::ptr32_sptr:
1712 case LangAS::ptr32_uptr:
1714 case LangAS::hlsl_groupshared:
1715 case LangAS::wasm_funcref:
1716 llvm_unreachable(
"NYI");
1718 llvm_unreachable(
"unknown/unsupported clang language address space");
1723 mlir::ptr::MemorySpaceAttrInterface &attr) {
1725 llvm::SMLoc loc = p.getCurrentLocation();
1729 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1731 if (p.parseLParen())
1732 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1734 if (p.parseInteger(val))
1735 return p.emitError(loc,
"expected target address space value");
1737 if (p.parseRParen())
1738 return p.emitError(loc,
"expected ')'");
1740 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1741 return mlir::success();
1745 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1746 if (p.parseLParen())
1747 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1749 mlir::FailureOr<cir::LangAddressSpace> result =
1750 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1751 if (mlir::failed(result))
1752 return mlir::failure();
1754 if (p.parseRParen())
1755 return p.emitError(loc,
"expected ')'");
1757 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1758 return mlir::success();
1761 llvm::StringRef keyword;
1762 if (p.parseOptionalKeyword(&keyword).succeeded())
1763 return p.emitError(loc,
"unknown address space specifier '")
1764 << keyword <<
"'; expected 'target_address_space' or "
1765 <<
"'lang_address_space'";
1767 return mlir::success();
1771 mlir::ptr::MemorySpaceAttrInterface attr) {
1775 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1776 p <<
"lang_address_space("
1777 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1781 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1782 p <<
"target_address_space(" << target.getValue() <<
')';
1786 llvm_unreachable(
"unexpected address-space attribute kind");
1789mlir::OptionalParseResult
1791 mlir::ptr::MemorySpaceAttrInterface &attr) {
1793 mlir::SMLoc loc = p.getCurrentLocation();
1795 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1796 return mlir::success();
1800 mlir::ptr::MemorySpaceAttrInterface attr) {
1805 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1807 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1808 if (langAS.getValue() == cir::LangAddressSpace::Default)
1813mlir::ptr::MemorySpaceAttrInterface
1817 if (langAS == LangAS::Default)
1818 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1822 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1835 return expected == cirAS;
1842mlir::LogicalResult cir::PointerType::verify(
1843 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1844 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1847 return emitError() <<
"unsupported address space attribute; expected "
1848 "'target_address_space' or 'lang_address_space'";
1859void CIRDialect::registerTypes() {
1862#define GET_TYPEDEF_LIST
1863#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
Provides definitions for the various language-specific address spaces.
mlir::OptionalParseResult parseGlobalMemorySpace(mlir::AsmParser &p, mlir::ptr::MemorySpaceAttrInterface &attr)
void printGlobalMemorySpace(mlir::AsmPrinter &printer, cir::GlobalOp op, mlir::ptr::MemorySpaceAttrInterface attr)
mlir::ParseResult parseMemorySpace(mlir::AsmParser &p, mlir::ptr::MemorySpaceAttrInterface &attr)
static mlir::LogicalResult verifyRecordMemberTypes(function_ref< mlir::InFlightDiagnostic()> emitError, llvm::ArrayRef< mlir::Type > members)
Members must be CIR types other than void, which has no layout.
static const llvm::StringRef memberKindMarks[]
The keywords that spell a member kind.
static void printRecordBody(mlir::AsmPrinter &printer, RecordTy self, mlir::StringAttr name, bool hasClassPrefix, bool isPacked, bool isIncomplete, llvm::ArrayRef< mlir::Type > members, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > memberKinds)
Print a complete CIR record body: '<' ['class '] [name] ['packed '] body '>' where body is "incomplet...
static mlir::LogicalResult verifyRecordMemberKinds(function_ref< mlir::InFlightDiagnostic()> emitError, size_t numMembers, llvm::ArrayRef< RecordMemberKind > memberKinds)
An incomplete record has no members, so a kind for one is caught by the same check.
static mlir::ParseResult parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector< mlir::Type > ¶ms, bool &isVarArg)
void printMemorySpace(mlir::AsmPrinter &printer, mlir::ptr::MemorySpaceAttrInterface attr)
static mlir::Type getMethodLayoutType(mlir::MLIRContext *ctx)
static void printFuncTypeParams(mlir::AsmPrinter &p, mlir::ArrayRef< mlir::Type > params, bool isVarArg)
static mlir::ParseResult parseRecordBody(mlir::AsmParser &parser, bool &incomplete, llvm::SmallVector< mlir::Type > &members, llvm::SmallVectorImpl< RecordMemberKind > &memberKinds)
Parse "incomplete" or "{mark type, mark type, ...}", writing results into incomplete,...
static std::optional< RecordMemberKind > parseMemberKind(mlir::AsmParser &parser)
static mlir::Type getDataMemberLayoutType(const mlir::DataLayout &dataLayout, mlir::MLIRContext *ctx)
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 isLayoutIdentical(const RecordType &other)
bool isABIConvertedRecord() const
bool isIncomplete() const
bool isEmptyForABI() const
Whether no member holds data.
std::string getPrefixedName() const
llvm::ArrayRef< mlir::Type > getMembers() const
void removeABIConversionNamePrefix()
static llvm::SmallVector< RecordMemberKind > getAllDataKinds(llvm::ArrayRef< mlir::Type > members)
One Data kind per member.
mlir::StringAttr getName() const
void complete(llvm::ArrayRef< mlir::Type > members, bool packed, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > memberKinds)
padding is union-only.
mlir::StringAttr getABIConvertedName() const
std::string getKindAsStr() const
llvm::ArrayRef< RecordMemberKind > getMemberKinds() const
uint64_t getElementOffset(const mlir::DataLayout &dataLayout, unsigned idx) const
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS)
mlir::Type memberStorageType(mlir::Type memberTy)
The storage a member is stored as: the access unit for a bit-field member, and the member type itself...
bool memberOwnsBytes(mlir::Type memberTy)
Whether a record member occupies bytes of its record.
bool isValidFundamentalIntWidth(unsigned width)
cir::FPTypeInterface getFloatingPointType(const llvm::fltSemantics &sem, mlir::MLIRContext *ctx)
Returns the CIR floating-point type for the given semantics, or a null type if CIR has no type for it...
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
bool anyMemberHoldsDataForABI(llvm::ArrayRef< RecordMemberKind > kinds)
Whether any member holds data for argument passing on its mark alone.
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.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
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()