Skip to content

Commit 53fd6ee

Browse files
ChuanqiXu9yuxuanchen1997
authored andcommitted
[C++20] [Modules] Write ODRHash for decls in GMF
Summary: Previously, we skipped calculating ODRHash for decls in GMF when writing them to .pcm files as an optimization. But actually, it is not true that this will be a pure optimization. Whether or not it is beneficial depends on the use cases. For example, if we're writing a function `a` in module and there are 10 consumers of `a` in other TUs, then the other TUs will pay for the cost to calculate the ODR hash for `a` ten times. Then this optimization doesn't work. However, if all the consumers of the module didn't touch `a`, then we can save the cost to calculate the ODR hash of `a` for 1 times. And the assumption to make it was: generally, the consumers of a module may only consume a small part of the imported module. This is the reason why we tried to load declarations, types and identifiers lazily. Then it looks good to do the similar thing for calculating ODR hashs. It works fine for a long time, until we started to look into the support of modules in clangd. Then we meet multiple issue reports complaining we're calculating ODR hash in the wrong place. To workaround these issue reports, I decided to always write the ODRhash for decls in GMF. In my local test, I only observed less than 1% compile time regression after doing this. So it should be fine. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250933
1 parent 4379e98 commit 53fd6ee

File tree

3 files changed

+14
-42
lines changed

3 files changed

+14
-42
lines changed

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -794,15 +794,12 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
794794
BitsUnpacker EnumDeclBits(Record.readInt());
795795
ED->setNumPositiveBits(EnumDeclBits.getNextBits(/*Width=*/8));
796796
ED->setNumNegativeBits(EnumDeclBits.getNextBits(/*Width=*/8));
797-
bool ShouldSkipCheckingODR = EnumDeclBits.getNextBit();
798797
ED->setScoped(EnumDeclBits.getNextBit());
799798
ED->setScopedUsingClassTag(EnumDeclBits.getNextBit());
800799
ED->setFixed(EnumDeclBits.getNextBit());
801800

802-
if (!ShouldSkipCheckingODR) {
803-
ED->setHasODRHash(true);
804-
ED->ODRHash = Record.readInt();
805-
}
801+
ED->setHasODRHash(true);
802+
ED->ODRHash = Record.readInt();
806803

807804
// If this is a definition subject to the ODR, and we already have a
808805
// definition, merge this one into it.
@@ -864,9 +861,6 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
864861

865862
void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
866863
VisitRecordDeclImpl(RD);
867-
// We should only reach here if we're in C/Objective-C. There is no
868-
// global module fragment.
869-
assert(!shouldSkipCheckingODR(RD));
870864
RD->setODRHash(Record.readInt());
871865

872866
// Maintain the invariant of a redeclaration chain containing only
@@ -1066,7 +1060,6 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
10661060

10671061
FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3));
10681062
FD->setStorageClass((StorageClass)FunctionDeclBits.getNextBits(/*Width=*/3));
1069-
bool ShouldSkipCheckingODR = FunctionDeclBits.getNextBit();
10701063
FD->setInlineSpecified(FunctionDeclBits.getNextBit());
10711064
FD->setImplicitlyInline(FunctionDeclBits.getNextBit());
10721065
FD->setHasSkippedBody(FunctionDeclBits.getNextBit());
@@ -1096,10 +1089,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
10961089
if (FD->isExplicitlyDefaulted())
10971090
FD->setDefaultLoc(readSourceLocation());
10981091

1099-
if (!ShouldSkipCheckingODR) {
1100-
FD->ODRHash = Record.readInt();
1101-
FD->setHasODRHash(true);
1102-
}
1092+
FD->ODRHash = Record.readInt();
1093+
FD->setHasODRHash(true);
11031094

