Skip to content

Commit 2bf5a6c

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 45ed7aa commit 2bf5a6c

15 files changed

+859
-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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ enum ASTRecordTypes {
721721

722722
/// Record code for \#pragma clang unsafe_buffer_usage begin/end
723723
PP_UNSAFE_BUFFER_USAGE = 69,
724+
725+
/// Record code for vtables to emit.
726+
VTABLES_TO_EMIT = 70,
727+
728+
/// Record code for updated specialization
729+
UPDATE_SPECIALIZATION = 71,
724730
};
725731

726732
/// Record types used within a source manager block.
@@ -1484,6 +1490,9 @@ enum DeclCode {
14841490
/// A HLSLBufferDecl record.
14851491
DECL_HLSL_BUFFER,
14861492

1493+
// A decls specilization record.
1494+
DECL_SPECIALIZATIONS,
1495+
14871496
/// An ImplicitConceptSpecializationDecl record.
14881497
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
14891498

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
///
@@ -1339,6 +1356,11 @@ class ASTReader
13391356
const serialization::reader::DeclContextLookupTable *
13401357
getLoadedLookupTables(DeclContext *Primary) const;
13411358

1359+
/// Get the loaded specializations lookup tables for \p D,
1360+
/// if any.
1361+
serialization::reader::LazySpecializationInfoLookupTable *
1362+
getLoadedSpecializationsLookupTables(const Decl *D);
1363+
13421364
private:
13431365
struct ImportedModule {
13441366
ModuleFile *Mod;
@@ -1986,6 +2008,12 @@ class ASTReader
19862008
unsigned BlockID,
19872009
uint64_t *StartOfBlockOffset = nullptr);
19882010

2011+
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
2012+
2013+
void
2014+
LoadExternalSpecializations(const Decl *D,
2015+
ArrayRef<TemplateArgument> TemplateArgs) override;
2016+
19892017
/// Finds all the visible declarations with a given name.
19902018
/// The current implementation of this method just loads the entire
19912019
/// 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
@@ -565,6 +571,12 @@ class ASTWriter : public ASTDeserializationListener,
565571

566572
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
567573

574+
void GenerateSpecializationInfoLookupTable(
575+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
576+
llvm::SmallVectorImpl<char> &LookupTable);
577+
uint64_t WriteSpecializationInfoLookupTable(
578+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations);
579+
568580
void GenerateNameLookupTable(const DeclContext *DC,
569581
llvm::SmallVectorImpl<char> &LookupTable);
570582
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
@@ -580,6 +592,7 @@ class ASTWriter : public ASTDeserializationListener,
580592
void WriteDeclAndTypes(ASTContext &Context);
581593
void PrepareWritingSpecialDecls(Sema &SemaRef);
582594
void WriteSpecialDeclRecords(Sema &SemaRef);
595+
void WriteSpecializationsUpdates();
583596
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
584597
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
585598
void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
@@ -606,6 +619,8 @@ class ASTWriter : public ASTDeserializationListener,
606619
unsigned DeclEnumAbbrev = 0;
607620
unsigned DeclObjCIvarAbbrev = 0;
608621
unsigned DeclCXXMethodAbbrev = 0;
622+
unsigned DeclSpecializationsAbbrev = 0;
623+
609624
unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
610625
unsigned DeclTemplateCXXMethodAbbrev = 0;
611626
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)