-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[Clang] Reduce the size of Decl and classes derived from it #87361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Good catch on this really nice space-saving change!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! I'd love it to be a little simplified (see suggestions), but am glad this could be done!
@@ -268,17 +268,34 @@ class alignas(8) Decl { | |||
/// } | |||
/// void A::f(); // SemanticDC == namespace 'A' | |||
/// // LexicalDC == global namespace | |||
llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; | |||
llvm::PointerIntPair< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find myself wondering a touch whether the two PointerIntPair
vs an enum-bitmask-thing of two bits is worth the extra complexity here.
Also, a comment above it explaining what this is doing would be REALLY helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IDK. I'm personally not a huge fan of manual bit twiddling, since it's way to easy to get things wrong. I much rather let the compiler do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it ends up being 'manual bit twiddling' so much as 3 values in an enum, and I also found the getPointer().getPointer()
pretty mind-bending, but at least it is somewhat well hidden in stuff we won't touch for a while, so I won't insist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for more comments. I spent more time to understand the structure here. Also maybe we can make the code self explained by:
llvm::PointerIntPair< | |
using DeclCtxTy = llvm::PointerUnion<DeclContext*, MultipleDC*>; | |
using DeclCtxAndHasAttrTy = llvm::PointerIntPair<llvm::PointerUnion<DeclContext *, MultipleDC *>, 1, | |
bool>; | |
using DeclCtxAndHasAttrTyOrInvalidDeclTy = ... |
@llvm/pr-subscribers-clang Author: Nikolas Klauser (philnik777) Changes
When parsing libc++'s Full diff: https://github.com/llvm/llvm-project/pull/87361.diff 3 Files Affected:
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 47ed6d0d1db0df..9a3f8c41de387e 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -268,17 +268,37 @@ class alignas(8) Decl {
/// }
/// void A::f(); // SemanticDC == namespace 'A'
/// // LexicalDC == global namespace
- llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
- bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
- bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
+ // Compress the InvalidDecl and HasAttrs bits into DeclCtx to keep Decl below
+ // 32 bytes in size
+ llvm::PointerIntPair<
+ llvm::PointerIntPair<llvm::PointerUnion<DeclContext *, MultipleDC *>, 1,
+ bool>,
+ 1, bool>
+ DeclCtxWithInvalidDeclAndHasAttrs;
+
+ bool isInSemaDC() const {
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .is<DeclContext *>();
+ }
+
+ bool isOutOfSemaDC() const {
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .is<MultipleDC *>();
+ }
MultipleDC *getMultipleDC() const {
- return DeclCtx.get<MultipleDC*>();
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .get<MultipleDC *>();
}
DeclContext *getSemanticDC() const {
- return DeclCtx.get<DeclContext*>();
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .get<DeclContext *>();
}
/// Loc - The location of this decl.
@@ -288,14 +308,6 @@ class alignas(8) Decl {
LLVM_PREFERRED_TYPE(Kind)
unsigned DeclKind : 7;
- /// InvalidDecl - This indicates a semantic error occurred.
- LLVM_PREFERRED_TYPE(bool)
- unsigned InvalidDecl : 1;
-
- /// HasAttrs - This indicates whether the decl has attributes or not.
- LLVM_PREFERRED_TYPE(bool)
- unsigned HasAttrs : 1;
-
/// Implicit - Whether this declaration was implicitly generated by
/// the implementation rather than explicitly written by the user.
LLVM_PREFERRED_TYPE(bool)
@@ -393,21 +405,22 @@ class alignas(8) Decl {
protected:
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)),
- DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false),
- Implicit(false), Used(false), Referenced(false),
+ DeclCtxWithInvalidDeclAndHasAttrs({DC, false}, false), Loc(L),
+ DeclKind(DK), Implicit(false), Used(false), Referenced(false),
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
- if (StatisticsEnabled) add(DK);
+ if (StatisticsEnabled)
+ add(DK);
}
Decl(Kind DK, EmptyShell Empty)
- : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false),
- Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
- Access(AS_none), FromASTFile(0),
+ : DeclKind(DK), Implicit(false), Used(false), Referenced(false),
+ TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
- if (StatisticsEnabled) add(DK);
+ if (StatisticsEnabled)
+ add(DK);
}
virtual ~Decl();
@@ -520,7 +533,7 @@ class alignas(8) Decl {
return AccessSpecifier(Access);
}
- bool hasAttrs() const { return HasAttrs; }
+ bool hasAttrs() const { return DeclCtxWithInvalidDeclAndHasAttrs.getPointer().getInt(); }
void setAttrs(const AttrVec& Attrs) {
return setAttrsImpl(Attrs, getASTContext());
@@ -549,13 +562,16 @@ class alignas(8) Decl {
}
template <typename... Ts> void dropAttrs() {
- if (!HasAttrs) return;
+ if (!hasAttrs()) return;
AttrVec &Vec = getAttrs();
llvm::erase_if(Vec, [](Attr *A) { return isa<Ts...>(A); });
- if (Vec.empty())
- HasAttrs = false;
+ if (Vec.empty()) {
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setInt(false);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
+ }
}
template <typename T> void dropAttr() { dropAttrs<T>(); }
@@ -590,7 +606,10 @@ class alignas(8) Decl {
/// setInvalidDecl - Indicates the Decl had a semantic error. This
/// allows for graceful error recovery.
void setInvalidDecl(bool Invalid = true);
- bool isInvalidDecl() const { return (bool) InvalidDecl; }
+
+ bool isInvalidDecl() const {
+ return DeclCtxWithInvalidDeclAndHasAttrs.getInt();
+ }
/// isImplicit - Indicates whether the declaration was implicitly
/// generated by the implementation. If false, this declaration
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 04bbc49ab2f319..c06b41d6b29f89 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -52,6 +52,8 @@
using namespace clang;
+static_assert(sizeof(Decl) <= 32, "Decl grew beyond 32 bytes!");
+
//===----------------------------------------------------------------------===//
// Statistics
//===----------------------------------------------------------------------===//
@@ -130,7 +132,7 @@ const char *Decl::getDeclKindName() const {
}
void Decl::setInvalidDecl(bool Invalid) {
- InvalidDecl = Invalid;
+ DeclCtxWithInvalidDeclAndHasAttrs.setInt(Invalid);
assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
if (!Invalid) {
return;
@@ -334,7 +336,9 @@ void PrettyStackTraceDecl::print(raw_ostream &OS) const {
Decl::~Decl() = default;
void Decl::setDeclContext(DeclContext *DC) {
- DeclCtx = DC;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setPointer(DC);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
}
void Decl::setLexicalDeclContext(DeclContext *DC) {
@@ -364,12 +368,16 @@ void Decl::setLexicalDeclContext(DeclContext *DC) {
void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
ASTContext &Ctx) {
if (SemaDC == LexicalDC) {
- DeclCtx = SemaDC;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setPointer(SemaDC);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
} else {
auto *MDC = new (Ctx) Decl::MultipleDC();
MDC->SemanticDC = SemaDC;
MDC->LexicalDC = LexicalDC;
- DeclCtx = MDC;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setPointer(MDC);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
}
}
@@ -956,19 +964,24 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
}
void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
- assert(!HasAttrs && "Decl already contains attrs.");
+ assert(!hasAttrs() && "Decl already contains attrs.");
AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
assert(AttrBlank.empty() && "HasAttrs was wrong?");
AttrBlank = attrs;
- HasAttrs = true;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setInt(true);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
}
void Decl::dropAttrs() {
- if (!HasAttrs) return;
+ if (!hasAttrs())
+ return;
- HasAttrs = false;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setInt(false);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
getASTContext().eraseDeclAttrs(this);
}
@@ -996,7 +1009,7 @@ void Decl::addAttr(Attr *A) {
}
const AttrVec &Decl::getAttrs() const {
- assert(HasAttrs && "No attrs to get!");
+ assert(hasAttrs() && "No attrs to get!");
return getASTContext().getDeclAttrs(this);
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index a22f760408c634..2e186109327fb2 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -594,7 +594,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {
bool HasStandaloneLexicalDC = DeclBits.getNextBit();
bool HasAttrs = DeclBits.getNextBit();
D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit());
- D->InvalidDecl = DeclBits.getNextBit();
+ D->DeclCtxWithInvalidDeclAndHasAttrs.setInt(DeclBits.getNextBit());
D->FromASTFile = true;
if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
|
@llvm/pr-subscribers-clang-modules Author: Nikolas Klauser (philnik777) Changes
When parsing libc++'s Full diff: https://github.com/llvm/llvm-project/pull/87361.diff 3 Files Affected:
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 47ed6d0d1db0df..9a3f8c41de387e 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -268,17 +268,37 @@ class alignas(8) Decl {
/// }
/// void A::f(); // SemanticDC == namespace 'A'
/// // LexicalDC == global namespace
- llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
- bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
- bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
+ // Compress the InvalidDecl and HasAttrs bits into DeclCtx to keep Decl below
+ // 32 bytes in size
+ llvm::PointerIntPair<
+ llvm::PointerIntPair<llvm::PointerUnion<DeclContext *, MultipleDC *>, 1,
+ bool>,
+ 1, bool>
+ DeclCtxWithInvalidDeclAndHasAttrs;
+
+ bool isInSemaDC() const {
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .is<DeclContext *>();
+ }
+
+ bool isOutOfSemaDC() const {
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .is<MultipleDC *>();
+ }
MultipleDC *getMultipleDC() const {
- return DeclCtx.get<MultipleDC*>();
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .get<MultipleDC *>();
}
DeclContext *getSemanticDC() const {
- return DeclCtx.get<DeclContext*>();
+ return DeclCtxWithInvalidDeclAndHasAttrs.getPointer()
+ .getPointer()
+ .get<DeclContext *>();
}
/// Loc - The location of this decl.
@@ -288,14 +308,6 @@ class alignas(8) Decl {
LLVM_PREFERRED_TYPE(Kind)
unsigned DeclKind : 7;
- /// InvalidDecl - This indicates a semantic error occurred.
- LLVM_PREFERRED_TYPE(bool)
- unsigned InvalidDecl : 1;
-
- /// HasAttrs - This indicates whether the decl has attributes or not.
- LLVM_PREFERRED_TYPE(bool)
- unsigned HasAttrs : 1;
-
/// Implicit - Whether this declaration was implicitly generated by
/// the implementation rather than explicitly written by the user.
LLVM_PREFERRED_TYPE(bool)
@@ -393,21 +405,22 @@ class alignas(8) Decl {
protected:
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)),
- DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false),
- Implicit(false), Used(false), Referenced(false),
+ DeclCtxWithInvalidDeclAndHasAttrs({DC, false}, false), Loc(L),
+ DeclKind(DK), Implicit(false), Used(false), Referenced(false),
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
- if (StatisticsEnabled) add(DK);
+ if (StatisticsEnabled)
+ add(DK);
}
Decl(Kind DK, EmptyShell Empty)
- : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false),
- Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
- Access(AS_none), FromASTFile(0),
+ : DeclKind(DK), Implicit(false), Used(false), Referenced(false),
+ TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
- if (StatisticsEnabled) add(DK);
+ if (StatisticsEnabled)
+ add(DK);
}
virtual ~Decl();
@@ -520,7 +533,7 @@ class alignas(8) Decl {
return AccessSpecifier(Access);
}
- bool hasAttrs() const { return HasAttrs; }
+ bool hasAttrs() const { return DeclCtxWithInvalidDeclAndHasAttrs.getPointer().getInt(); }
void setAttrs(const AttrVec& Attrs) {
return setAttrsImpl(Attrs, getASTContext());
@@ -549,13 +562,16 @@ class alignas(8) Decl {
}
template <typename... Ts> void dropAttrs() {
- if (!HasAttrs) return;
+ if (!hasAttrs()) return;
AttrVec &Vec = getAttrs();
llvm::erase_if(Vec, [](Attr *A) { return isa<Ts...>(A); });
- if (Vec.empty())
- HasAttrs = false;
+ if (Vec.empty()) {
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setInt(false);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
+ }
}
template <typename T> void dropAttr() { dropAttrs<T>(); }
@@ -590,7 +606,10 @@ class alignas(8) Decl {
/// setInvalidDecl - Indicates the Decl had a semantic error. This
/// allows for graceful error recovery.
void setInvalidDecl(bool Invalid = true);
- bool isInvalidDecl() const { return (bool) InvalidDecl; }
+
+ bool isInvalidDecl() const {
+ return DeclCtxWithInvalidDeclAndHasAttrs.getInt();
+ }
/// isImplicit - Indicates whether the declaration was implicitly
/// generated by the implementation. If false, this declaration
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 04bbc49ab2f319..c06b41d6b29f89 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -52,6 +52,8 @@
using namespace clang;
+static_assert(sizeof(Decl) <= 32, "Decl grew beyond 32 bytes!");
+
//===----------------------------------------------------------------------===//
// Statistics
//===----------------------------------------------------------------------===//
@@ -130,7 +132,7 @@ const char *Decl::getDeclKindName() const {
}
void Decl::setInvalidDecl(bool Invalid) {
- InvalidDecl = Invalid;
+ DeclCtxWithInvalidDeclAndHasAttrs.setInt(Invalid);
assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
if (!Invalid) {
return;
@@ -334,7 +336,9 @@ void PrettyStackTraceDecl::print(raw_ostream &OS) const {
Decl::~Decl() = default;
void Decl::setDeclContext(DeclContext *DC) {
- DeclCtx = DC;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setPointer(DC);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
}
void Decl::setLexicalDeclContext(DeclContext *DC) {
@@ -364,12 +368,16 @@ void Decl::setLexicalDeclContext(DeclContext *DC) {
void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
ASTContext &Ctx) {
if (SemaDC == LexicalDC) {
- DeclCtx = SemaDC;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setPointer(SemaDC);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
} else {
auto *MDC = new (Ctx) Decl::MultipleDC();
MDC->SemanticDC = SemaDC;
MDC->LexicalDC = LexicalDC;
- DeclCtx = MDC;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setPointer(MDC);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
}
}
@@ -956,19 +964,24 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
}
void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
- assert(!HasAttrs && "Decl already contains attrs.");
+ assert(!hasAttrs() && "Decl already contains attrs.");
AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
assert(AttrBlank.empty() && "HasAttrs was wrong?");
AttrBlank = attrs;
- HasAttrs = true;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setInt(true);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
}
void Decl::dropAttrs() {
- if (!HasAttrs) return;
+ if (!hasAttrs())
+ return;
- HasAttrs = false;
+ auto InnerPtr = DeclCtxWithInvalidDeclAndHasAttrs.getPointer();
+ InnerPtr.setInt(false);
+ DeclCtxWithInvalidDeclAndHasAttrs.setPointer(InnerPtr);
getASTContext().eraseDeclAttrs(this);
}
@@ -996,7 +1009,7 @@ void Decl::addAttr(Attr *A) {
}
const AttrVec &Decl::getAttrs() const {
- assert(HasAttrs && "No attrs to get!");
+ assert(hasAttrs() && "No attrs to get!");
return getASTContext().getDeclAttrs(this);
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index a22f760408c634..2e186109327fb2 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -594,7 +594,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {
bool HasStandaloneLexicalDC = DeclBits.getNextBit();
bool HasAttrs = DeclBits.getNextBit();
D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit());
- D->InvalidDecl = DeclBits.getNextBit();
+ D->DeclCtxWithInvalidDeclAndHasAttrs.setInt(DeclBits.getNextBit());
D->FromASTFile = true;
if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
|
@@ -268,17 +268,34 @@ class alignas(8) Decl { | |||
/// } | |||
/// void A::f(); // SemanticDC == namespace 'A' | |||
/// // LexicalDC == global namespace | |||
llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; | |||
llvm::PointerIntPair< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it ends up being 'manual bit twiddling' so much as 3 values in an enum, and I also found the getPointer().getPointer()
pretty mind-bending, but at least it is somewhat well hidden in stuff we won't touch for a while, so I won't insist.
Class | Old size (in bytes) | New size (in bytes) ----------------------------------|---------------------|-------------------- Decl | 40 | 32 AccessSpecDecl | 40 | 40 BlockDecl | 128 | 120 CapturedDecl | 88 | 80 EmptyDecl | 40 | 32 ExportDecl | 80 | 72 ExternCContextDecl | 72 | 64 FileScopeAsmDecl | 56 | 48 FriendDecl | 64 | 56 FriendTemplateDecl | 64 | 64 ImplicitConceptSpecializationDecl | 40 | 40 ImportDecl | 56 | 48 LifetimeExtendedTemporaryDecl | 72 | 64 LinkageSpecDecl | 80 | 72 NamedDecl | 48 | 40 ObjCPropertyImplDecl | 96 | 88 PragmaCommentDecl | 40 | 40 PragmaDetectMismatchDecl | 48 | 40 RequiresExprBodyDecl | 72 | 64 StaticAssertDecl | 64 | 56 TopLevelStmtDecl | 88 | 80 TranslationUnitDecl | 104 | 96 BaseUsingDecl | 56 | 48 UsingDecl | 88 | 80 UsingEnumDecl | 72 | 64 HLSLBufferDecl | 96 | 88 LabelDecl | 80 | 72 NamespaceAliasDecl | 96 | 88 NamespaceDecl | 112 | 104 ObjCCompatibleAliasDecl | 56 | 48 ObjCContainerDecl | 88 | 80 ObjCMethodDecl | 136 | 128 ObjCPropertyDecl | 128 | 120 TemplateDecl | 64 | 56 BuiltinTemplateDecl | 72 | 64 TypeDecl | 64 | 56 UnresolvedUsingIfExistsDecl | 48 | 40 UsingDirectiveDecl | 88 | 80 UsingPackDecl | 64 | 56 UsingShadowDecl | 80 | 72 ValueDecl | 56 | 48 When parsing libc++'s `<string>` header the used memory is reduced from 42.8MB to 42.5MB.
…lvm#88654) Reverts llvm#87361 On 32 bit platforms there is only a single bit available in the `DeclCtx`, resulting in an assertion failure.
When parsing libc++'s
<string>
header the used memory is reduced from 42.8MB to 42.5MB.