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);
67 return !ty.walk([](mlir::Type t) {
69 return mlir::WalkResult::advance();
70 return mlir::isa<cir::CIRDialect>(t.getDialect())
71 ? mlir::WalkResult::advance()
72 : mlir::WalkResult::interrupt();
80static mlir::ParseResult
84 mlir::ArrayRef<mlir::Type> params,
90static mlir::ParseResult
95 mlir::ArrayRef<mlir::Type> params,
105 mlir::ptr::MemorySpaceAttrInterface &attr);
108 mlir::ptr::MemorySpaceAttrInterface attr);
116#include "clang/CIR/Dialect/IR/CIRTypeConstraints.cpp.inc"
120#define GET_TYPEDEF_CLASSES
121#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
130Type CIRDialect::parseType(DialectAsmParser &parser)
const {
131 llvm::SMLoc typeLoc = parser.getCurrentLocation();
132 llvm::StringRef mnemonic;
136 OptionalParseResult parseResult =
137 generatedTypeParser(parser, &mnemonic, genType);
138 if (parseResult.has_value())
142 parser.emitError(typeLoc) <<
"unknown CIR type: " << mnemonic;
146void CIRDialect::printType(Type type, DialectAsmPrinter &os)
const {
148 if (generatedTypePrinter(type, os).succeeded())
152 llvm::report_fatal_error(
"printer is missing a handler for this type");
164 RecordMemberKind::Data);
169static mlir::LogicalResult
173 if (memberKinds.size() != numMembers)
174 return emitError() <<
"expected " << numMembers <<
" member kinds, got "
175 << memberKinds.size();
176 return mlir::success();
184static std::optional<RecordMemberKind>
186 llvm::StringRef keyword;
187 const llvm::SMLoc loc = parser.getCurrentLocation();
188 if (parser.parseKeyword(&keyword).failed())
190 std::optional<RecordMemberKind>
kind = symbolizeRecordMemberKind(keyword);
192 parser.emitError(loc,
"expected a record member kind");
199static mlir::ParseResult
203 assert(incomplete &&
"caller must pre-initialize incomplete to true");
204 if (parser.parseOptionalKeyword(
"incomplete").succeeded())
205 return mlir::success();
207 return parser.parseCommaSeparatedList(
208 AsmParser::Delimiter::Braces,
209 [&parser, &members, &memberKinds]() -> mlir::ParseResult {
212 return mlir::failure();
213 memberKinds.push_back(*
kind);
214 return parser.parseType(members.emplace_back());
222template <
typename RecordTy>
225 bool hasClassPrefix,
bool isPacked,
bool isIncomplete,
234 FailureOr<AsmPrinter::CyclicPrintReset> cyclicPrintGuard =
235 printer.tryStartCyclicPrint(self);
236 if (failed(cyclicPrintGuard)) {
241 if (hasClassPrefix || name)
244 printer <<
"packed ";
246 printer <<
"incomplete";
249 for (
auto [idx, member] : llvm::enumerate(members)) {
252 printer << stringifyRecordMemberKind(memberKinds[idx]) <<
' ';
253 printer.printType(member);
257 printer <<
", padding = {";
258 printer.printType(padding);
266Type StructType::parse(mlir::AsmParser &parser) {
267 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
268 const llvm::SMLoc loc = parser.getCurrentLocation();
269 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
271 mlir::MLIRContext *context = parser.getContext();
273 if (parser.parseLess())
277 bool is_class = parser.parseOptionalKeyword(
"class").succeeded();
279 mlir::StringAttr
name;
280 parser.parseOptionalAttribute(name);
283 if (name && parser.parseOptionalGreater().succeeded()) {
284 StructType
type = StructType::getChecked(eLoc, context, name, is_class);
285 if (succeeded(parser.tryStartCyclicParse(type))) {
286 parser.emitError(loc,
"invalid self-reference within record");
294 StructType
type = StructType::getChecked(eLoc, context, name, is_class);
295 cyclicParseGuard = parser.tryStartCyclicParse(type);
296 if (failed(cyclicParseGuard)) {
297 parser.emitError(loc,
"record already defined");
302 if (parser.parseOptionalKeyword(
"packed").succeeded())
305 bool incomplete =
true;
306 llvm::SmallVector<mlir::Type> members;
307 llvm::SmallVector<RecordMemberKind> memberKinds;
308 if (
parseRecordBody(parser, incomplete, members, memberKinds).failed())
311 if (parser.parseGreater())
314 ArrayRef<mlir::Type> membersRef(members);
315 ArrayRef<RecordMemberKind> kindsRef(memberKinds);
316 mlir::Type
type = {};
317 if (name && incomplete) {
318 type = StructType::getChecked(eLoc, context, name, is_class);
319 }
else if (!name && !incomplete) {
320 type = StructType::getChecked(eLoc, context, membersRef, packed, is_class,
324 }
else if (!incomplete) {
325 type = StructType::getChecked(eLoc, context, membersRef, name, packed,
329 if (
auto structTy = mlir::dyn_cast<StructType>(type))
330 if (structTy.isIncomplete())
331 structTy.complete(membersRef, packed, kindsRef);
334 parser.emitError(loc,
"anonymous records must be complete");
341void StructType::print(mlir::AsmPrinter &printer)
const {
343 isIncomplete(), getMembers(), {},
347mlir::LogicalResult StructType::verify(
348 function_ref<mlir::InFlightDiagnostic()> emitError,
349 llvm::ArrayRef<mlir::Type> members, mlir::StringAttr name,
bool incomplete,
350 bool packed, llvm::ArrayRef<RecordMemberKind> member_kinds,
bool is_class) {
351 if (name &&
name.getValue().empty())
352 return emitError() <<
"identified records cannot have an empty name";
358llvm::ArrayRef<mlir::Type> StructType::getMembers()
const {
361mlir::StringAttr StructType::getName()
const {
return getImpl()->name; }
362bool StructType::isIncomplete()
const {
return getImpl()->incomplete; }
363bool StructType::getIncomplete()
const {
return getImpl()->incomplete; }
364bool StructType::getPacked()
const {
return getImpl()->packed; }
365llvm::ArrayRef<RecordMemberKind> StructType::getMemberKinds()
const {
366 return getImpl()->member_kinds;
368bool StructType::getIsClass()
const {
return getImpl()->is_class; }
370bool StructType::getPadded()
const {
371 return llvm::is_contained(getMemberKinds(), RecordMemberKind::Pad);
374bool StructType::isABIConvertedRecord()
const {
375 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
378mlir::StringAttr StructType::getABIConvertedName()
const {
379 assert(!isABIConvertedRecord());
380 return StringAttr::get(getContext(),
381 abi_conversion_prefix +
getName().getValue());
384void StructType::removeABIConversionNamePrefix() {
385 mlir::StringAttr recordName =
getName();
386 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
387 getImpl()->name = mlir::StringAttr::get(
388 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
389 recordName.getType());
392void StructType::complete(ArrayRef<Type> members,
bool packed,
393 ArrayRef<RecordMemberKind> memberKinds) {
395 if (mutate(members, packed, memberKinds).failed())
396 llvm_unreachable(
"failed to complete struct");
399bool StructType::isLayoutIdentical(
const StructType &other) {
400 if (
getImpl() == other.getImpl())
402 if (getPacked() != other.getPacked())
404 return getMembers() == other.getMembers();
411Type UnionType::parse(mlir::AsmParser &parser) {
412 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
413 const llvm::SMLoc loc = parser.getCurrentLocation();
414 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
417 mlir::MLIRContext *context = parser.getContext();
419 if (parser.parseLess())
422 mlir::StringAttr
name;
423 parser.parseOptionalAttribute(name);
426 if (name && parser.parseOptionalGreater().succeeded()) {
427 UnionType
type = UnionType::getChecked(eLoc, context, name);
428 if (succeeded(parser.tryStartCyclicParse(type))) {
429 parser.emitError(loc,
"invalid self-reference within record");
437 UnionType
type = UnionType::getChecked(eLoc, context, name);
438 cyclicParseGuard = parser.tryStartCyclicParse(type);
439 if (failed(cyclicParseGuard)) {
440 parser.emitError(loc,
"record already defined");
445 if (parser.parseOptionalKeyword(
"packed").succeeded())
448 bool incomplete =
true;
449 llvm::SmallVector<mlir::Type> members;
450 llvm::SmallVector<RecordMemberKind> memberKinds;
451 if (
parseRecordBody(parser, incomplete, members, memberKinds).failed())
456 if (!incomplete && parser.parseOptionalComma().succeeded()) {
457 if (parser.parseKeyword(
"padding").failed())
459 if (parser.parseEqual().failed())
461 if (parser.parseLBrace().failed())
463 const llvm::SMLoc paddingLoc = parser.getCurrentLocation();
464 llvm::StringRef paddingKeyword;
467 parser.emitError(paddingLoc,
"a union's tail padding takes no kind mark");
470 if (parser.parseType(padding).failed())
472 if (parser.parseRBrace().failed())
476 if (parser.parseGreater())
479 ArrayRef<mlir::Type> membersRef(members);
480 ArrayRef<RecordMemberKind> kindsRef(memberKinds);
481 mlir::Type
type = {};
482 if (name && incomplete) {
483 type = UnionType::getChecked(eLoc, context, name);
484 }
else if (!name && !incomplete) {
485 type = UnionType::getChecked(eLoc, context, membersRef, packed, padding,
489 }
else if (!incomplete) {
490 type = UnionType::getChecked(eLoc, context, membersRef, name, packed,
494 if (
auto unionTy = mlir::dyn_cast<UnionType>(type))
495 if (unionTy.isIncomplete())
496 unionTy.complete(membersRef, packed, padding, kindsRef);
499 parser.emitError(loc,
"anonymous records must be complete");
506void UnionType::print(mlir::AsmPrinter &printer)
const {
508 getPacked(), isIncomplete(), getMembers(), getPadding(),
513UnionType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
514 llvm::ArrayRef<mlir::Type> members, mlir::StringAttr name,
515 bool incomplete,
bool packed, mlir::Type padding,
516 llvm::ArrayRef<RecordMemberKind> member_kinds) {
517 if (name &&
name.getValue().empty())
518 return emitError() <<
"identified records cannot have an empty name";
522 if (llvm::is_contained(member_kinds, RecordMemberKind::Pad))
523 return emitError() <<
"a union member cannot be marked pad";
527 for (
auto [idx, memberTy] : llvm::enumerate(members))
528 if (
auto bfTy = mlir::dyn_cast<cir::BitFieldType>(memberTy);
529 bfTy && !bfTy.ownsBytes())
530 return emitError() <<
"union bit-field member at index " << idx
531 <<
" must own its access unit storage";
536llvm::ArrayRef<mlir::Type> UnionType::getMembers()
const {
539mlir::StringAttr UnionType::getName()
const {
return getImpl()->name; }
540bool UnionType::isIncomplete()
const {
return getImpl()->incomplete; }
541bool UnionType::getIncomplete()
const {
return getImpl()->incomplete; }
542bool UnionType::getPacked()
const {
return getImpl()->packed; }
543bool UnionType::getPadded()
const {
return getPadding() ?
true :
false; }
544mlir::Type UnionType::getPadding()
const {
return getImpl()->padding; }
545llvm::ArrayRef<RecordMemberKind> UnionType::getMemberKinds()
const {
546 return getImpl()->member_kinds;
549bool UnionType::isABIConvertedRecord()
const {
550 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
553mlir::StringAttr UnionType::getABIConvertedName()
const {
554 assert(!isABIConvertedRecord());
555 return StringAttr::get(getContext(),
556 abi_conversion_prefix +
getName().getValue());
559void UnionType::removeABIConversionNamePrefix() {
560 mlir::StringAttr recordName =
getName();
561 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
562 getImpl()->name = mlir::StringAttr::get(
563 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
564 recordName.getType());
567void UnionType::complete(ArrayRef<Type> members,
bool packed,
569 ArrayRef<RecordMemberKind> memberKinds) {
571 if (mutate(members, packed, padding, memberKinds).failed())
572 llvm_unreachable(
"failed to complete union");
576UnionType::getUnionStorageType(
const mlir::DataLayout &dataLayout)
const {
577 return getUnionStorageType(dataLayout, getMembers());
580mlir::Type UnionType::getUnionStorageType(
const mlir::DataLayout &dataLayout,
581 llvm::ArrayRef<mlir::Type> members) {
584 mlir::Type largest = *std::max_element(
585 members.begin(), members.end(), [&](mlir::Type lhs, mlir::Type rhs) {
586 return dataLayout.getTypeABIAlignment(lhs) <
587 dataLayout.getTypeABIAlignment(rhs) ||
588 (dataLayout.getTypeABIAlignment(lhs) ==
589 dataLayout.getTypeABIAlignment(rhs) &&
590 dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
598bool UnionType::isLayoutIdentical(
const UnionType &other) {
599 if (
getImpl() == other.getImpl())
601 return getMembers() == other.getMembers() &&
602 getPadding() == other.getPadding();
610 if (
auto s = mlir::dyn_cast<StructType>(*
this))
611 return s.getMembers();
612 return mlir::cast<UnionType>(*this).getMembers();
615 if (
auto s = mlir::dyn_cast<StructType>(*
this))
617 return mlir::cast<UnionType>(*this).getName();
620 if (
auto s = mlir::dyn_cast<StructType>(*
this))
621 return s.isIncomplete();
622 return mlir::cast<UnionType>(*this).isIncomplete();
625 if (
auto s = mlir::dyn_cast<StructType>(*
this))
626 return s.getPacked();
627 return mlir::cast<UnionType>(*this).getPacked();
630 if (
auto s = mlir::dyn_cast<StructType>(*
this))
631 return s.getPadded();
632 return mlir::cast<UnionType>(*this).getPadded();
635 if (
auto s = mlir::dyn_cast<StructType>(*
this))
636 return s.getMemberKinds();
637 return mlir::cast<UnionType>(*this).getMemberKinds();
640 if (
auto s = mlir::dyn_cast<StructType>(*
this))
645 if (
auto s = mlir::dyn_cast<StructType>(*
this))
650 if (mlir::isa<UnionType>(*
this))
652 return mlir::cast<StructType>(*this).getKindAsStr();
660 if (
auto s = mlir::dyn_cast<StructType>(*
this)) {
661 assert(!padding &&
"only a union takes a separate padding slot");
662 return s.complete(members, packed, memberKinds);
664 return mlir::cast<UnionType>(*this).complete(members, packed, padding,
668 unsigned idx)
const {
669 if (mlir::isa<UnionType>(*
this))
671 return mlir::cast<StructType>(*this).getElementOffset(dataLayout, idx);
674 if (
auto s = mlir::dyn_cast<StructType>(*
this)) {
675 if (
auto so = mlir::dyn_cast<StructType>(other))
676 return s.isLayoutIdentical(so);
679 if (
auto u = mlir::dyn_cast<UnionType>(*
this)) {
680 if (
auto uo = mlir::dyn_cast<UnionType>(other))
681 return u.isLayoutIdentical(uo);
687 if (
auto s = mlir::dyn_cast<StructType>(*
this))
688 return s.isABIConvertedRecord();
689 return mlir::cast<UnionType>(*this).isABIConvertedRecord();
692 if (
auto s = mlir::dyn_cast<StructType>(*
this))
693 return s.getABIConvertedName();
694 return mlir::cast<UnionType>(*this).getABIConvertedName();
697 if (
auto s = mlir::dyn_cast<StructType>(*
this))
698 return s.removeABIConversionNamePrefix();
699 return mlir::cast<UnionType>(*this).removeABIConversionNamePrefix();
713 return llvm::none_of(
getMembers(), [](mlir::Type memberTy) {
714 auto bfTy = mlir::dyn_cast<cir::BitFieldType>(memberTy);
715 return bfTy && bfTy.ownsBytes();
726constexpr static uint64_t kBitsInByte = 8;
729constexpr static uint64_t kDefaultPointerSizeBits = 64;
730constexpr static uint64_t kDefaultPointerAlignment = 8;
734cir::PtrSpecAttr getPointerSpec(mlir::DataLayoutEntryListRef params,
735 cir::PointerType type) {
738 for (mlir::DataLayoutEntryInterface entry : params) {
739 if (!entry.isTypeEntry())
742 mlir::cast<cir::PointerType>(mlir::cast<mlir::Type>(entry.getKey()));
743 if (key.getAddrSpace())
745 if (
auto spec = mlir::dyn_cast<cir::PtrSpecAttr>(entry.getValue()))
748 return cir::PtrSpecAttr::get(type.getContext(), kDefaultPointerSizeBits,
749 kDefaultPointerAlignment * kBitsInByte,
750 kDefaultPointerAlignment * kBitsInByte,
751 kDefaultPointerSizeBits);
756PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
757 ::mlir::DataLayoutEntryListRef params)
const {
758 return llvm::TypeSize::getFixed(getPointerSpec(params, *
this).getSize());
762PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
763 ::mlir::DataLayoutEntryListRef params)
const {
764 return getPointerSpec(params, *
this).getAbi() / kBitsInByte;
767uint64_t PointerType::getPreferredAlignment(
768 const ::mlir::DataLayout &dataLayout,
769 ::mlir::DataLayoutEntryListRef params)
const {
770 return getPointerSpec(params, *
this).getPreferred() / kBitsInByte;
773std::optional<uint64_t>
774PointerType::getIndexBitwidth(const ::mlir::DataLayout &dataLayout,
775 ::mlir::DataLayoutEntryListRef params)
const {
776 cir::PtrSpecAttr spec = getPointerSpec(params, *
this);
777 if (spec.getIndex() == cir::PtrSpecAttr::kOptionalSpecValue)
778 return spec.getSize();
779 return spec.getIndex();
783PointerType::verifyEntries(mlir::DataLayoutEntryListRef entries,
784 mlir::Location loc)
const {
785 for (mlir::DataLayoutEntryInterface entry : entries) {
786 if (!entry.isTypeEntry())
788 auto key = mlir::cast<PointerType>(mlir::cast<mlir::Type>(entry.getKey()));
789 if (!mlir::isa<cir::PtrSpecAttr>(entry.getValue()))
790 return mlir::emitError(loc) <<
"expected layout attribute for " << key
791 <<
" to be a #cir.ptr_spec attribute";
792 if (!mlir::isa<cir::VoidType>(key.getPointee()))
793 return mlir::emitError(loc) <<
"expected !cir.ptr data layout entry for "
794 << key <<
" to use !cir.void as pointee";
796 if (key.getAddrSpace())
797 return mlir::emitError(loc)
798 <<
"!cir.ptr data layout entries are currently limited to the "
799 "default address space";
801 return mlir::success();
804bool PointerType::areCompatible(
805 mlir::DataLayoutEntryListRef oldLayout,
806 mlir::DataLayoutEntryListRef newLayout, mlir::DataLayoutSpecInterface,
807 const mlir::DataLayoutIdentifiedEntryMap &)
const {
810 cir::PtrSpecAttr oldSpec = getPointerSpec(oldLayout, *
this);
813 for (mlir::DataLayoutEntryInterface newEntry : newLayout) {
814 if (!newEntry.isTypeEntry())
816 auto newSpec = mlir::cast<cir::PtrSpecAttr>(newEntry.getValue());
817 if (size != newSpec.getSize() || abi < newSpec.getAbi() ||
818 abi % newSpec.getAbi() != 0)
825StructType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
826 mlir::DataLayoutEntryListRef params)
const {
827 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
828 return llvm::TypeSize::getFixed(recordSize * 8);
832StructType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
833 ::mlir::DataLayoutEntryListRef params)
const {
837 return computeStructAlignment(dataLayout);
844UnionType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
845 mlir::DataLayoutEntryListRef params)
const {
846 llvm::TypeSize size = llvm::TypeSize::getFixed(0);
847 if (mlir::Type storage = getUnionStorageType(dataLayout))
848 size += dataLayout.getTypeSizeInBits(storage);
849 if (mlir::Type pad = getPadding())
850 size += dataLayout.getTypeSizeInBits(pad);
855UnionType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
856 ::mlir::DataLayoutEntryListRef params)
const {
859 mlir::Type storage = getUnionStorageType(dataLayout);
862 return dataLayout.getTypeABIAlignment(storage);
866StructType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
867 assert(isComplete() &&
"Cannot get layout of incomplete records");
872 unsigned recordSize = 0;
875 for (mlir::Type ty : getMembers()) {
879 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
883 recordSize = llvm::alignTo(recordSize, tyAlign);
884 recordSize += dataLayout.getTypeSize(ty);
888 recordAlignment = std::max(tyAlign, recordAlignment);
893 recordSize = llvm::alignTo(recordSize, recordAlignment);
898StructType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
899 assert(isComplete() &&
"Cannot get layout of incomplete records");
904 llvm::ArrayRef<mlir::Type> members = getMembers();
905 llvm::ArrayRef<RecordMemberKind> kinds = getMemberKinds();
906 assert(kinds.size() == members.size() &&
907 "the two drop_back calls below must stay in step");
908 while (!kinds.empty() && (kinds.back() == RecordMemberKind::Pad ||
910 kinds = kinds.drop_back();
911 members = members.drop_back();
914 unsigned recordSize = 0;
915 for (mlir::Type ty : members) {
917 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
918 recordSize = llvm::alignTo(recordSize, tyAlign);
919 recordSize += dataLayout.getTypeSize(ty);
929StructType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
930 assert(isComplete() &&
"Cannot get layout of incomplete records");
933 for (mlir::Type ty : getMembers())
935 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
936 return recordAlignment;
939unsigned StructType::getLLVMFieldIndex(
unsigned idx)
const {
940 llvm::ArrayRef<mlir::Type> members = getMembers();
941 assert(idx < members.size() &&
"access not valid");
943 "a member that owns no bytes has no LLVM field");
945 unsigned llvmIdx = 0;
946 for (
unsigned i = 0; i != idx; ++i)
952uint64_t StructType::getElementOffset(const ::mlir::DataLayout &dataLayout,
953 unsigned idx)
const {
954 assert(idx < getMembers().size() &&
"access not valid");
958 assert(isComplete() &&
"Cannot get layout of incomplete records");
959 llvm::ArrayRef<mlir::Type> members = getMembers();
965 for (
unsigned i = 0; i != idx; ++i) {
966 const llvm::Align tyAlign = llvm::Align(
967 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[i]));
968 offset = llvm::alignTo(offset, tyAlign);
969 offset += dataLayout.getTypeSize(members[i]);
972 const llvm::Align tyAlign = llvm::Align(
973 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
974 return llvm::alignTo(offset, tyAlign);
981Type IntType::parse(mlir::AsmParser &parser) {
982 mlir::MLIRContext *context = parser.getBuilder().getContext();
983 llvm::SMLoc loc = parser.getCurrentLocation();
987 if (parser.parseLess())
991 llvm::StringRef
sign;
992 if (parser.parseKeyword(&
sign))
996 else if (
sign ==
"u")
999 parser.emitError(loc,
"expected 's' or 'u'");
1003 if (parser.parseComma())
1007 if (parser.parseInteger(width))
1009 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
1010 parser.emitError(loc,
"expected integer width to be from ")
1011 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
1015 bool isBitInt =
false;
1016 if (succeeded(parser.parseOptionalComma())) {
1018 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
1019 parser.emitError(loc,
"expected 'bitint'");
1025 if (parser.parseGreater())
1028 return IntType::get(context, width, isSigned, isBitInt);
1031void IntType::print(mlir::AsmPrinter &printer)
const {
1032 char sign = isSigned() ?
's' :
'u';
1033 printer <<
'<' <<
sign <<
", " << getWidth();
1035 printer <<
", bitint";
1040IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1041 mlir::DataLayoutEntryListRef params)
const {
1042 return llvm::TypeSize::getFixed(getStorageTypeWidth(dataLayout));
1046IntType::getStorageTypeWidth(
const mlir::DataLayout &dataLayout)
const {
1049 uint64_t alignBits = getABIAlignment(dataLayout, {}) * 8;
1050 return static_cast<unsigned>(llvm::alignTo(getWidth(), alignBits));
1054IntType::getStorageTypeAlignment(
const mlir::DataLayout &dataLayout)
const {
1056 return getABIAlignment(dataLayout, {});
1058 mlir::IntegerType::get(getContext(), getStorageTypeWidth(dataLayout));
1059 return dataLayout.getTypeABIAlignment(storageTy);
1062uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1063 mlir::DataLayoutEntryListRef params)
const {
1064 unsigned width = getWidth();
1069 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
1070 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
1077 uint64_t alignBits = llvm::PowerOf2Ceil(width);
1078 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
1082IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1083 unsigned width,
bool isSigned,
bool isBitInt) {
1084 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
1085 return emitError() <<
"IntType only supports widths from "
1086 << IntType::minBitwidth() <<
" up to "
1087 << IntType::maxBitwidth();
1088 return mlir::success();
1092 return width == 8 || width == 16 || width == 32 || width == 64;
1099const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
1100 return llvm::APFloat::IEEEsingle();
1104SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1105 mlir::DataLayoutEntryListRef params)
const {
1106 return llvm::TypeSize::getFixed(getWidth());
1110SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1111 mlir::DataLayoutEntryListRef params)
const {
1112 return (uint64_t)(getWidth() / 8);
1115const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
1116 return llvm::APFloat::IEEEdouble();
1120DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1121 mlir::DataLayoutEntryListRef params)
const {
1122 return llvm::TypeSize::getFixed(getWidth());
1126DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1127 mlir::DataLayoutEntryListRef params)
const {
1128 return (uint64_t)(getWidth() / 8);
1131const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
1132 return llvm::APFloat::IEEEhalf();
1136FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1137 mlir::DataLayoutEntryListRef params)
const {
1138 return llvm::TypeSize::getFixed(getWidth());
1141uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1142 mlir::DataLayoutEntryListRef params)
const {
1143 return (uint64_t)(getWidth() / 8);
1146const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
1147 return llvm::APFloat::BFloat();
1151BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1152 mlir::DataLayoutEntryListRef params)
const {
1153 return llvm::TypeSize::getFixed(getWidth());
1156uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1157 mlir::DataLayoutEntryListRef params)
const {
1158 return (uint64_t)(getWidth() / 8);
1161const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
1162 return llvm::APFloat::x87DoubleExtended();
1166FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1167 mlir::DataLayoutEntryListRef params)
const {
1169 return llvm::TypeSize::getFixed(128);
1172uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1173 mlir::DataLayoutEntryListRef params)
const {
1177const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
1178 return llvm::APFloat::IEEEquad();
1182FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1183 mlir::DataLayoutEntryListRef params)
const {
1184 return llvm::TypeSize::getFixed(getWidth());
1187uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
1188 mlir::DataLayoutEntryListRef params)
const {
1192const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
1193 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
1197LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1198 mlir::DataLayoutEntryListRef params)
const {
1199 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
1200 .getTypeSizeInBits(dataLayout, params);
1204LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1205 mlir::DataLayoutEntryListRef params)
const {
1206 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
1207 .getABIAlignment(dataLayout, params);
1215cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1216 mlir::DataLayoutEntryListRef params)
const {
1222 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
1226cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1227 mlir::DataLayoutEntryListRef params)
const {
1233 return dataLayout.getTypeABIAlignment(getElementType());
1236FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
1237 assert(results.size() == 1 &&
"expected exactly one result type");
1238 return get(llvm::to_vector(inputs), results[0], isVarArg());
1242static mlir::ParseResult
1246 return p.parseCommaSeparatedList(
1247 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
1249 return p.emitError(p.getCurrentLocation(),
1250 "variadic `...` must be the last parameter");
1251 if (succeeded(p.parseOptionalEllipsis())) {
1256 if (failed(p.parseType(type)))
1258 params.push_back(type);
1264 mlir::ArrayRef<mlir::Type> params,
1267 llvm::interleaveComma(params, p,
1268 [&p](mlir::Type type) { p.printType(type); });
1270 if (!params.empty())
1279mlir::Type FuncType::getReturnType()
const {
1280 if (hasVoidReturn())
1281 return cir::VoidType::get(getContext());
1282 return getOptionalReturnType();
1288llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
1289 if (hasVoidReturn())
1294 return getImpl()->optionalReturnType;
1298bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
1301FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1302 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
1304 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
1306 <<
"!cir.func cannot have an explicit 'void' return type";
1310 for (mlir::Type type : argTypes) {
1313 <<
"expected all types in the function signature to be CIR types";
1317 <<
"expected all types in the function signature to be CIR types";
1319 return mlir::success();
1331 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
1332 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
1333 return cir::StructType::get(ctx, fields,
false,
1339MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1340 mlir::DataLayoutEntryListRef params)
const {
1345MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1346 mlir::DataLayoutEntryListRef params)
const {
1348 .getABIAlignment(dataLayout, params);
1356BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1357 ::mlir::DataLayoutEntryListRef params)
const {
1358 return llvm::TypeSize::getFixed(8);
1362BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1363 ::mlir::DataLayoutEntryListRef params)
const {
1372 mlir::MLIRContext *ctx) {
1376 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
1377 uint64_t width = dataLayout.getTypeIndexBitwidth(voidPtrTy).value_or(
1378 dataLayout.getTypeSizeInBits(voidPtrTy).getFixedValue());
1379 return cir::IntType::get(ctx, width,
true);
1383DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1384 ::mlir::DataLayoutEntryListRef params)
const {
1386 return dataLayout.getTypeSizeInBits(
1391DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1392 ::mlir::DataLayoutEntryListRef params)
const {
1394 return dataLayout.getTypeABIAlignment(
1403VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1404 mlir::DataLayoutEntryListRef params)
const {
1406 return dataLayout.getTypeSizeInBits(
1407 cir::PointerType::get(cir::VoidType::get(getContext())));
1410uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1411 mlir::DataLayoutEntryListRef params)
const {
1412 return dataLayout.getTypeABIAlignment(
1413 cir::PointerType::get(cir::VoidType::get(getContext())));
1421ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1422 ::mlir::DataLayoutEntryListRef params)
const {
1423 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
1427ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1428 ::mlir::DataLayoutEntryListRef params)
const {
1429 return dataLayout.getTypeABIAlignment(getElementType());
1437BitFieldType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1438 mlir::Type storageType,
1439 llvm::ArrayRef<cir::BitFieldDeclAttr> fields) {
1441 return emitError() <<
"bit-field member must hold at least one bit-field";
1446 if (fields.size() != 1 || fields.front().getWidth() != 0)
1447 return emitError() <<
"a bit-field member without storage must hold a "
1448 "single zero-width bit-field";
1449 return mlir::success();
1452 if (mlir::isa<cir::BitFieldType>(storageType))
1453 return emitError() <<
"bit-field access unit storage cannot itself be a "
1457 return emitError() <<
"bit-field access unit storage must be sized, got "
1462 if (llvm::any_of(fields, [](cir::BitFieldDeclAttr decl) {
1463 return decl.getWidth() == 0;
1465 return emitError() <<
"a zero-width bit-field cannot occupy an access unit";
1467 return mlir::success();
1471BitFieldType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1472 mlir::DataLayoutEntryListRef params)
const {
1475 if (mlir::Type storage = getStorageType())
1476 return dataLayout.getTypeSizeInBits(storage);
1477 return llvm::TypeSize::getFixed(0);
1481BitFieldType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1482 mlir::DataLayoutEntryListRef params)
const {
1485 if (mlir::Type storage = getStorageType())
1486 return dataLayout.getTypeABIAlignment(storage);
1494llvm::TypeSize cir::VectorType::getTypeSizeInBits(
1495 const ::mlir::DataLayout &dataLayout,
1496 ::mlir::DataLayoutEntryListRef params)
const {
1497 return llvm::TypeSize::getFixed(
1498 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
1502cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1503 ::mlir::DataLayoutEntryListRef params)
const {
1505 return llvm::PowerOf2Ceil(
1506 llvm::divideCeil(dataLayout.getTypeSizeInBits(*
this), 8u));
1509mlir::LogicalResult cir::VectorType::verify(
1510 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1511 mlir::Type elementType, uint64_t size,
bool scalable) {
1513 return emitError() <<
"the number of vector elements must be non-zero";
1517mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
1519 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
1520 mlir::Builder odsBuilder(odsParser.getContext());
1521 mlir::FailureOr<::mlir::Type> elementType;
1522 mlir::FailureOr<uint64_t> size;
1523 bool isScalabe =
false;
1526 if (odsParser.parseLess())
1530 if (odsParser.parseOptionalLSquare().succeeded())
1534 size = mlir::FieldParser<uint64_t>::parse(odsParser);
1535 if (mlir::failed(size)) {
1536 odsParser.emitError(odsParser.getCurrentLocation(),
1537 "failed to parse CIR_VectorType parameter 'size' which "
1538 "is to be a `uint64_t`");
1544 if (isScalabe && odsParser.parseRSquare().failed()) {
1545 odsParser.emitError(odsParser.getCurrentLocation(),
1546 "missing closing `]` for scalable dim size");
1551 if (odsParser.parseKeyword(
"x"))
1555 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
1556 if (mlir::failed(elementType)) {
1557 odsParser.emitError(odsParser.getCurrentLocation(),
1558 "failed to parse CIR_VectorType parameter "
1559 "'elementType' which is to be a `mlir::Type`");
1564 if (odsParser.parseGreater())
1566 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
1567 mlir::Type((*elementType)),
1571void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
1572 mlir::Builder odsBuilder(getContext());
1574 if (this->getIsScalable())
1577 odsPrinter.printStrippedAttrOrType(getSize());
1578 if (this->getIsScalable())
1580 odsPrinter <<
' ' <<
"x";
1582 odsPrinter.printStrippedAttrOrType(getElementType());
1591 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1592 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1599 case LangAS::Default:
1600 return LangAddressSpace::Default;
1601 case LangAS::opencl_global:
1602 return LangAddressSpace::OffloadGlobal;
1603 case LangAS::opencl_local:
1604 case LangAS::cuda_shared:
1607 return LangAddressSpace::OffloadLocal;
1608 case LangAS::cuda_device:
1609 return LangAddressSpace::OffloadGlobal;
1610 case LangAS::opencl_constant:
1611 case LangAS::cuda_constant:
1612 return LangAddressSpace::OffloadConstant;
1613 case LangAS::opencl_private:
1614 return LangAddressSpace::OffloadPrivate;
1615 case LangAS::opencl_generic:
1616 return LangAddressSpace::OffloadGeneric;
1617 case LangAS::opencl_global_device:
1618 return LangAddressSpace::OffloadGlobalDevice;
1619 case LangAS::opencl_global_host:
1620 return LangAddressSpace::OffloadGlobalHost;
1621 case LangAS::sycl_global:
1622 case LangAS::sycl_global_device:
1623 case LangAS::sycl_global_host:
1624 case LangAS::sycl_local:
1625 case LangAS::sycl_private:
1626 case LangAS::ptr32_sptr:
1627 case LangAS::ptr32_uptr:
1629 case LangAS::hlsl_groupshared:
1630 case LangAS::wasm_funcref:
1631 llvm_unreachable(
"NYI");
1633 llvm_unreachable(
"unknown/unsupported clang language address space");
1638 mlir::ptr::MemorySpaceAttrInterface &attr) {
1640 llvm::SMLoc loc = p.getCurrentLocation();
1644 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1646 if (p.parseLParen())
1647 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1649 if (p.parseInteger(val))
1650 return p.emitError(loc,
"expected target address space value");
1652 if (p.parseRParen())
1653 return p.emitError(loc,
"expected ')'");
1655 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1656 return mlir::success();
1660 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1661 if (p.parseLParen())
1662 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1664 mlir::FailureOr<cir::LangAddressSpace> result =
1665 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1666 if (mlir::failed(result))
1667 return mlir::failure();
1669 if (p.parseRParen())
1670 return p.emitError(loc,
"expected ')'");
1672 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1673 return mlir::success();
1676 llvm::StringRef keyword;
1677 if (p.parseOptionalKeyword(&keyword).succeeded())
1678 return p.emitError(loc,
"unknown address space specifier '")
1679 << keyword <<
"'; expected 'target_address_space' or "
1680 <<
"'lang_address_space'";
1682 return mlir::success();
1686 mlir::ptr::MemorySpaceAttrInterface attr) {
1690 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1691 p <<
"lang_address_space("
1692 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1696 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1697 p <<
"target_address_space(" << target.getValue() <<
')';
1701 llvm_unreachable(
"unexpected address-space attribute kind");
1704mlir::OptionalParseResult
1706 mlir::ptr::MemorySpaceAttrInterface &attr) {
1708 mlir::SMLoc loc = p.getCurrentLocation();
1710 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1711 return mlir::success();
1715 mlir::ptr::MemorySpaceAttrInterface attr) {
1720 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1722 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1723 if (langAS.getValue() == cir::LangAddressSpace::Default)
1728mlir::ptr::MemorySpaceAttrInterface
1732 if (langAS == LangAS::Default)
1733 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1737 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1750 return expected == cirAS;
1757mlir::LogicalResult cir::PointerType::verify(
1758 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1759 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1762 return emitError() <<
"unsupported address space attribute; expected "
1763 "'target_address_space' or 'lang_address_space'";
1774void CIRDialect::registerTypes() {
1777#define GET_TYPEDEF_LIST
1778#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 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 bool isPureCIRType(mlir::Type ty)
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()