================
@@ -851,72 +850,61 @@ void CIRRecordLowering::lowerUnion(bool
nonVirtualBaseType) {
fieldType = getStorageType(field);
}
- // This maps a field to its index. For unions, the index is always 0.
fieldIdxMap[field->getCanonicalDecl()] = 0;
+ fieldTypes.push_back(fieldType);
+ }
- // Compute zero-initializable status.
- // This union might not be zero initialized: it may contain a pointer to
- // data member which might have some exotic initialization sequence.
- // If this is the case, then we ought not to try and come up with a
"better"
- // type, it might not be very easy to come up with a Constant which
- // correctly initializes it.
- if (!seenNamedMember) {
- seenNamedMember = field->getIdentifier();
- if (!seenNamedMember)
- if (const RecordDecl *fieldRD = field->getType()->getAsRecordDecl())
- seenNamedMember = fieldRD->findFirstNamedDataMember();
- if (seenNamedMember && !isZeroInitializable(field)) {
- zeroInitializable = zeroInitializableAsBase = false;
- storageType = fieldType;
- }
- }
+ // Compute zero-initializable status.
+ // This union might not be zero initialized: it may contain a pointer to
+ // data member which might have some exotic initialization sequence.
+ // Unlike classic codegen, we don't really 'give up' on adding all the
fields,
+ // though this is a decision/implementation we might want to revisit. We
just
+ // fall back on the typical storage type calculation rather than this bizarre
+ // "choose the first thing", as that likely won't be compatible with later
+ // decisions.
+ for (const FieldDecl *field : recordDecl->fields()) {
- // Because our union isn't zero initializable, we won't be getting a better
- // storage type.
- if (!zeroInitializable)
- continue;
+ auto hasNamedMember = [](const FieldDecl *curField) -> bool {
+ const auto *rd = curField->getType()->getAsRecordDecl();
+ return rd && rd->findFirstNamedDataMember();
+ };
- // Conditionally update our storage type if we've got a new "better" one.
- if (!storageType || getAlignment(fieldType) > getAlignment(storageType) ||
- (getAlignment(fieldType) == getAlignment(storageType) &&
- getSize(fieldType) > getSize(storageType)))
- storageType = fieldType;
-
- // NOTE(cir): Track all union member's types, not just the largest one. It
- // allows for proper type-checking and retain more info for analisys.
- //
- // The base-subobject type instead uses a single (possibly clipped) storage
- // type, mirroring classic CodeGen, so that it exposes the union's reusable
- // tail padding.
- if (!nonVirtualBaseType)
- fieldTypes.push_back(fieldType);
+ if ((field->getIdentifier() || hasNamedMember(field)) &&
+ !isZeroInitializable(field)) {
+ zeroInitializable = zeroInitializableAsBase = false;
+ }
}
- if (!storageType) {
+ // If we have no candidates for storage, we are JUST padding.
+ if (fieldTypes.empty()) {
appendPaddingBytes(layoutSize);
return;
}
+ mlir::Type storageType =
+ cir::UnionType::getUnionStorageType(dataLayout.layout, fieldTypes);
+
+ // If our storage size was bigger than our required size (can happen in the
+ // case of packed bitfields on Itanium) then just use an I8 array.
if (layoutSize < getSize(storageType))
storageType = getByteArrayType(layoutSize);
+ // The base-subobject record is built as a struct from fieldTypes, so add
+ // the storage type and any trailing padding as ordinary fields rather than
+ // routing padding through the union's single tail-padding slot.
if (nonVirtualBaseType) {
- // The base-subobject record is built as a struct from fieldTypes, so add
- // the storage type and any trailing padding as ordinary fields rather than
- // routing padding through the union's single tail-padding slot.
+ fieldTypes.clear();
----------------
andykaylor wrote:
I don't know what the case was where you needed all the field types in the
normal case, so I'm not sure how to try to apply it to reasoning about this
case, but it seems like we'd want all the fields for the same reason.
https://github.com/llvm/llvm-project/pull/210709
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits