Skip to content

Commit 047b136

Browse files
vgvassilevilya-biryukov
authored andcommitted
D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one.
Fix test mismatch failure fmt [Serialization] Introduce OnDiskHashTable for specializations Following up for llvm#83108 This follows the suggestion literally from llvm#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. [Serialization] Code cleanups and polish 83233
1 parent 3b5e7c8 commit 047b136

20 files changed

+1020
-145
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ class TemplateArgumentList final
256256
TemplateArgumentList(const TemplateArgumentList &) = delete;
257257
TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
258258

259+
/// Create stable hash for the given arguments across compiler invocations.
260+
static unsigned ComputeStableHash(ArrayRef<TemplateArgument> Args);
261+
259262
/// Create a new template argument list that copies the given set of
260263
/// template arguments.
261264
static TemplateArgumentList *CreateCopy(ASTContext &Context,
@@ -730,6 +733,7 @@ class RedeclarableTemplateDecl : public TemplateDecl,
730733
}
731734

732735
void anchor() override;
736+
733737
protected:
734738
template <typename EntryType> struct SpecEntryTraits {
735739
using DeclType = EntryType;
@@ -770,13 +774,22 @@ class RedeclarableTemplateDecl : public TemplateDecl,
770774
return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
771775
}
772776

773-
void loadLazySpecializationsImpl() const;
777+
void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
778+
779+
bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
780+
TemplateParameterList *TPL = nullptr) const;
774781

775782
template <class EntryType, typename ...ProfileArguments>
776783
typename SpecEntryTraits<EntryType>::DeclType*
777784
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
778785
void *&InsertPos, ProfileArguments &&...ProfileArgs);
779786

787+
template <class EntryType, typename... ProfileArguments>
788+
typename SpecEntryTraits<EntryType>::DeclType *
789+
findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
790+
void *&InsertPos,
791+
ProfileArguments &&...ProfileArgs);
792+
780793
template <class Derived, class EntryType>
781794
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
782795
EntryType *Entry, void *InsertPos);
@@ -792,13 +805,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
792805
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
793806
InstantiatedFromMember;
794807

795-
/// If non-null, points to an array of specializations (including
796-
/// partial specializations) known only by their external declaration IDs.
797-
///
798-
/// The first value in the array is the number of specializations/partial
799-
/// specializations that follow.
800-
uint32_t *LazySpecializations = nullptr;
801-
802808
/// The set of "injected" template arguments used within this
803809
/// template.
804810
///
@@ -2268,7 +2274,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22682274
friend class TemplateDeclInstantiator;
22692275

22702276
/// Load any lazily-loaded specializations from the external source.
2271-
void LoadLazySpecializations() const;
2277+
void LoadLazySpecializations(bool OnlyPartial = false) const;
22722278

22732279
/// Get the underlying class declarations of the template.
22742280
CXXRecordDecl *getTemplatedDecl() const {
@@ -3039,7 +3045,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
30393045
friend class ASTDeclWriter;
30403046

30413047
/// Load any lazily-loaded specializations from the external source.
3042-
void LoadLazySpecializations() const;
3048+
void LoadLazySpecializations(bool OnlyPartial = false) const;
30433049

30443050
/// Get the underlying variable declarations of the template.
30453051
VarDecl *getTemplatedDecl() const {

clang/include/clang/AST/ExternalASTSource.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ 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+
///
161+
/// Return true if any new specializations get loaded. Return false otherwise.
162+
virtual bool
163+
LoadExternalSpecializations(const Decl *D,
164+
ArrayRef<TemplateArgument> TemplateArgs);
165+
153166
/// Ensures that the table of all visible declarations inside this
154167
/// context is up to date.
155168
///

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+
bool
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ enum ASTRecordTypes {
698698
/// Record code for an unterminated \#pragma clang assume_nonnull begin
699699
/// recorded in a preamble.
700700
PP_ASSUME_NONNULL_LOC = 67,
701+
702+
CXX_ADDED_TEMPLATE_SPECIALIZATION = 68,
701703
};
702704

703705
/// Record types used within a source manager block.
@@ -1523,6 +1525,9 @@ enum DeclCode {
15231525
/// A HLSLBufferDecl record.
15241526
DECL_HLSL_BUFFER,
15251527

1528+
// A decls specilization record.
1529+
DECL_SPECIALIZATIONS,
1530+
15261531
/// An ImplicitConceptSpecializationDecl record.
15271532
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
15281533

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
@@ -603,21 +606,30 @@ class ASTReader
603606
llvm::DenseMap<const DeclContext *,
604607
serialization::reader::DeclContextLookupTable> Lookups;
605608

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

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

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

659+
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
660+
uint64_t Offset, Decl *D);
661+
void AddSpecializations(const Decl *D, const unsigned char *Data,
662+
ModuleFile &M);
663+
647664
/// A vector containing identifiers that have already been
648665
/// loaded.
649666
///
@@ -1348,6 +1365,11 @@ class ASTReader
13481365
const serialization::reader::DeclContextLookupTable *
13491366
getLoadedLookupTables(DeclContext *Primary) const;
13501367

1368+
/// Get the loaded specializations lookup tables for \p D,
1369+
/// if any.
1370+
serialization::reader::LazySpecializationInfoLookupTable *
1371+
getLoadedSpecializationsLookupTables(const Decl *D);
1372+
13511373
private:
13521374
struct ImportedModule {
13531375
ModuleFile *Mod;
@@ -1982,6 +2004,12 @@ class ASTReader
19822004
unsigned BlockID,
19832005
uint64_t *StartOfBlockOffset = nullptr);
19842006

2007+
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
2008+
2009+
bool
2010+
LoadExternalSpecializations(const Decl *D,
2011+
ArrayRef<TemplateArgument> TemplateArgs) override;
2012+
19852013
/// Finds all the visible declarations with a given name.
19862014
/// The current implementation of this method just loads the entire
19872015
/// lookup table as unmaterialized references.

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ class ASTWriter : public ASTDeserializationListener,
389389
/// record containing modifications to them.
390390
DeclUpdateMap DeclUpdates;
391391

392+
using SpecializationUpdateMap =
393+
llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
394+
SpecializationUpdateMap SpecializationsUpdates;
395+
392396
using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
393397

394398
/// Map of first declarations from a chained PCH that point to the
@@ -531,6 +535,12 @@ class ASTWriter : public ASTDeserializationListener,
531535
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
532536
bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);
533537

538+
void GenerateSpecializationInfoLookupTable(
539+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
540+
llvm::SmallVectorImpl<char> &LookupTable);
541+
uint64_t WriteSpecializationInfoLookupTable(
542+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations);
543+
534544
void GenerateNameLookupTable(const DeclContext *DC,
535545
llvm::SmallVectorImpl<char> &LookupTable);
536546
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
@@ -542,6 +552,7 @@ class ASTWriter : public ASTDeserializationListener,
542552
void WriteReferencedSelectorsPool(Sema &SemaRef);
543553
void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
544554
bool IsModule);
555+
void WriteSpecializationsUpdates();
545556
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
546557
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
547558
void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
@@ -568,6 +579,8 @@ class ASTWriter : public ASTDeserializationListener,
568579
unsigned DeclEnumAbbrev = 0;
569580
unsigned DeclObjCIvarAbbrev = 0;
570581
unsigned DeclCXXMethodAbbrev = 0;
582+
unsigned DeclSpecializationsAbbrev = 0;
583+
571584
unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
572585
unsigned DeclTemplateCXXMethodAbbrev = 0;
573586
unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;

0 commit comments

Comments
 (0)