14#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
15#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
16#include "mlir/IR/BuiltinTypes.h"
17#include "mlir/IR/SymbolTable.h"
18#include "mlir/Interfaces/DataLayoutInterfaces.h"
27bool isSplitStorageBitInt(cir::IntType ty,
const mlir::DataLayout &dataLayout) {
30 unsigned storageBits = ty.getStorageTypeWidth(dataLayout);
31 auto storageTy = mlir::IntegerType::get(ty.getContext(), storageBits);
32 uint64_t storeSize = storageBits / 8;
34 llvm::alignTo(storeSize, dataLayout.getTypeABIAlignment(storageTy));
35 return allocSize != storeSize;
39bool isBigEndian(
const mlir::DataLayout &dataLayout) {
41 mlir::dyn_cast_or_null<mlir::StringAttr>(dataLayout.getEndianness());
42 return endiannessStr && endiannessStr ==
"big";
48 const mlir::DataLayout &dataLayout) {
49 auto intTy = mlir::cast<cir::IntType>(attr.getType());
50 unsigned storageBits = intTy.getStorageTypeWidth(dataLayout);
51 llvm::APInt val = attr.getValue();
52 val = intTy.isSigned() ? val.sext(storageBits) : val.zext(storageBits);
54 if (!isSplitStorageBitInt(intTy, dataLayout))
55 return rewriter.getIntegerAttr(
56 mlir::IntegerType::get(intTy.getContext(), storageBits), val);
58 if (isBigEndian(dataLayout))
63 unsigned numBytes = storageBits / 8;
65 bytes.reserve(numBytes);
66 for (
unsigned i = 0; i != numBytes; ++i)
67 bytes.emplace_back(8, val.extractBitsAsZExtValue(8, i * 8));
69 auto i8Ty = mlir::IntegerType::get(intTy.getContext(), 8);
70 return mlir::DenseElementsAttr::get(
71 mlir::RankedTensorType::get({numBytes}, i8Ty),
bytes);
75 mlir::DataLayout
const &dataLayout,
76 mlir::Type type,
bool isForHLSL) {
79 if (mlir::isa<cir::BoolType>(type)) {
80 return mlir::IntegerType::get(type.getContext(),
81 dataLayout.getTypeSizeInBits(type));
84 if (
auto matrixTy = mlir::dyn_cast<cir::MatrixType>(type)) {
86 unsigned vecLen = matrixTy.getNumRows();
87 unsigned arrayLen = matrixTy.getNumColumns();
88 mlir::Type elementType = converter.convertType(matrixTy.getElementType());
89 auto vecTy = mlir::VectorType::get(vecLen, elementType);
90 return mlir::LLVM::LLVMArrayType::get(vecTy, arrayLen);
93 uint64_t size = matrixTy.getNumRows() * matrixTy.getNumColumns();
94 mlir::Type elementType = converter.convertType(matrixTy.getElementType());
95 return mlir::LLVM::LLVMArrayType::get(elementType, size);
98 if (
auto vecTy = mlir::dyn_cast<cir::VectorType>(type)) {
99 if (mlir::isa<cir::BoolType>(vecTy.getElementType())) {
101 return mlir::IntegerType::get(type.getContext(),
102 vecTy.getBoolStorageWidth());
111 if (
auto intTy = mlir::dyn_cast<cir::IntType>(type);
112 intTy && intTy.isBitInt()) {
113 if (isSplitStorageBitInt(intTy, dataLayout))
114 return mlir::LLVM::LLVMArrayType::get(
115 mlir::IntegerType::get(type.getContext(), 8),
116 intTy.getStorageTypeWidth(dataLayout) / 8);
117 return mlir::IntegerType::get(type.getContext(),
118 intTy.getStorageTypeWidth(dataLayout));
121 return converter.convertType(type);
125 mlir::DataLayout
const &dataLayout,
130 if (
auto intTy = mlir::dyn_cast<cir::IntType>(type);
131 intTy && intTy.isBitInt())
132 return mlir::IntegerType::get(type.getContext(),
133 intTy.getStorageTypeWidth(dataLayout));
137 if (
auto matrixTy = mlir::dyn_cast<cir::MatrixType>(type)) {
138 uint64_t size = matrixTy.getNumRows() * matrixTy.getNumColumns();
139 mlir::Type elemTy = converter.convertType(matrixTy.getElementType());
140 return mlir::VectorType::get(size, elemTy);
147 if (
auto intTy = mlir::dyn_cast<cir::IntType>(ty))
148 return intTy.getWidth();
149 assert(mlir::isa<cir::BoolType>(ty) &&
150 "expected CIR integer or bool element type");
154mlir::DenseElementsAttr
157 const auto stringAttr = mlir::cast<mlir::StringAttr>(attr.getElts());
158 const auto arrayTy = mlir::cast<cir::ArrayType>(attr.getType());
159 const unsigned totalSize = arrayTy.getSize();
160 const unsigned trailingZeros = attr.getTrailingZerosNum();
161 assert(stringAttr.size() + trailingZeros == totalSize &&
162 "string const_array size must match explicit elements plus "
167 values.reserve(totalSize);
172 for (
const char element : stringAttr)
173 values.emplace_back(bitWidth,
static_cast<unsigned char>(element));
175 values.insert(values.end(), trailingZeros, mlir::APInt::getZero(bitWidth));
177 return mlir::DenseElementsAttr::get(
178 mlir::RankedTensorType::get({totalSize}, type),
llvm::ArrayRef(values));
182 if (mlir::isa<cir::BoolType>(ty))
183 return mlir::APInt::getZero(1);
184 const auto intTy = mlir::cast<cir::IntType>(ty);
185 return mlir::APInt::getZero(intTy.getWidth());
189 auto fpTy = mlir::cast<cir::FPTypeInterface>(ty);
190 return mlir::APFloat::getZero(fpTy.getFloatSemantics());
198template <
typename AttrTy,
typename StorageTy>
203 if (
auto stringAttr = mlir::dyn_cast<mlir::StringAttr>(attr.getElts())) {
204 if (
auto arrayType = mlir::dyn_cast<cir::ArrayType>(attr.getType())) {
205 for (
auto element : stringAttr) {
206 auto intAttr = cir::IntAttr::get(arrayType.getElementType(), element);
207 values[currentIndex++] = mlir::dyn_cast<AttrTy>(intAttr).getValue();
210 currentIndex += attr.getTrailingZerosNum();
216 std::size_t elementsSizeInCurrentDim = 1;
217 for (std::size_t i = dimIndex; i < currentDims.size(); i++)
218 elementsSizeInCurrentDim *= currentDims[i];
220 auto arrayAttr = mlir::cast<mlir::ArrayAttr>(attr.getElts());
221 for (
auto eltAttr : arrayAttr) {
222 if constexpr (std::is_same_v<StorageTy, mlir::APInt>) {
223 if (
auto boolAttr = mlir::dyn_cast<cir::BoolAttr>(eltAttr)) {
224 values[currentIndex++] =
225 llvm::APInt(1,
static_cast<uint64_t
>(boolAttr.getValue()));
229 if (
auto valueAttr = mlir::dyn_cast<AttrTy>(eltAttr)) {
230 values[currentIndex++] = valueAttr.getValue();
234 if (
auto subArrayAttr = mlir::dyn_cast<cir::ConstArrayAttr>(eltAttr)) {
236 dimIndex, currentIndex);
237 currentIndex += elementsSizeInCurrentDim;
241 if (mlir::isa<cir::ZeroAttr, cir::UndefAttr>(eltAttr)) {
242 currentIndex += elementsSizeInCurrentDim;
248 if (
auto global = mlir::dyn_cast<cir::GlobalViewAttr>(eltAttr))
251 llvm_unreachable(
"unknown element in ConstArrayAttr");
256template <
typename AttrTy,
typename StorageTy>
259 mlir::Type elementType, mlir::Type convertedElementType) {
260 unsigned vectorSize = 1;
261 for (
auto dim : dims)
271 return mlir::DenseElementsAttr::get(
272 mlir::RankedTensorType::get(dims, convertedElementType),
280 mlir::SymbolTableCollection &symbolTables,
281 const mlir::TypeConverter *converter) {
282 if (gv.getIndices() || mlir::isa<cir::IntType, cir::VPtrType>(gv.getType()))
285 auto ptrTy = mlir::dyn_cast<cir::PointerType>(gv.getType());
289 unsigned sourceAddrSpace = 0;
290 mlir::Type sourceType;
291 auto sourceSymbol = symbolTables.lookupSymbolIn(moduleOp, gv.getSymbol());
292 if (
auto llvmSymbol = mlir::dyn_cast<mlir::LLVM::GlobalOp>(sourceSymbol)) {
293 sourceType = llvmSymbol.getType();
294 sourceAddrSpace = llvmSymbol.getAddrSpace();
295 }
else if (
auto cirSymbol = mlir::dyn_cast<cir::GlobalOp>(sourceSymbol)) {
296 sourceType = converter->convertType(cirSymbol.getSymType());
297 if (
auto targetAS = mlir::dyn_cast_if_present<cir::TargetAddressSpaceAttr>(
298 cirSymbol.getAddrSpaceAttr()))
299 sourceAddrSpace = targetAS.getValue();
306 auto llvmDstTy = converter->convertType<mlir::LLVM::LLVMPointerType>(ptrTy);
307 if (llvmDstTy.getAddressSpace() != sourceAddrSpace)
310 mlir::Type llvmEltTy = converter->convertType(ptrTy.getPointee());
311 if (llvmEltTy == sourceType)
313 if (
auto arrTy = mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(sourceType))
314 return llvmEltTy == arrTy.getElementType();
322static std::optional<mlir::Attribute>
324 mlir::ModuleOp moduleOp,
325 mlir::SymbolTableCollection &symbolTables,
326 const mlir::TypeConverter *converter) {
327 if (
auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(elt)) {
331 return gv.getSymbol();
333 if (
auto nullPtr = mlir::dyn_cast<cir::ConstPtrAttr>(elt)) {
334 if (nullPtr.isNullValue())
335 return mlir::LLVM::ZeroAttr::get(ctx);
342 if (mlir::isa<cir::PoisonAttr>(attr))
344 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(attr))
346 if (
auto constArr = mlir::dyn_cast<cir::ConstArrayAttr>(attr)) {
347 if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
349 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts()))
361 if (mlir::isa<cir::BlockAddrInfoAttr, cir::BlockAddrDiffAttr>(attr))
363 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(attr))
365 if (
auto constArr = mlir::dyn_cast<cir::ConstArrayAttr>(attr)) {
366 if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
368 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts()))
379 auto elts = mlir::dyn_cast<mlir::ArrayAttr>(attr.getElts());
380 return elts && !elts.empty() &&
385 if (
auto record = mlir::dyn_cast<cir::ConstRecordAttr>(attr))
387 auto array = mlir::dyn_cast<cir::ConstArrayAttr>(attr);
392 auto elts = mlir::dyn_cast<mlir::ArrayAttr>(array.getElts());
400 if (
auto record = mlir::dyn_cast<cir::ConstRecordAttr>(attr)) {
403 return cir::ConstRecordAttr::get(
404 mlir::cast<cir::RecordType>(record.getType()),
405 mlir::ArrayAttr::get(attr.getContext(), members));
408 auto array = mlir::cast<cir::ConstArrayAttr>(attr);
409 auto arrayTy = mlir::cast<cir::ArrayType>(array.getType());
410 auto elts = llvm::map_to_vector(mlir::cast<mlir::ArrayAttr>(array.getElts()),
413 return cir::ConstArrayAttr::get(
414 arrayTy, mlir::ArrayAttr::get(attr.getContext(), elts),
415 array.getTrailingZerosNum());
416 elts.append(array.getTrailingZerosNum(),
417 cir::ZeroAttr::get(arrayTy.getElementType()));
418 return cir::ConstArrayAttr::get(arrayTy,
419 mlir::ArrayAttr::get(attr.getContext(), elts),
424 mlir::Attribute attr, mlir::SymbolTableCollection &symbolTables,
425 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp);
431 cir::ConstArrayAttr constArr, mlir::SymbolTableCollection &symbolTables,
432 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp) {
433 mlir::MLIRContext *ctx = constArr.getContext();
434 auto arrayTy = mlir::cast<cir::ArrayType>(constArr.getType());
435 auto elts = mlir::cast<mlir::ArrayAttr>(constArr.getElts());
436 mlir::Type adjustedTy =
438 *converter, mlir::DataLayout(moduleOp));
442 auto structTy = mlir::dyn_cast<mlir::LLVM::LLVMStructType>(adjustedTy);
443 if (structTy && structTy.getBody().size() < elts.size()) {
444 auto prefix = cir::ConstArrayAttr::get(
445 cir::ArrayType::get(arrayTy.getElementType(), elts.size()), elts);
446 std::optional<mlir::Attribute> loweredPrefix =
450 lowered.push_back(*loweredPrefix);
452 for (mlir::Attribute elt : elts) {
453 std::optional<mlir::Attribute> loweredElt =
457 lowered.push_back(*loweredElt);
465 mlir::LLVM::ZeroAttr::get(ctx));
466 return mlir::ArrayAttr::get(ctx, lowered);
470 cir::ConstArrayAttr constArr, mlir::SymbolTableCollection &symbolTables,
471 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp) {
473 const auto typedConstArr = mlir::cast<mlir::TypedAttr>(constArr);
476 const auto cirArrayType = mlir::cast<cir::ArrayType>(typedConstArr.getType());
479 mlir::Type type = cirArrayType;
481 while (
auto arrayType = mlir::dyn_cast<cir::ArrayType>(type)) {
482 dims.push_back(arrayType.getSize());
483 type = arrayType.getElementType();
498 if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
500 converter->convertType(type));
501 if (mlir::isa<cir::IntType>(type)) {
505 if (mlir::cast<cir::IntType>(type).isBitInt())
508 constArr, dims, type, converter->convertType(type));
511 if (mlir::isa<cir::BoolType>(type))
513 constArr, dims, type, converter->convertType(type));
515 if (mlir::isa<cir::FPTypeInterface>(type))
517 constArr, dims, type, converter->convertType(type));
519 if (mlir::isa<cir::PointerType>(type)) {
522 if (constArr.getTrailingZerosNum() > 0)
524 auto eltsArr = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts());
528 lowered.reserve(eltsArr.size());
529 mlir::MLIRContext *ctx = constArr.getContext();
530 for (mlir::Attribute elt : eltsArr) {
531 std::optional<mlir::Attribute> llvmElt =
535 lowered.push_back(*llvmElt);
537 return mlir::ArrayAttr::get(ctx, lowered);
540 if (mlir::isa<cir::RecordType>(type)) {
542 auto eltsArr = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts());
547 loweredElts.reserve(cirArrayType.getSize());
549 for (mlir::Attribute elt : eltsArr) {
550 std::optional<mlir::Attribute> llvmElt =
554 loweredElts.push_back(*llvmElt);
560 while (loweredElts.size() < cirArrayType.getSize())
561 loweredElts.push_back(mlir::LLVM::ZeroAttr::get(constArr.getContext()));
562 return mlir::ArrayAttr::get(constArr.getContext(), loweredElts);
576 mlir::Attribute attr, mlir::SymbolTableCollection &symbolTables,
577 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp) {
578 mlir::MLIRContext *ctx = attr.getContext();
580 if (
auto arrayAttr = mlir::dyn_cast<cir::ConstArrayAttr>(attr))
583 if (
auto recordAttr = mlir::dyn_cast<cir::ConstRecordAttr>(attr))
586 if (mlir::isa<cir::ZeroAttr>(attr))
587 return mlir::LLVM::ZeroAttr::get(ctx);
589 if (mlir::isa<cir::UndefAttr>(attr))
590 return mlir::LLVM::UndefAttr::get(ctx);
592 if (
auto intAttr = mlir::dyn_cast<cir::IntAttr>(attr)) {
595 if (mlir::cast<cir::IntType>(intAttr.getType()).isBitInt())
597 return mlir::IntegerAttr::get(converter->convertType(intAttr.getType()),
601 if (
auto boolAttr = mlir::dyn_cast<cir::BoolAttr>(attr))
602 return mlir::IntegerAttr::get(converter->convertType(boolAttr.getType()),
603 boolAttr.getValue() ? 1 : 0);
605 if (
auto fpAttr = mlir::dyn_cast<cir::FPAttr>(attr))
606 return mlir::FloatAttr::get(converter->convertType(fpAttr.getType()),
625 uint64_t maxAlign = 1;
626 uint64_t totalSize = 0;
627 for (mlir::Type member : members) {
628 uint64_t align = dataLayout.getTypeABIAlignment(member);
629 maxAlign = std::max(maxAlign, align);
630 uint64_t size = dataLayout.getTypeSize(member).getFixedValue();
632 if (llvm::alignTo(totalSize, align) != totalSize)
637 return llvm::alignTo(totalSize, maxAlign) != totalSize;
656 mlir::LLVM::LLVMStructType structTy, cir::ConstRecordAttr constRecord,
657 const mlir::TypeConverter &converter,
const mlir::DataLayout &dataLayout,
659 assert(paddingAddedIndexes.empty() &&
660 "Not for accumulation, just single depth");
662 constRecord.getMembers().getValue();
665 bool packed = structTy.isPacked();
666 uint64_t curOffset = 0;
667 bool changed =
false;
673 for (
auto [idx, member] : llvm::enumerate(initMembers)) {
674 if (idx >= origBody.size())
676 mlir::Type adjusted =
680 unsigned adjustedAlign = dataLayout.getTypeABIAlignment(adjusted);
682 if (adjusted != origBody[idx]) {
686 unsigned origAlign = dataLayout.getTypeABIAlignment(origBody[idx]);
688 uint64_t origOffset =
689 packed ? curOffset : llvm::alignTo(curOffset, origAlign);
690 uint64_t adjustedOffset =
691 packed ? curOffset : llvm::alignTo(curOffset, adjustedAlign);
693 if (adjustedOffset != origOffset) {
697 assert(adjustedOffset < origOffset);
701 uint64_t difference = origOffset - curOffset;
702 newBody.push_back(mlir::LLVM::LLVMArrayType::get(
703 mlir::IntegerType::get(structTy.getContext(), 8), difference));
704 paddingAddedIndexes.push_back(idx);
705 curOffset = origOffset;
709 newBody.push_back(adjusted);
712 curOffset = llvm::alignTo(curOffset, adjustedAlign);
713 curOffset += dataLayout.getTypeSize(adjusted).getFixedValue();
722 bool widenedFAM =
false;
724 mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(structTy.getBody().back());
725 fam && fam.getNumElements() == 0) {
726 mlir::Type lastInitType =
727 mlir::cast<mlir::TypedAttr>(initMembers.back()).getType();
728 if (mlir::cast<cir::ArrayType>(lastInitType).getSize() != 0) {
731 initMembers.back(), converter, dataLayout);
748 uint64_t declaredSize = dataLayout.getTypeSize(structTy).getFixedValue();
749 assert(curOffset <= declaredSize &&
"body bigger than type?");
750 if (curOffset < declaredSize)
751 newBody.push_back(mlir::LLVM::LLVMArrayType::get(
752 mlir::IntegerType::get(structTy.getContext(), 8),
753 declaredSize - curOffset));
756 return mlir::LLVM::LLVMStructType::getLiteral(structTy.getContext(), newBody,
769 mlir::LLVM::LLVMStructType structTy, cir::ConstRecordAttr constRecord,
770 const mlir::TypeConverter &converter,
const mlir::DataLayout &dataLayout) {
772 auto unionTy = mlir::cast<cir::UnionType>(constRecord.getType());
775 assert(constRecord.getMembers().size() == 1);
776 mlir::Attribute member = constRecord.getMembers()[0];
778 converter, dataLayout, mlir::cast<mlir::TypedAttr>(member).
getType());
790 if (memberTy == structTy.getBody().front())
793 uint64_t unionSize = dataLayout.getTypeSize(unionTy).getFixedValue();
794 uint64_t initSize = dataLayout.getTypeSize(memberTy).getFixedValue();
796 newBody.push_back(memberTy);
799 if (initSize < unionSize)
800 newBody.push_back(mlir::LLVM::LLVMArrayType::get(
801 mlir::IntegerType::get(structTy.getContext(), 8),
802 unionSize - initSize));
804 return mlir::LLVM::LLVMStructType::getLiteral(structTy.getContext(), newBody,
805 unionTy.getPacked());
819 mlir::LLVM::LLVMArrayType arrayTy, cir::ConstArrayAttr arrayInit,
820 const mlir::TypeConverter &converter,
const mlir::DataLayout &dataLayout) {
821 auto elts = mlir::dyn_cast<mlir::ArrayAttr>(arrayInit.getElts());
826 mlir::Type origEltTy = arrayTy.getElementType();
828 adjustedElts.reserve(elts.size());
829 bool changed = elts.size() > arrayTy.getNumElements();
831 for (mlir::Attribute elt : elts) {
832 mlir::Type adjusted =
836 changed |= adjusted != origEltTy;
837 adjustedElts.push_back(adjusted);
841 mlir::Type commonEltTy =
842 llvm::all_equal(adjustedElts) ? adjustedElts.front() : mlir::Type{};
846 mlir::LLVM::LLVMArrayType::get(commonEltTy, adjustedElts.size()));
848 body.append(adjustedElts);
850 mlir::LLVM::LLVMArrayType::get(commonEltTy ? commonEltTy : origEltTy,
851 arrayInit.getTrailingZerosNum()));
852 return mlir::LLVM::LLVMStructType::getLiteral(arrayTy.getContext(), body,
860 std::max<size_t>(adjustedElts.size(), arrayTy.getNumElements()),
863 if (llvm::all_equal(adjustedElts))
864 return mlir::LLVM::LLVMArrayType::get(adjustedElts.front(),
865 adjustedElts.size());
868 return mlir::LLVM::LLVMStructType::getLiteral(
869 arrayTy.getContext(), adjustedElts,
true);
875 const mlir::TypeConverter &converter,
876 const mlir::DataLayout &dataLayout,
880 if (
auto arrayInit = mlir::dyn_cast_if_present<cir::ConstArrayAttr>(init)) {
881 auto arrayTy = mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(llvmType);
889 auto constRecord = mlir::dyn_cast_if_present<cir::ConstRecordAttr>(init);
895 auto structTy = mlir::dyn_cast<mlir::LLVM::LLVMStructType>(llvmType);
896 if (!structTy || structTy.getBody().empty())
900 if (mlir::isa<cir::StructType>(constRecord.getType()))
902 dataLayout, paddingAddedIndexes);
903 if (mlir::isa<cir::UnionType>(constRecord.getType()))
910 const mlir::TypeConverter &converter,
911 const mlir::DataLayout &dataLayout) {
914 ignoredAddedIndexes);
918 cir::ConstRecordAttr constRecord, mlir::SymbolTableCollection &symbolTables,
919 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp) {
925 mlir::ArrayAttr memberAttrs = constRecord.getMembers();
927 loweredMembers.reserve(memberAttrs.size());
928 for (mlir::Attribute member : memberAttrs) {
929 std::optional<mlir::Attribute> lowered =
933 loweredMembers.push_back(*lowered);
951 converter->convertType(constRecord.getType()), constRecord, *converter,
952 mlir::DataLayout(moduleOp), paddingAddedIndexes);
959 for (
unsigned paddedElt : llvm::reverse(paddingAddedIndexes))
960 loweredMembers.insert(loweredMembers.begin() + paddedElt,
961 mlir::LLVM::ZeroAttr::get(constRecord.getContext()));
966 if (
auto structTy = mlir::dyn_cast<mlir::LLVM::LLVMStructType>(adjustedTy))
967 while (loweredMembers.size() < structTy.getBody().size())
968 loweredMembers.push_back(
969 mlir::LLVM::ZeroAttr::get(constRecord.getContext()));
971 return mlir::ArrayAttr::get(constRecord.getContext(), loweredMembers);
975 mlir::Type typ,
const llvm::APInt &val) {
976 return mlir::LLVM::ConstantOp::create(bld, loc, typ, val);
979mlir::Value
getConst(mlir::OpBuilder &bld, mlir::Location loc, mlir::Type typ,
981 return mlir::LLVM::ConstantOp::create(bld, loc, typ, val);
984mlir::Value
createShL(mlir::OpBuilder &bld, mlir::Value lhs,
unsigned rhs) {
987 mlir::Value rhsVal =
getConst(bld, lhs.getLoc(), lhs.getType(), rhs);
988 return mlir::LLVM::ShlOp::create(bld, lhs.getLoc(), lhs, rhsVal);
991mlir::Value
createAShR(mlir::OpBuilder &bld, mlir::Value lhs,
unsigned rhs) {
994 mlir::Value rhsVal =
getConst(bld, lhs.getLoc(), lhs.getType(), rhs);
995 return mlir::LLVM::AShrOp::create(bld, lhs.getLoc(), lhs, rhsVal);
998mlir::Value
createAnd(mlir::OpBuilder &bld, mlir::Value lhs,
999 const llvm::APInt &rhs) {
1000 mlir::Value rhsVal =
getConstAPInt(bld, lhs.getLoc(), lhs.getType(), rhs);
1001 return mlir::LLVM::AndOp::create(bld, lhs.getLoc(), lhs, rhsVal);
1004mlir::Value
createLShR(mlir::OpBuilder &bld, mlir::Value lhs,
unsigned rhs) {
1007 mlir::Value rhsVal =
getConst(bld, lhs.getLoc(), lhs.getType(), rhs);
1008 return mlir::LLVM::LShrOp::create(bld, lhs.getLoc(), lhs, rhsVal);
static StringRef bytes(const std::vector< T, Allocator > &v)
mlir::Attribute spellOutSplitTrailingZeros(mlir::Attribute attr)
Return attr with the trailing zeros of any array that adjustGlobalTypeForInit would split off written...
mlir::DenseElementsAttr convertStringAttrToDenseElementsAttr(cir::ConstArrayAttr attr, mlir::Type type)
static bool globalViewMatchesPointerLeaf(cir::GlobalViewAttr gv, mlir::ModuleOp moduleOp, mlir::SymbolTableCollection &symbolTables, const mlir::TypeConverter *converter)
Return true when gv can be lowered to a FlatSymbolRefAttr leaf without addrspacecast or bitcast (mirr...
mlir::Value createLShR(mlir::OpBuilder &bld, mlir::Value lhs, unsigned rhs)
static std::optional< mlir::Attribute > lowerConstArrayAttrByElement(cir::ConstArrayAttr constArr, mlir::SymbolTableCollection &symbolTables, const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp)
Lower constArr, which is or contains an array split by adjustGlobalArrayTypeForInit,...
mlir::Value createShL(mlir::OpBuilder &bld, mlir::Value lhs, unsigned rhs)
mlir::Value getConst(mlir::OpBuilder &bld, mlir::Location loc, mlir::Type typ, unsigned val)
static mlir::Type adjustGlobalStructTypeForInit(mlir::LLVM::LLVMStructType structTy, cir::ConstRecordAttr constRecord, const mlir::TypeConverter &converter, const mlir::DataLayout &dataLayout, llvm::SmallVectorImpl< unsigned > &paddingAddedIndexes)
mlir::Value getConstAPInt(mlir::OpBuilder &bld, mlir::Location loc, mlir::Type typ, const llvm::APInt &val)
std::optional< mlir::DenseElementsAttr > convertToDenseElementsAttr(cir::ConstArrayAttr attr, const llvm::SmallVectorImpl< int64_t > &dims, mlir::Type elementType, mlir::Type convertedElementType)
std::optional< mlir::Attribute > lowerConstArrayAttr(cir::ConstArrayAttr constArr, mlir::SymbolTableCollection &symbolTables, const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp)
mlir::Type adjustGlobalTypeForInit(mlir::Type llvmType, mlir::Attribute init, const mlir::TypeConverter &converter, const mlir::DataLayout &dataLayout, llvm::SmallVectorImpl< unsigned > &paddingAddedIndexes)
mlir::Type convertTypeForMemory(const mlir::TypeConverter &converter, mlir::DataLayout const &dataLayout, mlir::Type type, bool isForHLSL)
static mlir::Type adjustGlobalArrayTypeForInit(mlir::LLVM::LLVMArrayType arrayTy, cir::ConstArrayAttr arrayInit, const mlir::TypeConverter &converter, const mlir::DataLayout &dataLayout)
static bool containsPoison(mlir::Attribute attr)
static std::optional< mlir::Attribute > lowerPointerElementAttr(mlir::Attribute elt, mlir::MLIRContext *ctx, mlir::ModuleOp moduleOp, mlir::SymbolTableCollection &symbolTables, const mlir::TypeConverter *converter)
Lower a single pointer-element of a cir.const_array to an LLVM-dialect constant leaf suitable for a b...
mlir::Value createAShR(mlir::OpBuilder &bld, mlir::Value lhs, unsigned rhs)
std::optional< mlir::Attribute > lowerConstRecordAttr(cir::ConstRecordAttr constRecord, mlir::SymbolTableCollection &symbolTables, const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp)
static std::optional< mlir::Attribute > lowerConstRecordMemberAttr(mlir::Attribute attr, mlir::SymbolTableCollection &symbolTables, const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp)
Lower a constant attribute that initializes a single member of a record (or a leaf of a nested aggreg...
mlir::Value createAnd(mlir::OpBuilder &bld, mlir::Value lhs, const llvm::APInt &rhs)
bool convertToDenseElementsAttrImpl(cir::ConstArrayAttr attr, llvm::SmallVectorImpl< StorageTy > &values, const llvm::SmallVectorImpl< int64_t > ¤tDims, int64_t dimIndex, int64_t currentIndex)
static bool containsSplitTrailingZeros(mlir::Attribute attr)
mlir::Type convertTypeForLoadStore(const mlir::TypeConverter &converter, mlir::DataLayout const &dataLayout, mlir::Type type)
The type of a load/store's value, as opposed to convertTypeForMemory's type of the memory it lives in...
static bool shouldPackFAMStruct(const mlir::DataLayout &dataLayout, llvm::ArrayRef< mlir::Type > members)
static bool shouldSplitTrailingZeros(cir::ConstArrayAttr attr)
static bool containsBlockAddress(mlir::Attribute attr)
Block-address attributes (address-of-label and label differences) are lowered to relocation expressio...
static constexpr int minSplitTrailingZeros
The fewest trailing zeros that adjustGlobalArrayTypeForInit splits off an array constant into a zero-...
static mlir::Type adjustGlobalUnionTypeForInit(mlir::LLVM::LLVMStructType structTy, cir::ConstRecordAttr constRecord, const mlir::TypeConverter &converter, const mlir::DataLayout &dataLayout)
mlir::Attribute getBitIntStorageAttr(mlir::ConversionPatternRewriter &rewriter, cir::IntAttr attr, const mlir::DataLayout &dataLayout)
mlir::APInt getZeroInitFromType(mlir::Type ty)
static unsigned getIntOrBoolBitWidth(mlir::Type ty)
mlir::Attribute spellOutSplitTrailingZeros(mlir::Attribute attr)
Return attr with the trailing zeros of any array that adjustGlobalTypeForInit would split off written...
StorageTy getZeroInitFromType(mlir::Type ty)
void convertToDenseElementsAttrImpl(cir::ConstArrayAttr attr, llvm::SmallVectorImpl< StorageTy > &values)
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t