Skip to content

Commit 3e84d3e

Browse files
committed
[Serialization] Introduce OnDiskHashTable for specializations
Following up for #83108 This follows the suggestion literally from #76774 (comment) which introduces OnDiskHashTable for specializations based on D41416. Note that I didn't polish this patch to reduce the diff from D41416 to it easier to review. I'll make the polishing patch later. So that we can focus what we're doing in this patch and focus on the style in the next patch.
1 parent a06599e commit 3e84d3e

15 files changed

+856
-13
lines changed

clang/include/clang/AST/ExternalASTSource.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,17 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
150150
virtual bool
151151
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
152152

153+
/// Load all the external specializations for the Decl \param D if \param
154+
/// OnlyPartial is false. Otherwise, load all the external **partial**
155+
/// specializations for the \param D.
156+
virtual void LoadExternalSpecializations(const Decl *D, bool OnlyPartial);
157+
158+
/// Load all the specializations for the Decl \param D with the same template
159+
/// args specified by \param TemplateArgs.
160+
virtual void
161+
LoadExternalSpecializations(const Decl *D,
162+
ArrayRef<TemplateArgument> TemplateArgs);
163+
153164
/// Ensures that the table of all visible declarations inside this
154165
/// context is up to date.
155166
///

clang/include/clang/Sema/MultiplexExternalSemaSource.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
9797
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
9898
DeclarationName Name) override;
9999

100+
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
101+
102+
void
103+
LoadExternalSpecializations(const Decl *D,
104+
ArrayRef<TemplateArgument> TemplateArgs) override;
105+
100106
/// Ensures that the table of all visible declarations inside this
101107
/// context is up to date.
102108
void completeVisibleDeclsMap(const DeclContext *DC) override;

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,9 @@ enum ASTRecordTypes {
724724

725725
/// Record code for vtables to emit.
726726
VTABLES_TO_EMIT = 70,
727+
728+
/// Record code for updated specialization
729+
UPDATE_SPECIALIZATION = 71,
727730
};
728731

729732
/// Record types used within a source manager block.
@@ -1487,6 +1490,9 @@ enum DeclCode {
14871490
/// A HLSLBufferDecl record.
14881491
DECL_HLSL_BUFFER,
14891492

1493+
// A decls specilization record.
1494+
DECL_SPECIALIZATIONS,
1495+
14901496
/// An ImplicitConceptSpecializationDecl record.
14911497
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
14921498

clang/include/clang/Serialization/ASTReader.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ class ASTIdentifierLookupTrait;
340340
/// The on-disk hash table(s) used for DeclContext name lookup.
341341
struct DeclContextLookupTable;
342342

343+
/// The on-disk hash table(s) used for specialization decls.
344+
struct LazySpecializationInfoLookupTable;
345+
343346
} // namespace reader
344347

345348
} // namespace serialization
@@ -605,20 +608,29 @@ class ASTReader
605608
llvm::DenseMap<const DeclContext *,
606609
serialization::reader::DeclContextLookupTable> Lookups;
607610

611+
/// Map from decls to specialized decls.
612+
llvm::DenseMap<const Decl *,
613+
serialization::reader::LazySpecializationInfoLookupTable>
614+
SpecializationsLookups;
615+
608616
// Updates for visible decls can occur for other contexts than just the
609617
// TU, and when we read those update records, the actual context may not
610618
// be available yet, so have this pending map using the ID as a key. It
611-
// will be realized when the context is actually loaded.
612-
struct PendingVisibleUpdate {
619+
// will be realized when the data is actually loaded.
620+
struct UpdateData {
613621
ModuleFile *Mod;
614622
const unsigned char *Data;
615623
};
616-
using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
624+
using DeclContextVisibleUpdates = SmallVector<UpdateData, 1>;
617625

618626
/// Updates to the visible declarations of declaration contexts that
619627
/// haven't been loaded yet.
620628
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;
621629

630+
using SpecializationsUpdate = SmallVector<UpdateData, 1>;
631+
llvm::DenseMap<GlobalDeclID, SpecializationsUpdate>
632+
PendingSpecializationsUpdates;
633+
622634
/// The set of C++ or Objective-C classes that have forward
623635
/// declarations that have not yet been linked to their definitions.
624636
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
@@ -645,6 +657,11 @@ class ASTReader
645657
llvm::BitstreamCursor &Cursor,
646658
uint64_t Offset, GlobalDeclID ID);
647659

660+
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
661+
uint64_t Offset, Decl *D);
662+
void AddSpecializations(const Decl *D, const unsigned char *Data,
663+
ModuleFile &M);
664+
648665
/// A vector containing identifiers that have already been
649666
/// loaded.
650667
///
@@ -1344,6 +1361,11 @@ class ASTReader
13441361
const serialization::reader::DeclContextLookupTable *
13451362
getLoadedLookupTables(DeclContext *Primary) const;
13461363

