================
@@ -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

Reply via email to