aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-06-13 18:00:18 +0000
committerAnders Carlsson <andersca@mac.com>2010-06-13 18:00:18 +0000
commite3362bc104f401564a68ef2e0e5fd89f440cf4fc (patch)
tree0832398f9b9862757ed5b804ff2c53509fb9b89a
parent5ccfdd8d215c7bf324a14523c71ed328325c2bc8 (diff)
Do the same short-circuit optimization when laying out bases.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105920 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 6b8d7cf22d..1f04cb80e1 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -81,7 +81,7 @@ class EmptySubobjectMap {
bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
uint64_t Offset);
void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
- uint64_t Offset);
+ uint64_t Offset, bool PlacingEmptyBase);
bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
const CXXRecordDecl *Class,
@@ -256,7 +256,17 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
}
void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
- uint64_t Offset) {
+ uint64_t Offset,
+ bool PlacingEmptyBase) {
+ if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) {
+ // We know that the only empty subobjects that can conflict with empty
+ // subobject of non-empty bases, are empty bases that can be placed at
+ // offset zero. Because of this, we only need to keep track of empty base
+ // subobjects with offsets less than the size of the largest empty
+ // subobject for our class.
+ return;
+ }
+
AddSubobjectAtOffset(Info->Class, Offset);
// Traverse all non-virtual bases.
@@ -267,14 +277,15 @@ void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
continue;
uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
- UpdateEmptyBaseSubobjects(Base, BaseOffset);
+ UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase);
}
if (Info->PrimaryVirtualBaseInfo) {
BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
if (Info == PrimaryVirtualBaseInfo->Derived)
- UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset);
+ UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset,
+ PlacingEmptyBase);
}
// Traverse all member variables.
@@ -300,7 +311,7 @@ bool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info,
// We are able to place the base at this offset. Make sure to update the
// empty base subobject map.
- UpdateEmptyBaseSubobjects(Info, Offset);
+ UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty());
return true;
}
@@ -416,7 +427,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD,
const CXXRecordDecl *Class,
uint64_t Offset) {
// We know that the only empty subobjects that can conflict with empty
- // field subobjects are subobjects empty bases that can be placed at offset
+ // field subobjects are subobjects of empty bases that can be placed at offset
// zero. Because of this, we only need to keep track of empty field
// subobjects with offsets less than the size of the largest empty
// subobject for our class.
@@ -488,7 +499,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD,
for (uint64_t I = 0; I != NumElements; ++I) {
// We know that the only empty subobjects that can conflict with empty
- // field subobjects are subobjects empty bases that can be placed at
+ // field subobjects are subobjects of empty bases that can be placed at
// offset zero. Because of this, we only need to keep track of empty field
// subobjects with offsets less than the size of the largest empty
// subobject for our class.