1364+
/// Get the loaded specializations lookup tables for \p D,
1365+
/// if any.
1366+
serialization::reader::LazySpecializationInfoLookupTable *
1367+
getLoadedSpecializationsLookupTables(const Decl *D);
1368+
13471369
private:
13481370
struct ImportedModule {
13491371
ModuleFile *Mod;
@@ -1992,6 +2014,12 @@ class ASTReader
19922014
unsigned BlockID,
19932015
uint64_t *StartOfBlockOffset = nullptr);
19942016

2017+
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
2018+
2019+
void
2020+
LoadExternalSpecializations(const Decl *D,
2021+
ArrayRef<TemplateArgument> TemplateArgs) override;
2022+
19952023
/// Finds all the visible declarations with a given name.
19962024
/// The current implementation of this method just loads the entire
19972025
/// lookup table as unmaterialized references.

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,12 @@ class ASTWriter : public ASTDeserializationListener,
418418
/// Only meaningful for reduced BMI.
419419
DeclUpdateMap DeclUpdatesFromGMF;
420420

421+
/// Mapping from decl templates and its new specialization in the
422+
/// current TU.
423+
using SpecializationUpdateMap =
424+
llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
425+
SpecializationUpdateMap SpecializationsUpdates;
426+
421427
using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
422428

423429
/// Map of first declarations from a chained PCH that point to the
@@ -569,6 +575,12 @@ class ASTWriter : public ASTDeserializationListener,
569575

570576
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
571577

578+
void GenerateSpecializationInfoLookupTable(
579+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
580+
llvm::SmallVectorImpl<char> &LookupTable);
581+
uint64_t WriteSpecializationInfoLookupTable(
582+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations);
583+
572584
void GenerateNameLookupTable(const DeclContext *DC,
573585
llvm::SmallVectorImpl<char> &LookupTable);
574586
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
@@ -584,6 +596,7 @@ class ASTWriter : public ASTDeserializationListener,
584596
void WriteDeclAndTypes(ASTContext &Context);
585597
void PrepareWritingSpecialDecls(Sema &SemaRef);
586598
void WriteSpecialDeclRecords(Sema &SemaRef);
599+
void WriteSpecializationsUpdates();
587600
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
588601
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
589602
void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
@@ -610,6 +623,8 @@ class ASTWriter : public ASTDeserializationListener,
610623
unsigned DeclEnumAbbrev = 0;
611624
unsigned DeclObjCIvarAbbrev = 0;
612625
unsigned DeclCXXMethodAbbrev = 0;
626+
unsigned DeclSpecializationsAbbrev = 0;
627+
613628
unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
614629
unsigned DeclTemplateCXXMethodAbbrev = 0;
615630
unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;

clang/lib/AST/DeclTemplate.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,14 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c
335335

336336
void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
337337
bool OnlyPartial /*=false*/) const {
338+
auto *ExternalSource = getASTContext().getExternalSource();
339+
if (!ExternalSource)
340+
return;
341+
342+
ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
343+
OnlyPartial);
344+
return;
345+
338346
// Grab the most recent declaration to ensure we've loaded any lazy
339347
// redeclarations of this template.
340348
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
@@ -354,6 +362,8 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
354362

355363
Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(
356364
LazySpecializationInfo &LazySpecInfo) const {
365+
llvm_unreachable("We don't use LazySpecializationInfo any more");
366+
357367
GlobalDeclID ID = LazySpecInfo.DeclID;
358368
assert(ID.isValid() && "Loading already loaded specialization!");
359369
// Note that we loaded the specialization.
@@ -364,6 +374,13 @@ Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(
364374

365375
void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
366376
ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
377+
auto *ExternalSource = getASTContext().getExternalSource();
378+
if (!ExternalSource)
379+
return;
380+
381+
ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), Args);
382+
return;
383+
367384
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
368385
if (auto *Specs = CommonBasePtr->LazySpecializations) {
369386
unsigned Hash = TemplateArgumentList::ComputeODRHash(Args);

clang/lib/AST/ExternalASTSource.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
9898
return false;
9999
}
100100

101+
void ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) {}
102+
103+
void ExternalASTSource::LoadExternalSpecializations(
104+
const Decl *D, ArrayRef<TemplateArgument>) {}
105+
101106
void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {}
102107

103108
void ExternalASTSource::FindExternalLexicalDecls(

clang/lib/Sema/MultiplexExternalSemaSource.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
115115
return AnyDeclsFound;
116116
}
117117

118+
void MultiplexExternalSemaSource::LoadExternalSpecializations(
119+
const Decl *D, bool OnlyPartial) {
120+
for (size_t i = 0; i < Sources.size(); ++i)
121+
Sources[i]->LoadExternalSpecializations(D, OnlyPartial);
122+
}
123+
124+
void MultiplexExternalSemaSource::LoadExternalSpecializations(
125+
const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
126+
for (size_t i = 0; i < Sources.size(); ++i)
127+
Sources[i]->LoadExternalSpecializations(D, TemplateArgs);
128+
}
129+
118130
void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
119131
for(size_t i = 0; i < Sources.size(); ++i)
120132
Sources[i]->completeVisibleDeclsMap(DC);

0 commit comments

Comments
 (0)