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,
92 mlir::ptr::MemorySpaceAttrInterface &attr);
95 mlir::ptr::MemorySpaceAttrInterface attr);
99 cir::TargetAddressSpaceAttr &attr);
102 cir::TargetAddressSpaceAttr attr);
110#include "clang/CIR/Dialect/IR/CIRTypeConstraints.cpp.inc"
114#define GET_TYPEDEF_CLASSES
115#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
124Type CIRDialect::parseType(DialectAsmParser &parser)
const {
125 llvm::SMLoc typeLoc = parser.getCurrentLocation();
126 llvm::StringRef mnemonic;
130 OptionalParseResult parseResult =
131 generatedTypeParser(parser, &mnemonic, genType);
132 if (parseResult.has_value())
136 parser.emitError(typeLoc) <<
"unknown CIR type: " << mnemonic;
140void CIRDialect::printType(Type type, DialectAsmPrinter &os)
const {
142 if (generatedTypePrinter(type, os).succeeded())
146 llvm::report_fatal_error(
"printer is missing a handler for this type");
157static mlir::ParseResult
160 assert(incomplete &&
"caller must pre-initialize incomplete to true");
161 if (parser.parseOptionalKeyword(
"incomplete").succeeded())
162 return mlir::success();
164 return parser.parseCommaSeparatedList(
165 AsmParser::Delimiter::Braces, [&parser, &members]() {
166 return parser.parseType(members.emplace_back());
174template <
typename RecordTy>
176 mlir::StringAttr name,
bool hasClassPrefix,
177 bool isPacked,
bool isPadded,
bool isIncomplete,
179 mlir::Type padding = {}) {
186 FailureOr<AsmPrinter::CyclicPrintReset> cyclicPrintGuard =
187 printer.tryStartCyclicPrint(self);
188 if (failed(cyclicPrintGuard)) {
193 if (hasClassPrefix || name)
196 printer <<
"packed ";
198 printer <<
"padded ";
200 printer <<
"incomplete";
203 llvm::interleaveComma(members, printer);
206 printer <<
", padding = {";
207 printer.printType(padding);
215Type StructType::parse(mlir::AsmParser &parser) {
216 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
217 const llvm::SMLoc loc = parser.getCurrentLocation();
218 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
221 mlir::MLIRContext *context = parser.getContext();
223 if (parser.parseLess())
227 bool is_class = parser.parseOptionalKeyword(
"class").succeeded();
229 mlir::StringAttr
name;
230 parser.parseOptionalAttribute(name);
233 if (name && parser.parseOptionalGreater().succeeded()) {
234 StructType type = StructType::getChecked(eLoc, context, name, is_class);
235 if (succeeded(parser.tryStartCyclicParse(type))) {
236 parser.emitError(loc,
"invalid self-reference within record");
244 StructType type = StructType::getChecked(eLoc, context, name, is_class);
245 cyclicParseGuard = parser.tryStartCyclicParse(type);
246 if (failed(cyclicParseGuard)) {
247 parser.emitError(loc,
"record already defined");
252 if (parser.parseOptionalKeyword(
"packed").succeeded())
255 if (parser.parseOptionalKeyword(
"padded").succeeded())
258 bool incomplete =
true;
263 if (parser.parseGreater())
267 mlir::Type type = {};
268 if (name && incomplete) {
269 type = StructType::getChecked(eLoc, context, name, is_class);
270 }
else if (!name && !incomplete) {
271 type = StructType::getChecked(eLoc, context, membersRef, packed, padded,
275 }
else if (!incomplete) {
276 type = StructType::getChecked(eLoc, context, membersRef, name, packed,
280 if (
auto structTy = mlir::dyn_cast<StructType>(type))
281 if (structTy.isIncomplete())
282 structTy.complete(membersRef, packed, padded);
285 parser.emitError(loc,
"anonymous records must be complete");
292void StructType::print(mlir::AsmPrinter &printer)
const {
294 getPadded(), isIncomplete(), getMembers());
298StructType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
300 bool incomplete,
bool packed,
bool padded,
bool is_class) {
301 if (name &&
name.getValue().empty())
302 return emitError() <<
"identified records cannot have an empty name";
303 return mlir::success();
311mlir::StringAttr StructType::getName()
const {
return getImpl()->name; }
312bool StructType::isIncomplete()
const {
return getImpl()->incomplete; }
313bool StructType::getIncomplete()
const {
return getImpl()->incomplete; }
314bool StructType::getPacked()
const {
return getImpl()->packed; }
315bool StructType::getPadded()
const {
return getImpl()->padded; }
316bool StructType::getIsClass()
const {
return getImpl()->is_class; }
318bool StructType::isABIConvertedRecord()
const {
319 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
322mlir::StringAttr StructType::getABIConvertedName()
const {
323 assert(!isABIConvertedRecord());
324 return StringAttr::get(getContext(),
325 abi_conversion_prefix +
getName().getValue());
328void StructType::removeABIConversionNamePrefix() {
329 mlir::StringAttr recordName =
getName();
330 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
331 getImpl()->name = mlir::StringAttr::get(
332 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
333 recordName.getType());
336void StructType::complete(
ArrayRef<Type> members,
bool packed,
bool padded) {
338 if (mutate(members, packed, padded).failed())
339 llvm_unreachable(
"failed to complete struct");
342bool StructType::isLayoutIdentical(
const StructType &other) {
343 if (
getImpl() == other.getImpl())
345 if (getPacked() != other.getPacked())
347 return getMembers() == other.getMembers();
354Type UnionType::parse(mlir::AsmParser &parser) {
355 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
356 const llvm::SMLoc loc = parser.getCurrentLocation();
357 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
360 mlir::MLIRContext *context = parser.getContext();
362 if (parser.parseLess())
365 mlir::StringAttr
name;
366 parser.parseOptionalAttribute(name);
369 if (name && parser.parseOptionalGreater().succeeded()) {
370 UnionType type = UnionType::getChecked(eLoc, context, name);
371 if (succeeded(parser.tryStartCyclicParse(type))) {
372 parser.emitError(loc,
"invalid self-reference within record");
380 UnionType type = UnionType::getChecked(eLoc, context, name);
381 cyclicParseGuard = parser.tryStartCyclicParse(type);
382 if (failed(cyclicParseGuard)) {
383 parser.emitError(loc,
"record already defined");
388 if (parser.parseOptionalKeyword(
"packed").succeeded())
391 bool incomplete =
true;
397 if (!incomplete && parser.parseOptionalComma().succeeded()) {
398 if (parser.parseKeyword(
"padding").failed())
400 if (parser.parseEqual().failed())
402 if (parser.parseLBrace().failed())
404 if (parser.parseType(padding).failed())
406 if (parser.parseRBrace().failed())
410 if (parser.parseGreater())
414 mlir::Type type = {};
415 if (name && incomplete) {
416 type = UnionType::getChecked(eLoc, context, name);
417 }
else if (!name && !incomplete) {
418 type = UnionType::getChecked(eLoc, context, membersRef, packed, padding);
421 }
else if (!incomplete) {
423 UnionType::getChecked(eLoc, context, membersRef, name, packed, padding);
426 if (
auto unionTy = mlir::dyn_cast<UnionType>(type))
427 if (unionTy.isIncomplete())
428 unionTy.complete(membersRef, packed, padding);
431 parser.emitError(loc,
"anonymous records must be complete");
438void UnionType::print(mlir::AsmPrinter &printer)
const {
440 getPacked(),
false, isIncomplete(), getMembers(),
445UnionType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
447 bool incomplete,
bool packed, mlir::Type padding) {
448 if (name &&
name.getValue().empty())
449 return emitError() <<
"identified records cannot have an empty name";
450 return mlir::success();
457mlir::StringAttr UnionType::getName()
const {
return getImpl()->name; }
458bool UnionType::isIncomplete()
const {
return getImpl()->incomplete; }
459bool UnionType::getIncomplete()
const {
return getImpl()->incomplete; }
460bool UnionType::getPacked()
const {
return getImpl()->packed; }
461bool UnionType::getPadded()
const {
return getPadding() ?
true :
false; }
462mlir::Type UnionType::getPadding()
const {
return getImpl()->padding; }
464bool UnionType::isABIConvertedRecord()
const {
465 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
468mlir::StringAttr UnionType::getABIConvertedName()
const {
469 assert(!isABIConvertedRecord());
470 return StringAttr::get(getContext(),
471 abi_conversion_prefix +
getName().getValue());
474void UnionType::removeABIConversionNamePrefix() {
475 mlir::StringAttr recordName =
getName();
476 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
477 getImpl()->name = mlir::StringAttr::get(
478 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
479 recordName.getType());
483 mlir::Type padding) {
485 if (mutate(members, packed, padding).failed())
486 llvm_unreachable(
"failed to complete union");
490UnionType::getUnionStorageType(
const mlir::DataLayout &dataLayout)
const {
491 return getUnionStorageType(dataLayout, getMembers());
494mlir::Type UnionType::getUnionStorageType(
const mlir::DataLayout &dataLayout,
498 return *std::max_element(
499 members.begin(), members.end(), [&](mlir::Type lhs, mlir::Type rhs) {
500 return dataLayout.getTypeABIAlignment(lhs) <
501 dataLayout.getTypeABIAlignment(rhs) ||
502 (dataLayout.getTypeABIAlignment(lhs) ==
503 dataLayout.getTypeABIAlignment(rhs) &&
504 dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
508bool UnionType::isLayoutIdentical(
const UnionType &other) {
509 if (
getImpl() == other.getImpl())
511 return getMembers() == other.getMembers() &&
512 getPadding() == other.getPadding();
520 if (
auto s = mlir::dyn_cast<StructType>(*
this))
521 return s.getMembers();
522 return mlir::cast<UnionType>(*this).getMembers();
525 if (
auto s = mlir::dyn_cast<StructType>(*
this))
527 return mlir::cast<UnionType>(*this).getName();
530 if (
auto s = mlir::dyn_cast<StructType>(*
this))
531 return s.isIncomplete();
532 return mlir::cast<UnionType>(*this).isIncomplete();
535 if (
auto s = mlir::dyn_cast<StructType>(*
this))
536 return s.getPacked();
537 return mlir::cast<UnionType>(*this).getPacked();
540 if (
auto s = mlir::dyn_cast<StructType>(*
this))
541 return s.getPadded();
542 return mlir::cast<UnionType>(*this).getPadded();
545 if (
auto s = mlir::dyn_cast<StructType>(*
this))
550 if (
auto s = mlir::dyn_cast<StructType>(*
this))
555 if (mlir::isa<UnionType>(*
this))
557 return mlir::cast<StructType>(*this).getKindAsStr();
563 mlir::Type padding) {
564 if (
auto s = mlir::dyn_cast<StructType>(*
this))
565 return s.complete(members, packed, padded);
567 assert((!padded || padding) &&
568 "padded=true requires a non-null padding type");
569 return mlir::cast<UnionType>(*this).complete(members, packed, padding);
572 unsigned idx)
const {
573 if (mlir::isa<UnionType>(*
this))
575 return mlir::cast<StructType>(*this).getElementOffset(dataLayout, idx);
578 if (
auto s = mlir::dyn_cast<StructType>(*
this)) {
579 if (
auto so = mlir::dyn_cast<StructType>(other))
580 return s.isLayoutIdentical(so);
583 if (
auto u = mlir::dyn_cast<UnionType>(*
this)) {
584 if (
auto uo = mlir::dyn_cast<UnionType>(other))
585 return u.isLayoutIdentical(uo);
591 if (
auto s = mlir::dyn_cast<StructType>(*
this))
592 return s.isABIConvertedRecord();
593 return mlir::cast<UnionType>(*this).isABIConvertedRecord();
596 if (
auto s = mlir::dyn_cast<StructType>(*
this))
597 return s.getABIConvertedName();
598 return mlir::cast<UnionType>(*this).getABIConvertedName();
601 if (
auto s = mlir::dyn_cast<StructType>(*
this))
602 return s.removeABIConversionNamePrefix();
603 return mlir::cast<UnionType>(*this).removeABIConversionNamePrefix();
611PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
612 ::mlir::DataLayoutEntryListRef params)
const {
615 return llvm::TypeSize::getFixed(64);
619PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
620 ::mlir::DataLayoutEntryListRef params)
const {
627StructType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
628 mlir::DataLayoutEntryListRef params)
const {
629 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
630 return llvm::TypeSize::getFixed(recordSize * 8);
634StructType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
635 ::mlir::DataLayoutEntryListRef params)
const {
639 return computeStructAlignment(dataLayout);
643UnionType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
644 mlir::DataLayoutEntryListRef params)
const {
645 mlir::Type storage = getUnionStorageType(dataLayout);
647 return llvm::TypeSize::getFixed(0);
653 llvm::TypeSize size = dataLayout.getTypeSizeInBits(storage);
654 if (mlir::Type pad = getPadding())
655 size += dataLayout.getTypeSizeInBits(pad);
660UnionType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
661 ::mlir::DataLayoutEntryListRef params)
const {
662 mlir::Type storage = getUnionStorageType(dataLayout);
665 return dataLayout.getTypeABIAlignment(storage);
669StructType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
670 assert(isComplete() &&
"Cannot get layout of incomplete records");
673 unsigned recordSize = 0;
676 for (mlir::Type ty : getMembers()) {
680 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
684 recordSize = llvm::alignTo(recordSize, tyAlign);
685 recordSize += dataLayout.getTypeSize(ty);
689 recordAlignment = std::max(tyAlign, recordAlignment);
694 recordSize = llvm::alignTo(recordSize, recordAlignment);
699StructType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
700 assert(isComplete() &&
"Cannot get layout of incomplete records");
707 auto members = getMembers();
708 unsigned numMembers =
709 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
710 unsigned recordSize = 0;
711 for (
unsigned i = 0; i < numMembers; ++i) {
712 mlir::Type ty = members[i];
714 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
715 recordSize = llvm::alignTo(recordSize, tyAlign);
716 recordSize += dataLayout.getTypeSize(ty);
726StructType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
727 assert(isComplete() &&
"Cannot get layout of incomplete records");
730 for (mlir::Type ty : getMembers())
732 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
733 return recordAlignment;
736uint64_t StructType::getElementOffset(const ::mlir::DataLayout &dataLayout,
737 unsigned idx)
const {
738 assert(idx < getMembers().size() &&
"access not valid");
742 assert(isComplete() &&
"Cannot get layout of incomplete records");
743 assert(idx < getNumElements());
744 llvm::ArrayRef<mlir::Type> members = getMembers();
748 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
749 const llvm::Align tyAlign =
750 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
751 offset = llvm::alignTo(offset, tyAlign);
752 offset += dataLayout.getTypeSize(ty);
755 const llvm::Align tyAlign = llvm::Align(
756 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
757 offset = llvm::alignTo(offset, tyAlign);
765Type IntType::parse(mlir::AsmParser &parser) {
766 mlir::MLIRContext *context = parser.getBuilder().getContext();
767 llvm::SMLoc loc = parser.getCurrentLocation();
771 if (parser.parseLess())
775 llvm::StringRef
sign;
776 if (parser.parseKeyword(&
sign))
780 else if (
sign ==
"u")
783 parser.emitError(loc,
"expected 's' or 'u'");
787 if (parser.parseComma())
791 if (parser.parseInteger(width))
793 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
794 parser.emitError(loc,
"expected integer width to be from ")
795 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
799 bool isBitInt =
false;
800 if (succeeded(parser.parseOptionalComma())) {
802 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
803 parser.emitError(loc,
"expected 'bitint'");
809 if (parser.parseGreater())
812 return IntType::get(context, width, isSigned, isBitInt);
815void IntType::print(mlir::AsmPrinter &printer)
const {
816 char sign = isSigned() ?
's' :
'u';
817 printer <<
'<' <<
sign <<
", " << getWidth();
819 printer <<
", bitint";
824IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
825 mlir::DataLayoutEntryListRef params)
const {
826 return llvm::TypeSize::getFixed(getWidth());
829uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
830 mlir::DataLayoutEntryListRef params)
const {
831 unsigned width = getWidth();
836 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
837 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
844 uint64_t alignBits = llvm::PowerOf2Ceil(width);
845 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
849IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
850 unsigned width,
bool isSigned,
bool isBitInt) {
851 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
852 return emitError() <<
"IntType only supports widths from "
853 << IntType::minBitwidth() <<
" up to "
854 << IntType::maxBitwidth();
855 return mlir::success();
859 return width == 8 || width == 16 || width == 32 || width == 64;
866const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
867 return llvm::APFloat::IEEEsingle();
871SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
872 mlir::DataLayoutEntryListRef params)
const {
873 return llvm::TypeSize::getFixed(getWidth());
877SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
878 mlir::DataLayoutEntryListRef params)
const {
879 return (uint64_t)(getWidth() / 8);
882const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
883 return llvm::APFloat::IEEEdouble();
887DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
888 mlir::DataLayoutEntryListRef params)
const {
889 return llvm::TypeSize::getFixed(getWidth());
893DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
894 mlir::DataLayoutEntryListRef params)
const {
895 return (uint64_t)(getWidth() / 8);
898const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
899 return llvm::APFloat::IEEEhalf();
903FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
904 mlir::DataLayoutEntryListRef params)
const {
905 return llvm::TypeSize::getFixed(getWidth());
908uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
909 mlir::DataLayoutEntryListRef params)
const {
910 return (uint64_t)(getWidth() / 8);
913const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
914 return llvm::APFloat::BFloat();
918BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
919 mlir::DataLayoutEntryListRef params)
const {
920 return llvm::TypeSize::getFixed(getWidth());
923uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
924 mlir::DataLayoutEntryListRef params)
const {
925 return (uint64_t)(getWidth() / 8);
928const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
929 return llvm::APFloat::x87DoubleExtended();
933FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
934 mlir::DataLayoutEntryListRef params)
const {
936 return llvm::TypeSize::getFixed(128);
939uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
940 mlir::DataLayoutEntryListRef params)
const {
944const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
945 return llvm::APFloat::IEEEquad();
949FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
950 mlir::DataLayoutEntryListRef params)
const {
951 return llvm::TypeSize::getFixed(getWidth());
954uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
955 mlir::DataLayoutEntryListRef params)
const {
959const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
960 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
964LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
965 mlir::DataLayoutEntryListRef params)
const {
966 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
967 .getTypeSizeInBits(dataLayout, params);
971LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
972 mlir::DataLayoutEntryListRef params)
const {
973 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
974 .getABIAlignment(dataLayout, params);
982cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
983 mlir::DataLayoutEntryListRef params)
const {
989 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
993cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
994 mlir::DataLayoutEntryListRef params)
const {
1000 return dataLayout.getTypeABIAlignment(getElementType());
1003FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
1004 assert(results.size() == 1 &&
"expected exactly one result type");
1005 return get(llvm::to_vector(inputs), results[0], isVarArg());
1009static mlir::ParseResult
1013 return p.parseCommaSeparatedList(
1014 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
1016 return p.emitError(p.getCurrentLocation(),
1017 "variadic `...` must be the last parameter");
1018 if (succeeded(p.parseOptionalEllipsis())) {
1023 if (failed(p.parseType(type)))
1025 params.push_back(type);
1031 mlir::ArrayRef<mlir::Type> params,
1034 llvm::interleaveComma(params, p,
1035 [&p](mlir::Type type) { p.printType(type); });
1037 if (!params.empty())
1046mlir::Type FuncType::getReturnType()
const {
1047 if (hasVoidReturn())
1048 return cir::VoidType::get(getContext());
1049 return getOptionalReturnType();
1055llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
1056 if (hasVoidReturn())
1061 return getImpl()->optionalReturnType;
1065bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
1068FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1069 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
1071 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
1073 <<
"!cir.func cannot have an explicit 'void' return type";
1074 return mlir::success();
1086 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
1087 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
1088 return cir::StructType::get(ctx, fields,
false,
1093MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1094 mlir::DataLayoutEntryListRef params)
const {
1099MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1100 mlir::DataLayoutEntryListRef params)
const {
1102 .getABIAlignment(dataLayout, params);
1110BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1111 ::mlir::DataLayoutEntryListRef params)
const {
1112 return llvm::TypeSize::getFixed(8);
1116BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1117 ::mlir::DataLayoutEntryListRef params)
const {
1126DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1127 ::mlir::DataLayoutEntryListRef params)
const {
1130 return llvm::TypeSize::getFixed(64);
1134DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1135 ::mlir::DataLayoutEntryListRef params)
const {
1146VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1147 mlir::DataLayoutEntryListRef params)
const {
1149 return llvm::TypeSize::getFixed(64);
1152uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1153 mlir::DataLayoutEntryListRef params)
const {
1163ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1164 ::mlir::DataLayoutEntryListRef params)
const {
1165 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
1169ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1170 ::mlir::DataLayoutEntryListRef params)
const {
1171 return dataLayout.getTypeABIAlignment(getElementType());
1178llvm::TypeSize cir::VectorType::getTypeSizeInBits(
1179 const ::mlir::DataLayout &dataLayout,
1180 ::mlir::DataLayoutEntryListRef params)
const {
1181 return llvm::TypeSize::getFixed(
1182 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
1186cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1187 ::mlir::DataLayoutEntryListRef params)
const {
1188 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
1191mlir::LogicalResult cir::VectorType::verify(
1192 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1193 mlir::Type elementType, uint64_t size,
bool scalable) {
1195 return emitError() <<
"the number of vector elements must be non-zero";
1199mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
1201 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
1202 mlir::Builder odsBuilder(odsParser.getContext());
1203 mlir::FailureOr<::mlir::Type> elementType;
1204 mlir::FailureOr<uint64_t> size;
1205 bool isScalabe =
false;
1208 if (odsParser.parseLess())
1212 if (odsParser.parseOptionalLSquare().succeeded())
1216 size = mlir::FieldParser<uint64_t>::parse(odsParser);
1217 if (mlir::failed(size)) {
1218 odsParser.emitError(odsParser.getCurrentLocation(),
1219 "failed to parse CIR_VectorType parameter 'size' which "
1220 "is to be a `uint64_t`");
1226 if (isScalabe && odsParser.parseRSquare().failed()) {
1227 odsParser.emitError(odsParser.getCurrentLocation(),
1228 "missing closing `]` for scalable dim size");
1233 if (odsParser.parseKeyword(
"x"))
1237 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
1238 if (mlir::failed(elementType)) {
1239 odsParser.emitError(odsParser.getCurrentLocation(),
1240 "failed to parse CIR_VectorType parameter "
1241 "'elementType' which is to be a `mlir::Type`");
1246 if (odsParser.parseGreater())
1248 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
1249 mlir::Type((*elementType)),
1253void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
1254 mlir::Builder odsBuilder(getContext());
1256 if (this->getIsScalable())
1259 odsPrinter.printStrippedAttrOrType(getSize());
1260 if (this->getIsScalable())
1262 odsPrinter <<
' ' <<
"x";
1264 odsPrinter.printStrippedAttrOrType(getElementType());
1273 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1274 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1281 case LangAS::Default:
1282 return LangAddressSpace::Default;
1283 case LangAS::opencl_global:
1284 return LangAddressSpace::OffloadGlobal;
1285 case LangAS::opencl_local:
1286 case LangAS::cuda_shared:
1289 return LangAddressSpace::OffloadLocal;
1290 case LangAS::cuda_device:
1291 return LangAddressSpace::OffloadGlobal;
1292 case LangAS::opencl_constant:
1293 case LangAS::cuda_constant:
1294 return LangAddressSpace::OffloadConstant;
1295 case LangAS::opencl_private:
1296 return LangAddressSpace::OffloadPrivate;
1297 case LangAS::opencl_generic:
1298 return LangAddressSpace::OffloadGeneric;
1299 case LangAS::opencl_global_device:
1300 return LangAddressSpace::OffloadGlobalDevice;
1301 case LangAS::opencl_global_host:
1302 return LangAddressSpace::OffloadGlobalHost;
1303 case LangAS::sycl_global:
1304 case LangAS::sycl_global_device:
1305 case LangAS::sycl_global_host:
1306 case LangAS::sycl_local:
1307 case LangAS::sycl_private:
1308 case LangAS::ptr32_sptr:
1309 case LangAS::ptr32_uptr:
1311 case LangAS::hlsl_groupshared:
1312 case LangAS::wasm_funcref:
1313 llvm_unreachable(
"NYI");
1315 llvm_unreachable(
"unknown/unsupported clang language address space");
1321 mlir::ptr::MemorySpaceAttrInterface &attr) {
1323 llvm::SMLoc loc = p.getCurrentLocation();
1327 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1329 if (p.parseLParen())
1330 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1332 if (p.parseInteger(val))
1333 return p.emitError(loc,
"expected target address space value");
1335 if (p.parseRParen())
1336 return p.emitError(loc,
"expected ')'");
1338 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1339 return mlir::success();
1343 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1344 if (p.parseLParen())
1345 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1347 mlir::FailureOr<cir::LangAddressSpace> result =
1348 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1349 if (mlir::failed(result))
1350 return mlir::failure();
1352 if (p.parseRParen())
1353 return p.emitError(loc,
"expected ')'");
1355 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1356 return mlir::success();
1359 llvm::StringRef keyword;
1360 if (p.parseOptionalKeyword(&keyword).succeeded())
1361 return p.emitError(loc,
"unknown address space specifier '")
1362 << keyword <<
"'; expected 'target_address_space' or "
1363 <<
"'lang_address_space'";
1365 return mlir::success();
1369 mlir::ptr::MemorySpaceAttrInterface attr) {
1373 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1374 p <<
"lang_address_space("
1375 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1379 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1380 p <<
"target_address_space(" << target.getValue() <<
')';
1384 llvm_unreachable(
"unexpected address-space attribute kind");
1387mlir::OptionalParseResult
1389 mlir::ptr::MemorySpaceAttrInterface &attr) {
1391 mlir::SMLoc loc = p.getCurrentLocation();
1393 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1394 return mlir::success();
1398 mlir::ptr::MemorySpaceAttrInterface attr) {
1403 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1405 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1406 if (langAS.getValue() == cir::LangAddressSpace::Default)
1411mlir::ptr::MemorySpaceAttrInterface
1415 if (langAS == LangAS::Default)
1416 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1420 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1433 return expected == cirAS;
1440mlir::LogicalResult cir::PointerType::verify(
1441 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1442 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1445 return emitError() <<
"unsupported address space attribute; expected "
1446 "'target_address_space' or 'lang_address_space'";
1457void CIRDialect::registerTypes() {
1460#define GET_TYPEDEF_LIST
1461#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)
static mlir::ParseResult parseRecordBody(mlir::AsmParser &parser, bool &incomplete, llvm::SmallVector< mlir::Type > &members)
Parse "incomplete" or "{type, type, ...}", writing results into incomplete and members.
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 printRecordBody(mlir::AsmPrinter &printer, RecordTy self, mlir::StringAttr name, bool hasClassPrefix, bool isPacked, bool isPadded, bool isIncomplete, llvm::ArrayRef< mlir::Type > members, mlir::Type padding={})
Print a complete CIR record body: '<' ['class '] [name] ['packed '] ['padded '] body '>' where body i...
static void printFuncTypeParams(mlir::AsmPrinter &p, mlir::ArrayRef< mlir::Type > params, bool isVarArg)
void printTargetAddressSpace(mlir::AsmPrinter &p, cir::TargetAddressSpaceAttr attr)
static LiveVariablesImpl & getImpl(void *x)
bool isLayoutIdentical(const RecordType &other)
bool isABIConvertedRecord() const
bool isIncomplete() const
std::string getPrefixedName() const
llvm::ArrayRef< mlir::Type > getMembers() const
void removeABIConversionNamePrefix()
void complete(llvm::ArrayRef< mlir::Type > members, bool packed, bool padded, mlir::Type padding={})
mlir::StringAttr getName() const
mlir::StringAttr getABIConvertedName() const
std::string getKindAsStr() 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)
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.
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)
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()