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 {
494 return *std::max_element(
495 members.begin(), members.end(), [&](mlir::Type lhs, mlir::Type rhs) {
496 return dataLayout.getTypeABIAlignment(lhs) <
497 dataLayout.getTypeABIAlignment(rhs) ||
498 (dataLayout.getTypeABIAlignment(lhs) ==
499 dataLayout.getTypeABIAlignment(rhs) &&
500 dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs));
504bool UnionType::isLayoutIdentical(
const UnionType &other) {
505 if (
getImpl() == other.getImpl())
507 return getMembers() == other.getMembers() &&
508 getPadding() == other.getPadding();
516 if (
auto s = mlir::dyn_cast<StructType>(*
this))
517 return s.getMembers();
518 return mlir::cast<UnionType>(*this).getMembers();
521 if (
auto s = mlir::dyn_cast<StructType>(*
this))
523 return mlir::cast<UnionType>(*this).getName();
526 if (
auto s = mlir::dyn_cast<StructType>(*
this))
527 return s.isIncomplete();
528 return mlir::cast<UnionType>(*this).isIncomplete();
531 if (
auto s = mlir::dyn_cast<StructType>(*
this))
532 return s.getPacked();
533 return mlir::cast<UnionType>(*this).getPacked();
536 if (
auto s = mlir::dyn_cast<StructType>(*
this))
537 return s.getPadded();
538 return mlir::cast<UnionType>(*this).getPadded();
541 if (
auto s = mlir::dyn_cast<StructType>(*
this))
546 if (
auto s = mlir::dyn_cast<StructType>(*
this))
551 if (mlir::isa<UnionType>(*
this))
553 return mlir::cast<StructType>(*this).getKindAsStr();
559 mlir::Type padding) {
560 if (
auto s = mlir::dyn_cast<StructType>(*
this))
561 return s.complete(members, packed, padded);
563 assert((!padded || padding) &&
564 "padded=true requires a non-null padding type");
565 return mlir::cast<UnionType>(*this).complete(members, packed, padding);
568 unsigned idx)
const {
569 if (mlir::isa<UnionType>(*
this))
571 return mlir::cast<StructType>(*this).getElementOffset(dataLayout, idx);
574 if (
auto s = mlir::dyn_cast<StructType>(*
this)) {
575 if (
auto so = mlir::dyn_cast<StructType>(other))
576 return s.isLayoutIdentical(so);
579 if (
auto u = mlir::dyn_cast<UnionType>(*
this)) {
580 if (
auto uo = mlir::dyn_cast<UnionType>(other))
581 return u.isLayoutIdentical(uo);
587 if (
auto s = mlir::dyn_cast<StructType>(*
this))
588 return s.isABIConvertedRecord();
589 return mlir::cast<UnionType>(*this).isABIConvertedRecord();
592 if (
auto s = mlir::dyn_cast<StructType>(*
this))
593 return s.getABIConvertedName();
594 return mlir::cast<UnionType>(*this).getABIConvertedName();
597 if (
auto s = mlir::dyn_cast<StructType>(*
this))
598 return s.removeABIConversionNamePrefix();
599 return mlir::cast<UnionType>(*this).removeABIConversionNamePrefix();
607PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
608 ::mlir::DataLayoutEntryListRef params)
const {
611 return llvm::TypeSize::getFixed(64);
615PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
616 ::mlir::DataLayoutEntryListRef params)
const {
623StructType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
624 mlir::DataLayoutEntryListRef params)
const {
625 auto recordSize =
static_cast<uint64_t>(computeStructSize(dataLayout));
626 return llvm::TypeSize::getFixed(recordSize * 8);
630StructType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
631 ::mlir::DataLayoutEntryListRef params)
const {
635 return computeStructAlignment(dataLayout);
639UnionType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
640 mlir::DataLayoutEntryListRef params)
const {
641 mlir::Type storage = getUnionStorageType(dataLayout);
643 return llvm::TypeSize::getFixed(0);
649 llvm::TypeSize size = dataLayout.getTypeSizeInBits(storage);
650 if (mlir::Type pad = getPadding())
651 size += dataLayout.getTypeSizeInBits(pad);
656UnionType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
657 ::mlir::DataLayoutEntryListRef params)
const {
658 mlir::Type storage = getUnionStorageType(dataLayout);
661 return dataLayout.getTypeABIAlignment(storage);
665StructType::computeStructSize(
const mlir::DataLayout &dataLayout)
const {
666 assert(isComplete() &&
"Cannot get layout of incomplete records");
669 unsigned recordSize = 0;
672 for (mlir::Type ty : getMembers()) {
676 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
680 recordSize = llvm::alignTo(recordSize, tyAlign);
681 recordSize += dataLayout.getTypeSize(ty);
685 recordAlignment = std::max(tyAlign, recordAlignment);
690 recordSize = llvm::alignTo(recordSize, recordAlignment);
695StructType::computeStructDataSize(
const mlir::DataLayout &dataLayout)
const {
696 assert(isComplete() &&
"Cannot get layout of incomplete records");
703 auto members = getMembers();
704 unsigned numMembers =
705 getPadded() && members.size() > 1 ? members.size() - 1 : members.size();
706 unsigned recordSize = 0;
707 for (
unsigned i = 0; i < numMembers; ++i) {
708 mlir::Type ty = members[i];
710 (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
711 recordSize = llvm::alignTo(recordSize, tyAlign);
712 recordSize += dataLayout.getTypeSize(ty);
722StructType::computeStructAlignment(
const mlir::DataLayout &dataLayout)
const {
723 assert(isComplete() &&
"Cannot get layout of incomplete records");
726 for (mlir::Type ty : getMembers())
728 std::max(dataLayout.getTypeABIAlignment(ty), recordAlignment);
729 return recordAlignment;
732uint64_t StructType::getElementOffset(const ::mlir::DataLayout &dataLayout,
733 unsigned idx)
const {
734 assert(idx < getMembers().size() &&
"access not valid");
738 assert(isComplete() &&
"Cannot get layout of incomplete records");
739 assert(idx < getNumElements());
740 llvm::ArrayRef<mlir::Type> members = getMembers();
744 llvm::make_range(members.begin(), std::next(members.begin(), idx))) {
745 const llvm::Align tyAlign =
746 llvm::Align(getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty));
747 offset = llvm::alignTo(offset, tyAlign);
748 offset += dataLayout.getTypeSize(ty);
751 const llvm::Align tyAlign = llvm::Align(
752 getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
753 offset = llvm::alignTo(offset, tyAlign);
761Type IntType::parse(mlir::AsmParser &parser) {
762 mlir::MLIRContext *context = parser.getBuilder().getContext();
763 llvm::SMLoc loc = parser.getCurrentLocation();
767 if (parser.parseLess())
771 llvm::StringRef
sign;
772 if (parser.parseKeyword(&
sign))
776 else if (
sign ==
"u")
779 parser.emitError(loc,
"expected 's' or 'u'");
783 if (parser.parseComma())
787 if (parser.parseInteger(width))
789 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
790 parser.emitError(loc,
"expected integer width to be from ")
791 << IntType::minBitwidth() <<
" up to " << IntType::maxBitwidth();
795 bool isBitInt =
false;
796 if (succeeded(parser.parseOptionalComma())) {
798 if (parser.parseKeyword(&kw) || kw !=
"bitint") {
799 parser.emitError(loc,
"expected 'bitint'");
805 if (parser.parseGreater())
808 return IntType::get(context, width, isSigned, isBitInt);
811void IntType::print(mlir::AsmPrinter &printer)
const {
812 char sign = isSigned() ?
's' :
'u';
813 printer <<
'<' <<
sign <<
", " << getWidth();
815 printer <<
", bitint";
820IntType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
821 mlir::DataLayoutEntryListRef params)
const {
822 return llvm::TypeSize::getFixed(getWidth());
825uint64_t IntType::getABIAlignment(
const mlir::DataLayout &dataLayout,
826 mlir::DataLayoutEntryListRef params)
const {
827 unsigned width = getWidth();
832 std::min(llvm::PowerOf2Ceil(width),
static_cast<uint64_t>(64));
833 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
840 uint64_t alignBits = llvm::PowerOf2Ceil(width);
841 return std::max(alignBits / 8,
static_cast<uint64_t>(1));
845IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
846 unsigned width,
bool isSigned,
bool isBitInt) {
847 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth())
848 return emitError() <<
"IntType only supports widths from "
849 << IntType::minBitwidth() <<
" up to "
850 << IntType::maxBitwidth();
851 return mlir::success();
855 return width == 8 || width == 16 || width == 32 || width == 64;
862const llvm::fltSemantics &SingleType::getFloatSemantics()
const {
863 return llvm::APFloat::IEEEsingle();
867SingleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
868 mlir::DataLayoutEntryListRef params)
const {
869 return llvm::TypeSize::getFixed(getWidth());
873SingleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
874 mlir::DataLayoutEntryListRef params)
const {
875 return (uint64_t)(getWidth() / 8);
878const llvm::fltSemantics &DoubleType::getFloatSemantics()
const {
879 return llvm::APFloat::IEEEdouble();
883DoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
884 mlir::DataLayoutEntryListRef params)
const {
885 return llvm::TypeSize::getFixed(getWidth());
889DoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
890 mlir::DataLayoutEntryListRef params)
const {
891 return (uint64_t)(getWidth() / 8);
894const llvm::fltSemantics &FP16Type::getFloatSemantics()
const {
895 return llvm::APFloat::IEEEhalf();
899FP16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
900 mlir::DataLayoutEntryListRef params)
const {
901 return llvm::TypeSize::getFixed(getWidth());
904uint64_t FP16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
905 mlir::DataLayoutEntryListRef params)
const {
906 return (uint64_t)(getWidth() / 8);
909const llvm::fltSemantics &BF16Type::getFloatSemantics()
const {
910 return llvm::APFloat::BFloat();
914BF16Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
915 mlir::DataLayoutEntryListRef params)
const {
916 return llvm::TypeSize::getFixed(getWidth());
919uint64_t BF16Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
920 mlir::DataLayoutEntryListRef params)
const {
921 return (uint64_t)(getWidth() / 8);
924const llvm::fltSemantics &FP80Type::getFloatSemantics()
const {
925 return llvm::APFloat::x87DoubleExtended();
929FP80Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
930 mlir::DataLayoutEntryListRef params)
const {
932 return llvm::TypeSize::getFixed(128);
935uint64_t FP80Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
936 mlir::DataLayoutEntryListRef params)
const {
940const llvm::fltSemantics &FP128Type::getFloatSemantics()
const {
941 return llvm::APFloat::IEEEquad();
945FP128Type::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
946 mlir::DataLayoutEntryListRef params)
const {
947 return llvm::TypeSize::getFixed(getWidth());
950uint64_t FP128Type::getABIAlignment(
const mlir::DataLayout &dataLayout,
951 mlir::DataLayoutEntryListRef params)
const {
955const llvm::fltSemantics &LongDoubleType::getFloatSemantics()
const {
956 return mlir::cast<cir::FPTypeInterface>(getUnderlying()).getFloatSemantics();
960LongDoubleType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
961 mlir::DataLayoutEntryListRef params)
const {
962 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
963 .getTypeSizeInBits(dataLayout, params);
967LongDoubleType::getABIAlignment(
const mlir::DataLayout &dataLayout,
968 mlir::DataLayoutEntryListRef params)
const {
969 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
970 .getABIAlignment(dataLayout, params);
978cir::ComplexType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
979 mlir::DataLayoutEntryListRef params)
const {
985 return dataLayout.getTypeSizeInBits(getElementType()) * 2;
989cir::ComplexType::getABIAlignment(
const mlir::DataLayout &dataLayout,
990 mlir::DataLayoutEntryListRef params)
const {
996 return dataLayout.getTypeABIAlignment(getElementType());
999FuncType FuncType::clone(TypeRange inputs, TypeRange results)
const {
1000 assert(results.size() == 1 &&
"expected exactly one result type");
1001 return get(llvm::to_vector(inputs), results[0], isVarArg());
1005static mlir::ParseResult
1009 return p.parseCommaSeparatedList(
1010 AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
1012 return p.emitError(p.getCurrentLocation(),
1013 "variadic `...` must be the last parameter");
1014 if (succeeded(p.parseOptionalEllipsis())) {
1019 if (failed(p.parseType(type)))
1021 params.push_back(type);
1027 mlir::ArrayRef<mlir::Type> params,
1030 llvm::interleaveComma(params, p,
1031 [&p](mlir::Type type) { p.printType(type); });
1033 if (!params.empty())
1042mlir::Type FuncType::getReturnType()
const {
1043 if (hasVoidReturn())
1044 return cir::VoidType::get(getContext());
1045 return getOptionalReturnType();
1051llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes()
const {
1052 if (hasVoidReturn())
1057 return getImpl()->optionalReturnType;
1061bool FuncType::hasVoidReturn()
const {
return !getOptionalReturnType(); }
1064FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1065 llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
1067 if (mlir::isa_and_nonnull<cir::VoidType>(returnType))
1069 <<
"!cir.func cannot have an explicit 'void' return type";
1070 return mlir::success();
1082 auto voidPtrTy = cir::PointerType::get(cir::VoidType::get(ctx));
1083 mlir::Type fields[2]{voidPtrTy, voidPtrTy};
1084 return cir::StructType::get(ctx, fields,
false,
1089MethodType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1090 mlir::DataLayoutEntryListRef params)
const {
1095MethodType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1096 mlir::DataLayoutEntryListRef params)
const {
1098 .getABIAlignment(dataLayout, params);
1106BoolType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1107 ::mlir::DataLayoutEntryListRef params)
const {
1108 return llvm::TypeSize::getFixed(8);
1112BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1113 ::mlir::DataLayoutEntryListRef params)
const {
1122DataMemberType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1123 ::mlir::DataLayoutEntryListRef params)
const {
1126 return llvm::TypeSize::getFixed(64);
1130DataMemberType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1131 ::mlir::DataLayoutEntryListRef params)
const {
1142VPtrType::getTypeSizeInBits(
const mlir::DataLayout &dataLayout,
1143 mlir::DataLayoutEntryListRef params)
const {
1145 return llvm::TypeSize::getFixed(64);
1148uint64_t VPtrType::getABIAlignment(
const mlir::DataLayout &dataLayout,
1149 mlir::DataLayoutEntryListRef params)
const {
1159ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
1160 ::mlir::DataLayoutEntryListRef params)
const {
1161 return getSize() * dataLayout.getTypeSizeInBits(getElementType());
1165ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1166 ::mlir::DataLayoutEntryListRef params)
const {
1167 return dataLayout.getTypeABIAlignment(getElementType());
1174llvm::TypeSize cir::VectorType::getTypeSizeInBits(
1175 const ::mlir::DataLayout &dataLayout,
1176 ::mlir::DataLayoutEntryListRef params)
const {
1177 return llvm::TypeSize::getFixed(
1178 getSize() * dataLayout.getTypeSizeInBits(getElementType()));
1182cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
1183 ::mlir::DataLayoutEntryListRef params)
const {
1184 return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*
this));
1187mlir::LogicalResult cir::VectorType::verify(
1188 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1189 mlir::Type elementType, uint64_t size,
bool scalable) {
1191 return emitError() <<
"the number of vector elements must be non-zero";
1195mlir::Type cir::VectorType::parse(::mlir::AsmParser &odsParser) {
1197 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
1198 mlir::Builder odsBuilder(odsParser.getContext());
1199 mlir::FailureOr<::mlir::Type> elementType;
1200 mlir::FailureOr<uint64_t> size;
1201 bool isScalabe =
false;
1204 if (odsParser.parseLess())
1208 if (odsParser.parseOptionalLSquare().succeeded())
1212 size = mlir::FieldParser<uint64_t>::parse(odsParser);
1213 if (mlir::failed(size)) {
1214 odsParser.emitError(odsParser.getCurrentLocation(),
1215 "failed to parse CIR_VectorType parameter 'size' which "
1216 "is to be a `uint64_t`");
1222 if (isScalabe && odsParser.parseRSquare().failed()) {
1223 odsParser.emitError(odsParser.getCurrentLocation(),
1224 "missing closing `]` for scalable dim size");
1229 if (odsParser.parseKeyword(
"x"))
1233 elementType = mlir::FieldParser<::mlir::Type>::parse(odsParser);
1234 if (mlir::failed(elementType)) {
1235 odsParser.emitError(odsParser.getCurrentLocation(),
1236 "failed to parse CIR_VectorType parameter "
1237 "'elementType' which is to be a `mlir::Type`");
1242 if (odsParser.parseGreater())
1244 return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
1245 mlir::Type((*elementType)),
1249void cir::VectorType::print(mlir::AsmPrinter &odsPrinter)
const {
1250 mlir::Builder odsBuilder(getContext());
1252 if (this->getIsScalable())
1255 odsPrinter.printStrippedAttrOrType(getSize());
1256 if (this->getIsScalable())
1258 odsPrinter <<
' ' <<
"x";
1260 odsPrinter.printStrippedAttrOrType(getElementType());
1269 mlir::ptr::MemorySpaceAttrInterface memorySpace) {
1270 return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>(
1277 case LangAS::Default:
1278 return LangAddressSpace::Default;
1279 case LangAS::opencl_global:
1280 return LangAddressSpace::OffloadGlobal;
1281 case LangAS::opencl_local:
1282 case LangAS::cuda_shared:
1285 return LangAddressSpace::OffloadLocal;
1286 case LangAS::cuda_device:
1287 return LangAddressSpace::OffloadGlobal;
1288 case LangAS::opencl_constant:
1289 case LangAS::cuda_constant:
1290 return LangAddressSpace::OffloadConstant;
1291 case LangAS::opencl_private:
1292 return LangAddressSpace::OffloadPrivate;
1293 case LangAS::opencl_generic:
1294 return LangAddressSpace::OffloadGeneric;
1295 case LangAS::opencl_global_device:
1296 return LangAddressSpace::OffloadGlobalDevice;
1297 case LangAS::opencl_global_host:
1298 return LangAddressSpace::OffloadGlobalHost;
1299 case LangAS::sycl_global:
1300 case LangAS::sycl_global_device:
1301 case LangAS::sycl_global_host:
1302 case LangAS::sycl_local:
1303 case LangAS::sycl_private:
1304 case LangAS::ptr32_sptr:
1305 case LangAS::ptr32_uptr:
1307 case LangAS::hlsl_groupshared:
1308 case LangAS::wasm_funcref:
1309 llvm_unreachable(
"NYI");
1311 llvm_unreachable(
"unknown/unsupported clang language address space");
1317 mlir::ptr::MemorySpaceAttrInterface &attr) {
1319 llvm::SMLoc loc = p.getCurrentLocation();
1323 if (p.parseOptionalKeyword(
"target_address_space").succeeded()) {
1325 if (p.parseLParen())
1326 return p.emitError(loc,
"expected '(' after 'target_address_space'");
1328 if (p.parseInteger(val))
1329 return p.emitError(loc,
"expected target address space value");
1331 if (p.parseRParen())
1332 return p.emitError(loc,
"expected ')'");
1334 attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val);
1335 return mlir::success();
1339 if (p.parseOptionalKeyword(
"lang_address_space").succeeded()) {
1340 if (p.parseLParen())
1341 return p.emitError(loc,
"expected '(' after 'lang_address_space'");
1343 mlir::FailureOr<cir::LangAddressSpace> result =
1344 mlir::FieldParser<cir::LangAddressSpace>::parse(p);
1345 if (mlir::failed(result))
1346 return mlir::failure();
1348 if (p.parseRParen())
1349 return p.emitError(loc,
"expected ')'");
1351 attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
1352 return mlir::success();
1355 llvm::StringRef keyword;
1356 if (p.parseOptionalKeyword(&keyword).succeeded())
1357 return p.emitError(loc,
"unknown address space specifier '")
1358 << keyword <<
"'; expected 'target_address_space' or "
1359 <<
"'lang_address_space'";
1361 return mlir::success();
1365 mlir::ptr::MemorySpaceAttrInterface attr) {
1369 if (
auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
1370 p <<
"lang_address_space("
1371 << cir::stringifyLangAddressSpace(language.getValue()) <<
')';
1375 if (
auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
1376 p <<
"target_address_space(" << target.getValue() <<
')';
1380 llvm_unreachable(
"unexpected address-space attribute kind");
1383mlir::OptionalParseResult
1385 mlir::ptr::MemorySpaceAttrInterface &attr) {
1387 mlir::SMLoc loc = p.getCurrentLocation();
1389 return p.emitError(loc,
"failed to parse Address Space Value for GlobalOp");
1390 return mlir::success();
1394 mlir::ptr::MemorySpaceAttrInterface attr) {
1399 mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1401 mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
1402 if (langAS.getValue() == cir::LangAddressSpace::Default)
1407mlir::ptr::MemorySpaceAttrInterface
1411 if (langAS == LangAS::Default)
1412 return cir::LangAddressSpaceAttr::get(&ctx, cir::LangAddressSpace::Default);
1416 return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
1429 return expected == cirAS;
1436mlir::LogicalResult cir::PointerType::verify(
1437 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1438 mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) {
1441 return emitError() <<
"unsupported address space attribute; expected "
1442 "'target_address_space' or 'lang_address_space'";
1453void CIRDialect::registerTypes() {
1456#define GET_TYPEDEF_LIST
1457#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()