================ @@ -225,17 +235,88 @@ void RecordType::complete(ArrayRef<Type> members, bool packed, bool padded) { //===----------------------------------------------------------------------===// llvm::TypeSize -RecordType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout, - ::mlir::DataLayoutEntryListRef params) const { - assert(!cir::MissingFeatures::recordTypeLayoutInfo()); - return llvm::TypeSize::getFixed(8); +RecordType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + if (isUnion()) { + // TODO(CIR): Implement union layout. + return llvm::TypeSize::getFixed(8); + } + + unsigned recordSize = computeStructSize(dataLayout); + return llvm::TypeSize::getFixed(recordSize * 8); } uint64_t RecordType::getABIAlignment(const ::mlir::DataLayout &dataLayout, ::mlir::DataLayoutEntryListRef params) const { - assert(!cir::MissingFeatures::recordTypeLayoutInfo()); - return 4; + if (isUnion()) { + // TODO(CIR): Implement union layout. + return 8; + } + + // Packed structures always have an ABI alignment of 1. + if (getPacked()) + return 1; + return computeStructAlignment(dataLayout); +} + +unsigned +RecordType::computeStructSize(const mlir::DataLayout &dataLayout) const { + assert(isComplete() && "Cannot get layout of incomplete records"); + + // This is a similar algorithm to LLVM's StructLayout. + unsigned recordSize = 0; + uint64_t recordAlignment = 1; + + // We can't use a range-based for loop here because we might be ignoring the + // last element. + for (mlir::Type ty : getMembers()) { + // This assumes that we're calculating size based on the ABI alignment, not + // the preferred alignment for each type. + const uint64_t tyAlign = + (getPacked() ? 1 : dataLayout.getTypeABIAlignment(ty)); + + // This should be aligned because the padding is inserted when we build + // the record. + assert(llvm::isAligned(llvm::Align(tyAlign), recordSize)); + + // Add padding to the struct size to align it to the abi alignment of the + // element type before than adding the size of the element. + recordSize = llvm::alignTo(recordSize, tyAlign); + recordSize += dataLayout.getTypeSize(ty); + + // The alignment requirement of a struct is equal to the strictest alignment + // requirement of its elements. + recordAlignment = std::max(tyAlign, recordAlignment); + } + + // Add padding to the end of the record so that it could be put in an array + // and all array elements would be aligned correctly. + assert(llvm::isAligned(llvm::Align(recordAlignment), recordSize)); + // if (!llvm::isAligned(recordAlignment, recordSize)) ---------------- andykaylor wrote:
This shouldn't be here. https://github.com/llvm/llvm-project/pull/136036 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits