15#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
16#include "mlir/IR/BuiltinAttributes.h"
17#include "mlir/IR/DialectImplementation.h"
18#include "mlir/IR/MLIRContext.h"
19#include "mlir/Support/LLVM.h"
26#include "llvm/ADT/APInt.h"
27#include "llvm/ADT/APSInt.h"
28#include "llvm/ADT/TypeSwitch.h"
29#include "llvm/Support/MathExtras.h"
35 if (
auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
36 return sizedTy.isSized();
45static mlir::ParseResult
49 mlir::ArrayRef<mlir::Type> params,
55static mlir::ParseResult
60 mlir::ArrayRef<mlir::Type> params,
69 mlir::ptr::MemorySpaceAttrInterface &attr);
72 mlir::ptr::MemorySpaceAttrInterface attr);
76 cir::TargetAddressSpaceAttr &attr);
79 cir::TargetAddressSpaceAttr attr);
87#include "clang/CIR/Dialect/IR/CIRTypeConstraints.cpp.inc"
91#define GET_TYPEDEF_CLASSES
92#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
101Type CIRDialect::parseType(DialectAsmParser &parser)
const {
102 llvm::SMLoc typeLoc = parser.getCurrentLocation();
103 llvm::StringRef mnemonic;
107 OptionalParseResult parseResult =
108 generatedTypeParser(parser, &mnemonic, genType);
109 if (parseResult.has_value())
113 parser.emitError(typeLoc) <<
"unknown CIR type: " << mnemonic;
117void CIRDialect::printType(Type type, DialectAsmPrinter &os)
const {
119 if (generatedTypePrinter(type, os).succeeded())
123 llvm::report_fatal_error(
"printer is missing a handler for this type");
134static mlir::ParseResult
137 assert(incomplete &&
"caller must pre-initialize incomplete to true");
138 if (parser.parseOptionalKeyword(
"incomplete").succeeded())
139 return mlir::success();
141 return parser.parseCommaSeparatedList(
142 AsmParser::Delimiter::Braces, [&parser, &members]() {
143 return parser.parseType(members.emplace_back());
151template <
typename RecordTy>
153 mlir::StringAttr name,
bool hasClassPrefix,
154 bool isPacked,
bool isPadded,
bool isIncomplete,
156 mlir::Type padding = {}) {
163 FailureOr<AsmPrinter::CyclicPrintReset> cyclicPrintGuard =
164 printer.tryStartCyclicPrint(self);
165 if (failed(cyclicPrintGuard)) {
170 if (hasClassPrefix || name)
173 printer <<
"packed ";
175 printer <<
"padded ";
177 printer <<
"incomplete";
180 llvm::interleaveComma(members, printer);
183 printer <<
", padding = {";
184 printer.printType(padding);
192Type StructType::parse(mlir::AsmParser &parser) {
193 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
194 const llvm::SMLoc loc = parser.getCurrentLocation();
195 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
198 mlir::MLIRContext *context = parser.getContext();
200 if (parser.parseLess())
204 bool is_class = parser.parseOptionalKeyword(
"class").succeeded();
206 mlir::StringAttr
name;
207 parser.parseOptionalAttribute(name);
210 if (name && parser.parseOptionalGreater().succeeded()) {
211 StructType type = StructType::getChecked(eLoc, context, name, is_class);
212 if (succeeded(parser.tryStartCyclicParse(type))) {
213 parser.emitError(loc,
"invalid self-reference within record");
221 StructType type = StructType::getChecked(eLoc, context, name, is_class);
222 cyclicParseGuard = parser.tryStartCyclicParse(type);
223 if (failed(cyclicParseGuard)) {
224 parser.emitError(loc,
"record already defined");
229 if (parser.parseOptionalKeyword(
"packed").succeeded())
232 if (parser.parseOptionalKeyword(
"padded").succeeded())
235 bool incomplete =
true;
240 if (parser.parseGreater())
244 mlir::Type type = {};
245 if (name && incomplete) {
246 type = StructType::getChecked(eLoc, context, name, is_class);
247 }
else if (!name && !incomplete) {
248 type = StructType::getChecked(eLoc, context, membersRef, packed, padded,
252 }
else if (!incomplete) {
253 type = StructType::getChecked(eLoc, context, membersRef, name, packed,
257 if (
auto structTy = mlir::dyn_cast<StructType>(type))
258 if (structTy.isIncomplete())
259 structTy.complete(membersRef, packed, padded);
262 parser.emitError(loc,
"anonymous records must be complete");
269void StructType::print(mlir::AsmPrinter &printer)
const {
271 getPadded(), isIncomplete(), getMembers());
275StructType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
277 bool incomplete,
bool packed,
bool padded,
bool is_class) {
278 if (name &&
name.getValue().empty())
279 return emitError() <<
"identified records cannot have an empty name";
280 return mlir::success();
288mlir::StringAttr StructType::getName()
const {
return getImpl()->name; }
289bool StructType::isIncomplete()
const {
return getImpl()->incomplete; }
290bool StructType::getIncomplete()
const {
return getImpl()->incomplete; }
291bool StructType::getPacked()
const {
return getImpl()->packed; }
292bool StructType::getPadded()
const {
return getImpl()->padded; }
293bool StructType::getIsClass()
const {
return getImpl()->is_class; }
295bool StructType::isABIConvertedRecord()
const {
296 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
299mlir::StringAttr StructType::getABIConvertedName()
const {
300 assert(!isABIConvertedRecord());
301 return StringAttr::get(getContext(),
302 abi_conversion_prefix +
getName().getValue());
305void StructType::removeABIConversionNamePrefix() {
306 mlir::StringAttr recordName =
getName();
307 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
308 getImpl()->name = mlir::StringAttr::get(
309 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
310 recordName.getType());
313void StructType::complete(
ArrayRef<Type> members,
bool packed,
bool padded) {
315 if (mutate(members, packed, padded).failed())
316 llvm_unreachable(
"failed to complete struct");
319bool StructType::isLayoutIdentical(
const StructType &other) {
320 if (
getImpl() == other.getImpl())
322 if (getPacked() != other.getPacked())
324 return getMembers() == other.getMembers();
331Type UnionType::parse(mlir::AsmParser &parser) {
332 FailureOr<AsmParser::CyclicParseReset> cyclicParseGuard;
333 const llvm::SMLoc loc = parser.getCurrentLocation();
334 const mlir::Location eLoc = parser.getEncodedSourceLoc(loc);
337 mlir::MLIRContext *context = parser.getContext();
339 if (parser.parseLess())
342 mlir::StringAttr
name;
343 parser.parseOptionalAttribute(name);
346 if (name && parser.parseOptionalGreater().succeeded()) {
347 UnionType type = UnionType::getChecked(eLoc, context, name);
348 if (succeeded(parser.tryStartCyclicParse(type))) {
349 parser.emitError(loc,
"invalid self-reference within record");
357 UnionType type = UnionType::getChecked(eLoc, context, name);
358 cyclicParseGuard = parser.tryStartCyclicParse(type);
359 if (failed(cyclicParseGuard)) {
360 parser.emitError(loc,
"record already defined");
365 if (parser.parseOptionalKeyword(
"packed").succeeded())
368 bool incomplete =
true;
374 if (!incomplete && parser.parseOptionalComma().succeeded()) {
375 if (parser.parseKeyword(
"padding").failed())
377 if (parser.parseEqual().failed())
379 if (parser.parseLBrace().failed())
381 if (parser.parseType(padding).failed())
383 if (parser.parseRBrace().failed())
387 if (parser.parseGreater())
391 mlir::Type type = {};
392 if (name && incomplete) {
393 type = UnionType::getChecked(eLoc, context, name);
394 }
else if (!name && !incomplete) {
395 type = UnionType::getChecked(eLoc, context, membersRef, packed, padding);
398 }
else if (!incomplete) {
400 UnionType::getChecked(eLoc, context, membersRef, name, packed, padding);
403 if (
auto unionTy = mlir::dyn_cast<UnionType>(type))
404 if (unionTy.isIncomplete())
405 unionTy.complete(membersRef, packed, padding);
408 parser.emitError(loc,
"anonymous records must be complete");
415void UnionType::print(mlir::AsmPrinter &printer)
const {
417 getPacked(),
false, isIncomplete(), getMembers(),
422UnionType::verify(function_ref<mlir::InFlightDiagnostic()> emitError,
424 bool incomplete,
bool packed, mlir::Type padding) {
425 if (name &&
name.getValue().empty())
426 return emitError() <<
"identified records cannot have an empty name";
427 return mlir::success();
434mlir::StringAttr UnionType::getName()
const {
return getImpl()->name; }
435bool UnionType::isIncomplete()
const {
return getImpl()->incomplete; }
436bool UnionType::getIncomplete()
const {
return getImpl()->incomplete; }
437bool UnionType::getPacked()
const {
return getImpl()->packed; }
438bool UnionType::getPadded()
const {
return getPadding() ?
true :
false; }
439mlir::Type UnionType::getPadding()
const {
return getImpl()->padding; }
441bool UnionType::isABIConvertedRecord()
const {
442 return getName() &&
getName().getValue().starts_with(abi_conversion_prefix);
445mlir::StringAttr UnionType::getABIConvertedName()
const {
446 assert(!isABIConvertedRecord());
447 return StringAttr::get(getContext(),
448 abi_conversion_prefix +
getName().getValue());
451void UnionType::removeABIConversionNamePrefix() {
452 mlir::StringAttr recordName =
getName();
453 if (recordName && recordName.getValue().starts_with(abi_conversion_prefix))
454 getImpl()->name = mlir::StringAttr::get(
455 recordName.getValue().drop_front(
sizeof(abi_conversion_prefix) - 1),
456 recordName.getType());
460 mlir::Type padding) {
462 if (mutate(members, packed, padding).failed())
463 llvm_unreachable(
"failed to complete union");
467UnionType::getUnionStorageType(
const mlir::DataLayout &dataLayout)
const {
471 return *std::max_element(
472 members.begin(), members.end(), [&](mlir::Type lhs, mlir::Type rhs) {
473 return dataLayout.getTypeABIAlignment(lhs) <
474 dataLayout.getTypeABIAlignment(rhs) ||
475 (dataLayout.getTypeABIAlignment(lhs) ==
476 dataLayout.getTypeABIAlignment(rhs) &&
477 dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
481bool UnionType::isLayoutIdentical(
const UnionType &other) {
482 if (
getImpl() == other.getImpl())
484 return getMembers() == other.getMembers() &&
485 getPadding() == other.getPadding();
493 if (
auto s = mlir::dyn_cast<StructType>(*
this))
494 return s.getMembers();
495 return mlir::cast<UnionType>(*this).getMembers();
498 if (
auto s = mlir::dyn_cast<StructType>(*
this))
500 return mlir::cast<UnionType>(*this).getName();
503 if (
auto s = mlir::dyn_cast<StructType>(*
this))
504 return s.isIncomplete();
505 return mlir::cast<UnionType>(*this).isIncomplete();
508 if (
auto s = mlir::dyn_cast<StructType>(*
this))
509 return s.getPacked();
510 return mlir::cast<UnionType>(*this).getPacked();
513 if (
auto s = mlir::dyn_cast<StructType>(*
this))
514 return s.getPadded();
515 return mlir::cast<UnionType>(*this).getPadded();
518 if (
auto s = mlir::dyn_cast<StructType>(*
this))
523 if (
auto s = mlir::dyn_cast<StructType>(*
this))
528 if (mlir::isa<UnionType>(*
this))
530 return mlir::cast<StructType>(*this).getKindAsStr();
536 mlir::Type padding) {
537 if (
auto s = mlir::dyn_cast<StructType>(*
this))
538 return s.complete(members, packed, padded);
540 assert((!padded || padding) &&
541 "padded=true requires a non-null padding type");
542 return mlir::cast<UnionType>(*this).complete(members, packed, padding);
545 unsigned idx)
const {
546 if (mlir::isa<UnionType>(*
this))
548 return mlir::cast<StructType>(*this).getElementOffset(dataLayout, idx);
551 if (
auto s = mlir::dyn_cast<StructType>(*
this)) {
552 if (
auto so = mlir::dyn_cast<StructType>(other))
553 return s.isLayoutIdentical(so);
556 if (
auto u = mlir::dyn_cast<UnionType>(*
this)) {
557 if (
auto uo = mlir::dyn_cast<UnionType>(other))
558 return u.isLayoutIdentical(uo);
564 if (
auto s = mlir::dyn_cast<StructType>(*
this))
565 return s.isABIConvertedRecord();
566 return mlir::cast<UnionType>(*this).isABIConvertedRecord();
569 if (
auto s = mlir::dyn_cast<StructType>(*
this))
570 return s.getABIConvertedName();
571 return mlir::cast<UnionType>(*this).getABIConvertedName();
574 if (
auto s = mlir::dyn_cast<StructType>(*
this))
575 return s.removeABIConversionNamePrefix();
576 return mlir::cast<UnionType>(*this).removeABIConversionNamePrefix();
584PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
585 ::mlir::DataLayoutEntryListRef params)
const {
588 return llvm::TypeSize::getFixed(64);
592PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
593 ::mlir::DataLayoutEntryListRef params)
const {
600StructType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
601 mlir::DataLayoutEntryListRef params)
const {
602 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
603 return llvm::TypeSize::getFixed(recordSize * 8);
607StructType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
608 ::mlir::DataLayoutEntryListRef params)
const {
612 return computeStructAlignment(dataLayout);
616UnionType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
617 mlir::DataLayoutEntryListRef params)
const {
618 mlir::Type storage = getUnionStorageType(dataLayout);
620 return llvm::TypeSize::getFixed(0);
626 llvm::TypeSize size = dataLayout.getTypeSizeInBits(storage);
627 if (mlir::Type pad = getPadding())
628 size += dataLayout.getTypeSizeInBits(pad);
633UnionType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
634 ::mlir::DataLayoutEntryListRef params)
const {
635 mlir::Type storage = getUnionStorageType(dataLayout);
638 return dataLayout.getTypeABIAlignment(storage);
642StructType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
643 assert(isComplete() &&
"Cannot get layout of incomplete records");
646 unsigned recordSize = 0;
649 for (mlir::Type ty : getMembers()) {
653 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
657 recordSize = llvm::alignTo(recordSize, tyAlign);
658 recordSize += dataLayout.getTypeSize(ty);
662 recordAlignment = std::max(tyAlign, recordAlignment);
667 recordSize = llvm::alignTo(recordSize, recordAlignment);
672StructType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
673 assert(isComplete() &&
"Cannot get layout of incomplete records");
680 auto members = getMembers();
681 unsigned numMembers =
682 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
683 unsigned recordSize = 0;
684 for (
unsigned i = 0; i < numMembers; ++i) {
685 mlir::Type ty = members[i];
687 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
688 recordSize = llvm::alignTo(recordSize, tyAlign);
689 recordSize += dataLayout.getTypeSize(ty);
699StructType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
700 assert(isComplete() &&
"Cannot get layout of incomplete records");
703 for (mlir::Type ty : getMembers())
705 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
706 return recordAlignment;
709uint64_t StructType::getElementOffset(const ::mlir::DataLayout &dataLayout,
710 unsigned idx)
const {
711 assert(idx < getMembers().size() &&
"access not valid");
715 assert(isComplete() &&
"Cannot get layout of incomplete records");
716 assert(idx < getNumElements());
717 llvm::ArrayRef<mlir::Type> members = getMembers();
721 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
722 const llvm::Align tyAlign =
723 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
724 offset = llvm::alignTo(offset, tyAlign);
725 offset += dataLayout.getTypeSize(ty);
728 const llvm::Align tyAlign = llvm::Align(
729 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
730 offset = llvm::alignTo(offset, tyAlign);
738Type IntType::parse(mlir::AsmParser &parser) {
739 mlir::MLIRContext *context = parser.getBuilder().getContext();
740 llvm::SMLoc loc = parser.getCurrentLocation();
744 if (parser.parseLess())
748 llvm::StringRef
sign;
749 if (parser.parseKeyword(&
sign))
753 else if (
sign ==
"u")
756 parser.emitError(loc,
"expected 's' or 'u'");
760 if (parser.parseComma())
764 if (parser.parseInteger(width))
766 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
767 parser.emitError(loc,
"expected integer width to be from ")
768 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
772 bool isBitInt =
false;
773 if (succeeded(parser.parseOptionalComma())) {
775 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
776 parser.emitError(loc,
"expected 'bitint'");
782 if (parser.parseGreater())
785 return IntType::get(context, width, isSigned, isBitInt);
788void IntType::print(mlir::AsmPrinter &printer)
const {
789 char sign = isSigned() ?
's' :
'u';
790 printer <<
'<' <<
sign <<
", " << getWidth();
792 printer <<
", bitint";
797IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
798 mlir::DataLayoutEntryListRef params)
const {
799 return llvm::TypeSize::getFixed(getWidth());
802uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
803 mlir::DataLayoutEntryListRef params)
const {
804 unsigned width = getWidth();
809 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
810 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
812 return (uint64_t)(width / 8);
816IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
817 unsigned width,
bool isSigned,
bool isBitInt) {
818 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
819 return emitError() <<
"IntType only supports widths from "
820 << IntType::minBitwidth() <<
" up to "
821 << IntType::maxBitwidth();
822 return mlir::success();
826 return width == 8 || width == 16 || width == 32 || width == 64;
833const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
834 return llvm::APFloat::IEEEsingle();
838SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
839 mlir::DataLayoutEntryListRef params)
const {
840 return llvm::TypeSize::getFixed(getWidth());
844SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
845 mlir::DataLayoutEntryListRef params)
const {
846 return (uint64_t)(getWidth() / 8);
849const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
850 return llvm::APFloat::IEEEdouble();
854DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
855 mlir::DataLayoutEntryListRef params)
const {
856 return llvm::TypeSize::getFixed(getWidth());
860DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
861 mlir::DataLayoutEntryListRef params)
const {
862 return (uint64_t)(getWidth() / 8);
865const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
866 return llvm::APFloat::IEEEhalf();
870FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
871 mlir::DataLayoutEntryListRef params)
const {
872 return llvm::TypeSize::getFixed(getWidth());
875uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
876 mlir::DataLayoutEntryListRef params)
const {
877 return (uint64_t)(getWidth() / 8);
880const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
881 return llvm::APFloat::BFloat();
885BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
886 mlir::DataLayoutEntryListRef params)
const {
887 return llvm::TypeSize::getFixed(getWidth());
890uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
891 mlir::DataLayoutEntryListRef params)
const {
892 return (uint64_t)(getWidth() / 8);
895const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
896 return llvm::APFloat::x87DoubleExtended();
900FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
901 mlir::DataLayoutEntryListRef params)
const {
903 return llvm::TypeSize::getFixed(128);
906uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
907 mlir::DataLayoutEntryListRef params)
const {
911const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
912 return llvm::APFloat::IEEEquad();
916FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
917 mlir::DataLayoutEntryListRef params)
const {
918 return llvm::TypeSize::getFixed(getWidth());
921uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
922 mlir::DataLayoutEntryListRef params)
const {
926const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
927 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
931LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
932 mlir::DataLayoutEntryListRef params)
const {
933 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
934 .getTypeSizeInBits(dataLayout, params);
938LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
939 mlir::DataLayoutEntryListRef params)
const {
940 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
941 .getABIAlignment(dataLayout, params);
949cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
950 mlir::DataLayoutEntryListRef params)
const {
956 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
960cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
961 mlir::DataLayoutEntryListRef params)
const {
967 return dataLayout.getTypeABIAlignment(getElementType());
970FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
971 assert(results.size() == 1 &&
"expected exactly one result type");
972 return get(llvm::to_vector(inputs), results[0], isVarArg());
976static mlir::ParseResult
980 return p.parseCommaSeparatedList(
981 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
983 return p.emitError(p.getCurrentLocation(),
984 "variadic `...` must be the last parameter");
985 if (succeeded(p.parseOptionalEllipsis())) {
990 if (failed(p.parseType(type)))
992 params.push_back(type);
998 mlir::ArrayRef<mlir::Type> params,
1001 llvm::interleaveComma(params, p,
1002 [&p](mlir::Type type) { p.printType(type); });
1004 if (!params.empty())
1013mlir::Type FuncType::getReturnType()
const {
1014 if (hasVoidReturn())
1015 return cir::VoidType::get(getContext());
1016 return getOptionalReturnType();
1022llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
1023 if (hasVoidReturn())
1028 return getImpl()->optionalReturnType;
1032bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
1035FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1036 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
1038 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
1040 <<
"!cir.func cannot have an explicit 'void' return type";
1041 return mlir::success();
1053 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
1054 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
1055 return cir::StructType::get(ctx, fields,
false,
1060MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1061 mlir::DataLayoutEntryListRef params)
const {
1066MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1067 mlir::DataLayoutEntryListRef params)
const {
1069 .getABIAlignment(dataLayout, params);
1077BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1078 ::mlir::DataLayoutEntryListRef params)
const {
1079 return llvm::TypeSize::getFixed(8);
1083BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1084 ::mlir::DataLayoutEntryListRef params)
const {
1093DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1094 ::mlir::DataLayoutEntryListRef params)
const {
1097 return llvm::TypeSize::getFixed(64);
1101DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1102 ::mlir::DataLayoutEntryListRef params)
const {
1113VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1114 mlir::DataLayoutEntryListRef params)
const {
1116 return llvm::TypeSize::getFixed(64);
1119uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1120 mlir::DataLayoutEntryListRef params)
const {
1130ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1131 ::mlir::DataLayoutEntryListRef params)
const {
1132 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
1136ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1137 ::mlir::DataLayoutEntryListRef params)
const {
1138 return dataLayout.getTypeABIAlignment(getElementType());
1145llvm::TypeSize cir::VectorType::getTypeSizeInBits(
1146 const ::mlir::DataLayout &dataLayout,
1147 ::mlir::DataLayoutEntryListRef params)
const {
1148 return llvm::TypeSize::getFixed(
1149 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
1153cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1154 ::mlir::DataLayoutEntryListRef params)
const {
1155 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
1158mlir::LogicalResult cir::VectorType::verify(
1159 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1160 mlir::Type elementType, uint64_t size,
bool scalable) {
1162 return emitError() <<
"the number of vector elements must be non-zero";
1166mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
1168 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
1169 mlir::Builder odsBuilder(odsParser.getContext());
1170 mlir::FailureOr<::mlir::Type> elementType;
1171 mlir::FailureOr<uint64_t> size;
1172 bool isScalabe =
false;
1175 if (odsParser.parseLess())
1179 if (odsParser.parseOptionalLSquare().succeeded())
1183 size = mlir::FieldParser<uint64_t>::parse(odsParser);
1184 if (mlir::failed(size)) {
1185 odsParser.emitError(odsParser.getCurrentLocation(),
1186 "failed to parse CIR_VectorType parameter 'size' which "
1187 "is to be a `uint64_t`");
1193 if (isScalabe && odsParser.parseRSquare().failed()) {
1194 odsParser.emitError(odsParser.getCurrentLocation(),
1195 "missing closing `]` for scalable dim size");
1200 if (odsParser.parseKeyword(
"x"))
1204 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
1205 if (mlir::failed(elementType)) {
1206 odsParser.emitError(odsParser.getCurrentLocation(),
1207 "failed to parse CIR_VectorType parameter "
1208 "'elementType' which is to be a `mlir::Type`");
1213 if (odsParser.parseGreater())
1215 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
1216 mlir::Type((*elementType)),
1220void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
1221 mlir::Builder odsBuilder(getContext());
1223 if (this->getIsScalable())
1226 odsPrinter.printStrippedAttrOrType(getSize());
1227 if (this->getIsScalable())
1229 odsPrinter <<
' ' <<
"x";
1231 odsPrinter.printStrippedAttrOrType(getElementType());
1240 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1241 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1248 case LangAS::Default:
1249 return LangAddressSpace::Default;
1250 case LangAS::opencl_global:
1251 return LangAddressSpace::OffloadGlobal;
1252 case LangAS::opencl_local:
1253 case LangAS::cuda_shared:
1256 return LangAddressSpace::OffloadLocal;
1257 case LangAS::cuda_device:
1258 return LangAddressSpace::OffloadGlobal;
1259 case LangAS::opencl_constant:
1260 case LangAS::cuda_constant:
1261 return LangAddressSpace::OffloadConstant;
1262 case LangAS::opencl_private:
1263 return LangAddressSpace::OffloadPrivate;
1264 case LangAS::opencl_generic:
1265 return LangAddressSpace::OffloadGeneric;
1266 case LangAS::opencl_global_device:
1267 return LangAddressSpace::OffloadGlobalDevice;
1268 case LangAS::opencl_global_host:
1269 return LangAddressSpace::OffloadGlobalHost;
1270 case LangAS::sycl_global:
1271 case LangAS::sycl_global_device:
1272 case LangAS::sycl_global_host:
1273 case LangAS::sycl_local:
1274 case LangAS::sycl_private:
1275 case LangAS::ptr32_sptr:
1276 case LangAS::ptr32_uptr:
1278 case LangAS::hlsl_groupshared:
1279 case LangAS::wasm_funcref:
1280 llvm_unreachable(
"NYI");
1282 llvm_unreachable(
"unknown/unsupported clang language address space");
1288 mlir::ptr::MemorySpaceAttrInterface &attr) {
1290 llvm::SMLoc loc = p.getCurrentLocation();
1294 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1296 if (p.parseLParen())
1297 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1299 if (p.parseInteger(val))
1300 return p.emitError(loc,
"expected target address space value");
1302 if (p.parseRParen())
1303 return p.emitError(loc,
"expected ')'");
1305 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1306 return mlir::success();
1310 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1311 if (p.parseLParen())
1312 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1314 mlir::FailureOr<cir::LangAddressSpace> result =
1315 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1316 if (mlir::failed(result))
1317 return mlir::failure();
1319 if (p.parseRParen())
1320 return p.emitError(loc,
"expected ')'");
1322 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1323 return mlir::success();
1326 llvm::StringRef keyword;
1327 if (p.parseOptionalKeyword(&keyword).succeeded())
1328 return p.emitError(loc,
"unknown address space specifier '")
1329 << keyword <<
"'; expected 'target_address_space' or "
1330 <<
"'lang_address_space'";
1332 return mlir::success();
1336 mlir::ptr::MemorySpaceAttrInterface attr) {
1340 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1341 p <<
"lang_address_space("
1342 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1346 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1347 p <<
"target_address_space(" << target.getValue() <<
')';
1351 llvm_unreachable(
"unexpected address-space attribute kind");
1354mlir::OptionalParseResult
1356 mlir::ptr::MemorySpaceAttrInterface &attr) {
1358 mlir::SMLoc loc = p.getCurrentLocation();
1360 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1361 return mlir::success();
1365 mlir::ptr::MemorySpaceAttrInterface attr) {
1370 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1372 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1373 if (langAS.getValue() == cir::LangAddressSpace::Default)
1378mlir::ptr::MemorySpaceAttrInterface
1382 if (langAS == LangAS::Default)
1383 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1387 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1400 return expected == cirAS;
1407mlir::LogicalResult cir::PointerType::verify(
1408 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1409 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1412 return emitError() <<
"unsupported address space attribute; expected "
1413 "'target_address_space' or 'lang_address_space'";
1424void CIRDialect::registerTypes() {
1427#define GET_TYPEDEF_LIST
1428#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)
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()