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;
40 mlir::DataLayout
const &dataLayout,
44 if (mlir::isa<cir::BoolType>(type)) {
45 return mlir::IntegerType::get(type.getContext(),
46 dataLayout.getTypeSizeInBits(type));
49 if (
auto vecTy = mlir::dyn_cast<cir::VectorType>(type)) {
50 if (mlir::isa<cir::BoolType>(vecTy.getElementType())) {
53 uint64_t bytePadded = std::max<uint64_t>(vecTy.getSize(), 8);
54 return mlir::IntegerType::get(type.getContext(), bytePadded);
63 if (
auto intTy = mlir::dyn_cast<cir::IntType>(type);
64 intTy && intTy.isBitInt()) {
65 if (isSplitStorageBitInt(intTy, dataLayout))
67 return mlir::IntegerType::get(type.getContext(),
68 intTy.getStorageTypeWidth(dataLayout));
71 return converter.convertType(type);
75 if (
auto intTy = mlir::dyn_cast<cir::IntType>(ty))
76 return intTy.getWidth();
77 assert(mlir::isa<cir::BoolType>(ty) &&
78 "expected CIR integer or bool element type");
82mlir::DenseElementsAttr
85 const auto stringAttr = mlir::cast<mlir::StringAttr>(attr.getElts());
86 const auto arrayTy = mlir::cast<cir::ArrayType>(attr.getType());
87 const unsigned totalSize = arrayTy.getSize();
88 const unsigned trailingZeros = attr.getTrailingZerosNum();
89 assert(stringAttr.size() + trailingZeros == totalSize &&
90 "string const_array size must match explicit elements plus "
95 values.reserve(totalSize);
100 for (
const char element : stringAttr)
101 values.emplace_back(bitWidth,
static_cast<unsigned char>(element));
103 values.insert(values.end(), trailingZeros, mlir::APInt::getZero(bitWidth));
105 return mlir::DenseElementsAttr::get(
106 mlir::RankedTensorType::get({totalSize}, type),
llvm::ArrayRef(values));
110 if (mlir::isa<cir::BoolType>(ty))
111 return mlir::APInt::getZero(1);
112 const auto intTy = mlir::cast<cir::IntType>(ty);
113 return mlir::APInt::getZero(intTy.getWidth());
117 auto fpTy = mlir::cast<cir::FPTypeInterface>(ty);
118 return mlir::APFloat::getZero(fpTy.getFloatSemantics());
126template <
typename AttrTy,
typename StorageTy>
130 int64_t currentIndex) {
131 if (
auto stringAttr = mlir::dyn_cast<mlir::StringAttr>(attr.getElts())) {
132 if (
auto arrayType = mlir::dyn_cast<cir::ArrayType>(attr.getType())) {
133 for (
auto element : stringAttr) {
134 auto intAttr = cir::IntAttr::get(arrayType.getElementType(), element);
135 values[currentIndex++] = mlir::dyn_cast<AttrTy>(intAttr).getValue();
138 currentIndex += attr.getTrailingZerosNum();
144 std::size_t elementsSizeInCurrentDim = 1;
145 for (std::size_t i = dimIndex; i < currentDims.size(); i++)
146 elementsSizeInCurrentDim *= currentDims[i];
148 auto arrayAttr = mlir::cast<mlir::ArrayAttr>(attr.getElts());
149 for (
auto eltAttr : arrayAttr) {
150 if constexpr (std::is_same_v<StorageTy, mlir::APInt>) {
151 if (
auto boolAttr = mlir::dyn_cast<cir::BoolAttr>(eltAttr)) {
152 values[currentIndex++] =
153 llvm::APInt(1,
static_cast<uint64_t
>(boolAttr.getValue()));
157 if (
auto valueAttr = mlir::dyn_cast<AttrTy>(eltAttr)) {
158 values[currentIndex++] = valueAttr.getValue();
162 if (
auto subArrayAttr = mlir::dyn_cast<cir::ConstArrayAttr>(eltAttr)) {
164 dimIndex, currentIndex);
165 currentIndex += elementsSizeInCurrentDim;
169 if (mlir::isa<cir::ZeroAttr, cir::UndefAttr>(eltAttr)) {
170 currentIndex += elementsSizeInCurrentDim;
174 llvm_unreachable(
"unknown element in ConstArrayAttr");
178template <
typename AttrTy,
typename StorageTy>
181 mlir::Type elementType, mlir::Type convertedElementType) {
182 unsigned vectorSize = 1;
183 for (
auto dim : dims)
189 return mlir::DenseElementsAttr::get(
190 mlir::RankedTensorType::get(dims, convertedElementType),
198 mlir::SymbolTableCollection &symbolTables,
199 const mlir::TypeConverter *converter) {
200 if (gv.getIndices() || mlir::isa<cir::IntType, cir::VPtrType>(gv.getType()))
203 auto ptrTy = mlir::dyn_cast<cir::PointerType>(gv.getType());
207 unsigned sourceAddrSpace = 0;
208 mlir::Type sourceType;
209 auto sourceSymbol = symbolTables.lookupSymbolIn(moduleOp, gv.getSymbol());
210 if (
auto llvmSymbol = mlir::dyn_cast<mlir::LLVM::GlobalOp>(sourceSymbol)) {
211 sourceType = llvmSymbol.getType();
212 sourceAddrSpace = llvmSymbol.getAddrSpace();
213 }
else if (
auto cirSymbol = mlir::dyn_cast<cir::GlobalOp>(sourceSymbol)) {
214 sourceType = converter->convertType(cirSymbol.getSymType());
215 if (
auto targetAS = mlir::dyn_cast_if_present<cir::TargetAddressSpaceAttr>(
216 cirSymbol.getAddrSpaceAttr()))
217 sourceAddrSpace = targetAS.getValue();
224 auto llvmDstTy = converter->convertType<mlir::LLVM::LLVMPointerType>(ptrTy);
225 if (llvmDstTy.getAddressSpace() != sourceAddrSpace)
228 mlir::Type llvmEltTy = converter->convertType(ptrTy.getPointee());
229 if (llvmEltTy == sourceType)
231 if (
auto arrTy = mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(sourceType))
232 return llvmEltTy == arrTy.getElementType();
240static std::optional<mlir::Attribute>
242 mlir::ModuleOp moduleOp,
243 mlir::SymbolTableCollection &symbolTables,
244 const mlir::TypeConverter *converter) {
245 if (
auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(elt)) {
249 return gv.getSymbol();
251 if (
auto nullPtr = mlir::dyn_cast<cir::ConstPtrAttr>(elt)) {
252 if (nullPtr.isNullValue())
253 return mlir::LLVM::ZeroAttr::get(ctx);
260 if (mlir::isa<cir::PoisonAttr>(attr))
262 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(attr))
264 if (
auto constArr = mlir::dyn_cast<cir::ConstArrayAttr>(attr)) {
265 if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
267 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts()))
279 if (mlir::isa<cir::BlockAddrInfoAttr, cir::BlockAddrDiffAttr>(attr))
281 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(attr))
283 if (
auto constArr = mlir::dyn_cast<cir::ConstArrayAttr>(attr)) {
284 if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
286 if (
auto elts = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts()))
293 mlir::Attribute attr, mlir::SymbolTableCollection &symbolTables,
294 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp);
297 cir::ConstArrayAttr constArr, mlir::SymbolTableCollection &symbolTables,
298 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp) {
300 const auto typedConstArr = mlir::cast<mlir::TypedAttr>(constArr);
303 const auto cirArrayType = mlir::cast<cir::ArrayType>(typedConstArr.getType());
306 mlir::Type type = cirArrayType;
308 while (
auto arrayType = mlir::dyn_cast<cir::ArrayType>(type)) {
309 dims.push_back(arrayType.getSize());
310 type = arrayType.getElementType();
321 if (mlir::isa<mlir::StringAttr>(constArr.getElts()))
323 converter->convertType(type));
324 if (mlir::isa<cir::IntType>(type)) {
328 if (mlir::cast<cir::IntType>(type).isBitInt())
331 constArr, dims, type, converter->convertType(type));
334 if (mlir::isa<cir::BoolType>(type))
336 constArr, dims, type, converter->convertType(type));
338 if (mlir::isa<cir::FPTypeInterface>(type))
340 constArr, dims, type, converter->convertType(type));
342 if (mlir::isa<cir::PointerType>(type)) {
345 if (constArr.getTrailingZerosNum() > 0)
347 auto eltsArr = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts());
351 lowered.reserve(eltsArr.size());
352 mlir::MLIRContext *ctx = constArr.getContext();
353 for (mlir::Attribute elt : eltsArr) {
354 std::optional<mlir::Attribute> llvmElt =
358 lowered.push_back(*llvmElt);
360 return mlir::ArrayAttr::get(ctx, lowered);
363 if (mlir::isa<cir::RecordType>(type)) {
365 auto eltsArr = mlir::dyn_cast<mlir::ArrayAttr>(constArr.getElts());
370 loweredElts.reserve(cirArrayType.getSize());
372 for (mlir::Attribute elt : eltsArr) {
373 std::optional<mlir::Attribute> llvmElt =
377 loweredElts.push_back(*llvmElt);
383 while (loweredElts.size() < cirArrayType.getSize())
384 loweredElts.push_back(mlir::LLVM::ZeroAttr::get(constArr.getContext()));
385 return mlir::ArrayAttr::get(constArr.getContext(), loweredElts);
399 mlir::Attribute attr, mlir::SymbolTableCollection &symbolTables,
400 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp) {
401 mlir::MLIRContext *ctx = attr.getContext();
403 if (
auto arrayAttr = mlir::dyn_cast<cir::ConstArrayAttr>(attr))
406 if (
auto recordAttr = mlir::dyn_cast<cir::ConstRecordAttr>(attr))
409 if (mlir::isa<cir::ZeroAttr>(attr))
410 return mlir::LLVM::ZeroAttr::get(ctx);
412 if (mlir::isa<cir::UndefAttr>(attr))
413 return mlir::LLVM::UndefAttr::get(ctx);
415 if (
auto intAttr = mlir::dyn_cast<cir::IntAttr>(attr)) {
418 if (mlir::cast<cir::IntType>(intAttr.getType()).isBitInt())
420 return mlir::IntegerAttr::get(converter->convertType(intAttr.getType()),
424 if (
auto boolAttr = mlir::dyn_cast<cir::BoolAttr>(attr))
425 return mlir::IntegerAttr::get(converter->convertType(boolAttr.getType()),
426 boolAttr.getValue() ? 1 : 0);
428 if (
auto fpAttr = mlir::dyn_cast<cir::FPAttr>(attr))
429 return mlir::FloatAttr::get(converter->convertType(fpAttr.getType()),
448 uint64_t maxAlign = 1;
449 uint64_t totalSize = 0;
450 for (mlir::Type member : members) {
451 uint64_t align = dataLayout.getTypeABIAlignment(member);
452 maxAlign = std::max(maxAlign, align);
453 uint64_t size = dataLayout.getTypeSize(member).getFixedValue();
455 if (llvm::alignTo(totalSize, align) != totalSize)
460 return llvm::alignTo(totalSize, maxAlign) != totalSize;
479 mlir::LLVM::LLVMStructType structTy, cir::ConstRecordAttr constRecord,
480 const mlir::TypeConverter &converter,
const mlir::DataLayout &dataLayout,
482 assert(paddingAddedIndexes.empty() &&
483 "Not for accumulation, just single depth");
485 constRecord.getMembers().getValue();
488 bool packed = structTy.isPacked();
489 uint64_t curOffset = 0;
490 bool changed =
false;
496 for (
auto [idx, member] : llvm::enumerate(initMembers)) {
497 if (idx >= origBody.size())
499 mlir::Type adjusted =
501 unsigned adjustedAlign = dataLayout.getTypeABIAlignment(adjusted);
503 if (adjusted != origBody[idx]) {
507 unsigned origAlign = dataLayout.getTypeABIAlignment(origBody[idx]);
509 uint64_t origOffset =
510 packed ? curOffset : llvm::alignTo(curOffset, origAlign);
511 uint64_t adjustedOffset =
512 packed ? curOffset : llvm::alignTo(curOffset, adjustedAlign);
514 if (adjustedOffset != origOffset) {
518 assert(adjustedOffset < origOffset);
522 uint64_t difference = origOffset - curOffset;
523 newBody.push_back(mlir::LLVM::LLVMArrayType::get(
524 mlir::IntegerType::get(structTy.getContext(), 8), difference));
525 paddingAddedIndexes.push_back(idx);
526 curOffset = origOffset;
530 newBody.push_back(adjusted);
533 curOffset = llvm::alignTo(curOffset, adjustedAlign);
534 curOffset += dataLayout.getTypeSize(adjusted).getFixedValue();
543 bool widenedFAM =
false;
545 mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(structTy.getBody().back());
546 fam && fam.getNumElements() == 0) {
547 mlir::Type lastInitType =
548 mlir::cast<mlir::TypedAttr>(initMembers.back()).getType();
549 if (mlir::cast<cir::ArrayType>(lastInitType).getSize() != 0) {
552 initMembers.back(), converter, dataLayout);
567 uint64_t declaredSize = dataLayout.getTypeSize(structTy).getFixedValue();
568 assert(curOffset <= declaredSize &&
"body bigger than type?");
569 if (curOffset < declaredSize)
570 newBody.push_back(mlir::LLVM::LLVMArrayType::get(
571 mlir::IntegerType::get(structTy.getContext(), 8),
572 declaredSize - curOffset));
575 return mlir::LLVM::LLVMStructType::getLiteral(structTy.getContext(), newBody,
588 mlir::LLVM::LLVMStructType structTy, cir::ConstRecordAttr constRecord,
589 const mlir::TypeConverter &converter,
const mlir::DataLayout &dataLayout) {
591 auto unionTy = mlir::cast<cir::UnionType>(constRecord.getType());
594 assert(constRecord.getMembers().size() == 1);
595 mlir::Attribute member = constRecord.getMembers()[0];
597 converter, dataLayout, mlir::cast<mlir::TypedAttr>(member).
getType());
607 if (memberTy == structTy.getBody().front())
610 uint64_t unionSize = dataLayout.getTypeSize(unionTy).getFixedValue();
611 uint64_t initSize = dataLayout.getTypeSize(memberTy).getFixedValue();
612 assert(initSize <= unionSize &&
"union initializer larger than the union");
615 newBody.push_back(memberTy);
618 if (initSize < unionSize)
619 newBody.push_back(mlir::LLVM::LLVMArrayType::get(
620 mlir::IntegerType::get(structTy.getContext(), 8),
621 unionSize - initSize));
623 return mlir::LLVM::LLVMStructType::getLiteral(structTy.getContext(), newBody,
624 unionTy.getPacked());
631 mlir::LLVM::LLVMArrayType arrayTy, cir::ConstArrayAttr arrayInit,
632 const mlir::TypeConverter &converter,
const mlir::DataLayout &dataLayout) {
633 auto elts = mlir::dyn_cast<mlir::ArrayAttr>(arrayInit.getElts());
638 mlir::Type origEltTy = arrayTy.getElementType();
641 bool changed =
false;
643 for (
auto [idx, elt] : llvm::enumerate(elts)) {
644 mlir::Type adjusted =
647 if (idx >= arrayTy.getNumElements()) {
648 adjustedElts.push_back(adjusted);
650 }
else if (adjusted != origEltTy) {
651 adjustedElts[idx] = adjusted;
659 if (llvm::all_equal(adjustedElts))
660 return mlir::LLVM::LLVMArrayType::get(adjustedElts.front(),
661 adjustedElts.size());
664 return mlir::LLVM::LLVMStructType::getLiteral(
665 arrayTy.getContext(), adjustedElts,
true);
671 const mlir::TypeConverter &converter,
672 const mlir::DataLayout &dataLayout,
674 if (
auto arrayInit = mlir::dyn_cast_if_present<cir::ConstArrayAttr>(init)) {
675 auto arrayTy = mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(llvmType);
683 auto constRecord = mlir::dyn_cast_if_present<cir::ConstRecordAttr>(init);
689 auto structTy = mlir::dyn_cast<mlir::LLVM::LLVMStructType>(llvmType);
690 if (!structTy || structTy.getBody().empty())
694 if (mlir::isa<cir::StructType>(constRecord.getType()))
696 dataLayout, paddingAddedIndexes);
697 if (mlir::isa<cir::UnionType>(constRecord.getType()))
704 const mlir::TypeConverter &converter,
705 const mlir::DataLayout &dataLayout) {
708 ignoredAddedIndexes);
712 cir::ConstRecordAttr constRecord, mlir::SymbolTableCollection &symbolTables,
713 const mlir::TypeConverter *converter, mlir::ModuleOp moduleOp) {
719 mlir::ArrayAttr memberAttrs = constRecord.getMembers();
721 loweredMembers.reserve(memberAttrs.size());
722 for (mlir::Attribute member : memberAttrs) {
723 std::optional<mlir::Attribute> lowered =
727 loweredMembers.push_back(*lowered);
745 converter->convertType(constRecord.getType()), constRecord, *converter,
746 mlir::DataLayout(moduleOp), paddingAddedIndexes);
751 for (
unsigned paddedElt : llvm::reverse(paddingAddedIndexes))
752 loweredMembers.insert(loweredMembers.begin() + paddedElt,
753 mlir::LLVM::ZeroAttr::get(constRecord.getContext()));
758 if (
auto structTy = mlir::dyn_cast<mlir::LLVM::LLVMStructType>(adjustedTy))
759 while (loweredMembers.size() < structTy.getBody().size())
760 loweredMembers.push_back(
761 mlir::LLVM::ZeroAttr::get(constRecord.getContext()));
763 return mlir::ArrayAttr::get(constRecord.getContext(), loweredMembers);
767 mlir::Type typ,
const llvm::APInt &val) {
768 return mlir::LLVM::ConstantOp::create(bld, loc, typ, val);
771mlir::Value
getConst(mlir::OpBuilder &bld, mlir::Location loc, mlir::Type typ,
773 return mlir::LLVM::ConstantOp::create(bld, loc, typ, val);
776mlir::Value
createShL(mlir::OpBuilder &bld, mlir::Value lhs,
unsigned rhs) {
779 mlir::Value rhsVal =
getConst(bld, lhs.getLoc(), lhs.getType(), rhs);
780 return mlir::LLVM::ShlOp::create(bld, lhs.getLoc(), lhs, rhsVal);
783mlir::Value
createAShR(mlir::OpBuilder &bld, mlir::Value lhs,
unsigned rhs) {
786 mlir::Value rhsVal =
getConst(bld, lhs.getLoc(), lhs.getType(), rhs);
787 return mlir::LLVM::AShrOp::create(bld, lhs.getLoc(), lhs, rhsVal);
790mlir::Value
createAnd(mlir::OpBuilder &bld, mlir::Value lhs,
791 const llvm::APInt &rhs) {
792 mlir::Value rhsVal =
getConstAPInt(bld, lhs.getLoc(), lhs.getType(), rhs);
793 return mlir::LLVM::AndOp::create(bld, lhs.getLoc(), lhs, rhsVal);
796mlir::Value
createLShR(mlir::OpBuilder &bld, mlir::Value lhs,
unsigned rhs) {
799 mlir::Value rhsVal =
getConst(bld, lhs.getLoc(), lhs.getType(), rhs);
800 return mlir::LLVM::LShrOp::create(bld, lhs.getLoc(), lhs, rhsVal);
mlir::DenseElementsAttr convertStringAttrToDenseElementsAttr(cir::ConstArrayAttr attr, mlir::Type type)
mlir::Type convertTypeForMemory(const mlir::TypeConverter &converter, mlir::DataLayout const &dataLayout, 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)
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::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)
void convertToDenseElementsAttrImpl(cir::ConstArrayAttr attr, llvm::SmallVectorImpl< StorageTy > &values, const llvm::SmallVectorImpl< int64_t > ¤tDims, int64_t dimIndex, int64_t currentIndex)
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)
static bool shouldPackFAMStruct(const mlir::DataLayout &dataLayout, llvm::ArrayRef< mlir::Type > members)
mlir::DenseElementsAttr convertToDenseElementsAttr(cir::ConstArrayAttr attr, const llvm::SmallVectorImpl< int64_t > &dims, mlir::Type elementType, mlir::Type convertedElementType)
static bool containsBlockAddress(mlir::Attribute attr)
Block-address attributes (address-of-label and label differences) are lowered to relocation expressio...
static mlir::Type adjustGlobalUnionTypeForInit(mlir::LLVM::LLVMStructType structTy, cir::ConstRecordAttr constRecord, const mlir::TypeConverter &converter, const mlir::DataLayout &dataLayout)
mlir::APInt getZeroInitFromType(mlir::Type ty)
static unsigned getIntOrBoolBitWidth(mlir::Type ty)
StorageTy getZeroInitFromType(mlir::Type ty)