Skip to content

Commit 80c9ab1

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 672fde1 commit 80c9ab1

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
@@ -694,6 +694,9 @@ enum ASTRecordTypes {
694694
/// Record code for lexical and visible block for delayed namespace in
695695
/// reduced BMI.
696696
DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD = 68,
697+
698+
/// Record code for updated specialization
699+
UPDATE_SPECIALIZATION = 69,
697700
};
698701

699702
/// Record types used within a source manager block.
@@ -1451,6 +1454,9 @@ enum DeclCode {
14511454
/// A HLSLBufferDecl record.
14521455
DECL_HLSL_BUFFER,
14531456

1457+
// A decls specilization record.
1458+
DECL_SPECIALIZATIONS,
1459+
14541460
/// An ImplicitConceptSpecializationDecl record.
14551461
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
14561462

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
@@ -618,20 +621,29 @@ class ASTReader
618621
llvm::DenseMap<const DeclContext *,
619622
serialization::reader::DeclContextLookupTable> Lookups;
620623

624+
/// Map from decls to specialized decls.
625+
llvm::DenseMap<const Decl *,
626+
serialization::reader::LazySpecializationInfoLookupTable>
627+
SpecializationsLookups;
628+
621629
// Updates for visible decls can occur for other contexts than just the
622630
// TU, and when we read those update records, the actual context may not
623631
// be available yet, so have this pending map using the ID as a key. It
624-
// will be realized when the context is actually loaded.
625-
struct PendingVisibleUpdate {
632+
// will be realized when the data is actually loaded.
633+
struct UpdateData {
626634
ModuleFile *Mod;
627635
const unsigned char *Data;
628636
};
629-
using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
637+
using DeclContextVisibleUpdates = SmallVector<UpdateData, 1>;
630638

631639
/// Updates to the visible declarations of declaration contexts that
632640
/// haven't been loaded yet.
633641
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;
634642

643+
using SpecializationsUpdate = SmallVector<UpdateData, 1>;
644+
llvm::DenseMap<GlobalDeclID, SpecializationsUpdate>
645+
PendingSpecializationsUpdates;
646+
635647
/// The set of C++ or Objective-C classes that have forward
636648
/// declarations that have not yet been linked to their definitions.
637649
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
@@ -658,6 +670,11 @@ class ASTReader
658670
llvm::BitstreamCursor &Cursor,
659671
uint64_t Offset, GlobalDeclID ID);
660672

673+
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
674+
uint64_t Offset, Decl *D);
675+
void AddSpecializations(const Decl *D, const unsigned char *Data,
676+
ModuleFile &M);
677+
661678
/// A vector containing identifiers that have already been
662679
/// loaded.
663680
///
@@ -1360,6 +1377,11 @@ class ASTReader
13601377
const serialization::reader::DeclContextLookupTable *
13611378
getLoadedLookupTables(DeclContext *Primary) const;
13621379

1380+
/// Get the loaded specializations lookup tables for \p D,
1381+
/// if any.
1382+
serialization::reader::LazySpecializationInfoLookupTable *
1383+
getLoadedSpecializationsLookupTables(const Decl *D);
1384+
13631385
private:
13641386
struct ImportedModule {
13651387
ModuleFile *Mod;
@@ -1989,6 +2011,12 @@ class ASTReader
19892011
unsigned BlockID,
19902012
uint64_t *StartOfBlockOffset = nullptr);
19912013

2014+
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
2015+
2016+
void
2017+
LoadExternalSpecializations(const Decl *D,
2018+
ArrayRef<TemplateArgument> TemplateArgs) override;
2019+
19922020
/// Finds all the visible declarations with a given name.
19932021
/// The current implementation of this method just loads the entire
19942022
/// 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
@@ -403,6 +403,12 @@ class ASTWriter : public ASTDeserializationListener,
403403
/// Only meaningful for reduced BMI.
404404
DeclUpdateMap DeclUpdatesFromGMF;
405405

406+
/// Mapping from decl templates and its new specialization in the
407+
/// current TU.
408+
using SpecializationUpdateMap =
409+
llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
410+
SpecializationUpdateMap SpecializationsUpdates;
411+
406412
using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
407413

408414
/// Map of first declarations from a chained PCH that point to the
@@ -546,6 +552,12 @@ class ASTWriter : public ASTDeserializationListener,
546552
bool isLookupResultEntirelyExternalOrUnreachable(StoredDeclsList &Result,
547553
DeclContext *DC);
548554

555+
void GenerateSpecializationInfoLookupTable(
556+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
557+
llvm::SmallVectorImpl<char> &LookupTable);
558+
uint64_t WriteSpecializationInfoLookupTable(
559+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations);
560+
549561
void GenerateNameLookupTable(const DeclContext *DC,
550562
llvm::SmallVectorImpl<char> &LookupTable);
551563
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
@@ -560,6 +572,7 @@ class ASTWriter : public ASTDeserializationListener,
560572
void WriteDeclAndTypes(ASTContext &Context);
561573
void PrepareWritingSpecialDecls(Sema &SemaRef);
562574
void WriteSpecialDeclRecords(Sema &SemaRef);
575+
void WriteSpecializationsUpdates();
563576
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
564577
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
565578
void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
@@ -586,6 +599,8 @@ class ASTWriter : public ASTDeserializationListener,
586599
unsigned DeclEnumAbbrev = 0;
587600
unsigned DeclObjCIvarAbbrev = 0;
588601
unsigned DeclCXXMethodAbbrev = 0;
602+
unsigned DeclSpecializationsAbbrev = 0;
603+
589604
unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
590605
unsigned DeclTemplateCXXMethodAbbrev = 0;
591606
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)