11041095
if (FD->isDefaulted() || FD->isDeletedAsWritten()) {
11051096
// If 'Info' is nonzero, we need to read an DefaultedOrDeletedInfo; if,
@@ -1971,8 +1962,6 @@ void ASTDeclReader::ReadCXXDefinitionData(
19711962

19721963
BitsUnpacker CXXRecordDeclBits = Record.readInt();
19731964

1974-
bool ShouldSkipCheckingODR = CXXRecordDeclBits.getNextBit();
1975-
19761965
#define FIELD(Name, Width, Merge) \
19771966
if (!CXXRecordDeclBits.canGetNextNBits(Width)) \
19781967
CXXRecordDeclBits.updateValue(Record.readInt()); \
@@ -1981,12 +1970,9 @@ void ASTDeclReader::ReadCXXDefinitionData(
19811970
#include "clang/AST/CXXRecordDeclDefinitionBits.def"
19821971
#undef FIELD
19831972

1984-
// We only perform ODR checks for decls not in GMF.
1985-
if (!ShouldSkipCheckingODR) {
1986-
// Note: the caller has deserialized the IsLambda bit already.
1987-
Data.ODRHash = Record.readInt();
1988-
Data.HasODRHash = true;
1989-
}
1973+
// Note: the caller has deserialized the IsLambda bit already.
1974+
Data.ODRHash = Record.readInt();
1975+
Data.HasODRHash = true;
19901976

19911977
if (Record.readInt()) {
19921978
Reader.DefinitionSource[D] =

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6543,9 +6543,6 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
65436543

65446544
BitsPacker DefinitionBits;
65456545

6546-
bool ShouldSkipCheckingODR = shouldSkipCheckingODR(D);
6547-
DefinitionBits.addBit(ShouldSkipCheckingODR);
6548-
65496546
#define FIELD(Name, Width, Merge) \
65506547
if (!DefinitionBits.canWriteNextNBits(Width)) { \
65516548
Record->push_back(DefinitionBits); \
@@ -6558,11 +6555,9 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
65586555

65596556
Record->push_back(DefinitionBits);
65606557

6561-
// We only perform ODR checks for decls not in GMF.
6562-
if (!ShouldSkipCheckingODR)
6563-
// getODRHash will compute the ODRHash if it has not been previously
6564-
// computed.
6565-
Record->push_back(D->getODRHash());
6558+
// getODRHash will compute the ODRHash if it has not been previously
6559+
// computed.
6560+
Record->push_back(D->getODRHash());
65666561

65676562
bool ModulesDebugInfo =
65686563
Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType();

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -527,16 +527,12 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
527527
BitsPacker EnumDeclBits;
528528
EnumDeclBits.addBits(D->getNumPositiveBits(), /*BitWidth=*/8);
529529
EnumDeclBits.addBits(D->getNumNegativeBits(), /*BitWidth=*/8);
530-
bool ShouldSkipCheckingODR = shouldSkipCheckingODR(D);
531-
EnumDeclBits.addBit(ShouldSkipCheckingODR);
532530
EnumDeclBits.addBit(D->isScoped());
533531
EnumDeclBits.addBit(D->isScopedUsingClassTag());
534532
EnumDeclBits.addBit(D->isFixed());
535533
Record.push_back(EnumDeclBits);
536534

537-
// We only perform ODR checks for decls not in GMF.
538-
if (!ShouldSkipCheckingODR)
539-
Record.push_back(D->getODRHash());
535+
Record.push_back(D->getODRHash());
540536

541537
if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
542538
Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
@@ -553,7 +549,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
553549
!D->isTopLevelDeclInObjCContainer() &&
554550
!CXXRecordDecl::classofKind(D->getKind()) &&
555551
!D->getIntegerTypeSourceInfo() && !D->getMemberSpecializationInfo() &&
556-
!needsAnonymousDeclarationNumber(D) && !shouldSkipCheckingODR(D) &&
552+
!needsAnonymousDeclarationNumber(D) &&
557553
D->getDeclName().getNameKind() == DeclarationName::Identifier)
558554
AbbrevToUse = Writer.getDeclEnumAbbrev();
559555

@@ -719,8 +715,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
719715
// FIXME: stable encoding
720716
FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3);
721717
FunctionDeclBits.addBits((uint32_t)D->getStorageClass(), /*BitWidth=*/3);
722-
bool ShouldSkipCheckingODR = shouldSkipCheckingODR(D);
723-
FunctionDeclBits.addBit(ShouldSkipCheckingODR);
724718
FunctionDeclBits.addBit(D->isInlineSpecified());
725719
FunctionDeclBits.addBit(D->isInlined());
726720
FunctionDeclBits.addBit(D->hasSkippedBody());
@@ -746,9 +740,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
746740
if (D->isExplicitlyDefaulted())
747741
Record.AddSourceLocation(D->getDefaultLoc());
748742

749-
// We only perform ODR checks for decls not in GMF.
750-
if (!ShouldSkipCheckingODR)
751-
Record.push_back(D->getODRHash());
743+
Record.push_back(D->getODRHash());
752744

753745
if (D->isDefaulted() || D->isDeletedAsWritten()) {
754746
if (auto *FDI = D->getDefalutedOrDeletedInfo()) {
@@ -1560,8 +1552,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
15601552
D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
15611553
!D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
15621554
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
1563-
!shouldSkipCheckingODR(D) && !D->hasExtInfo() &&
1564-
!D->isExplicitlyDefaulted()) {
1555+
!D->hasExtInfo() && !D->isExplicitlyDefaulted()) {
15651556
if (D->getTemplatedKind() == FunctionDecl::TK_NonTemplate ||
15661557
D->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate ||
15671558
D->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||

0 commit comments

Comments
 (0)