Skip to content

Commit 50fd47f

Browse files
committed
Load Specializations Lazily
1 parent abaa79b commit 50fd47f

19 files changed

+728
-65
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,11 @@ class FunctionTemplateSpecializationInfo final
525525
return Function.getInt();
526526
}
527527

528+
void loadExternalRedecls();
529+
528530
public:
529531
friend TrailingObjects;
532+
friend class ASTReader;
530533

531534
static FunctionTemplateSpecializationInfo *
532535
Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
@@ -789,13 +792,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
789792
return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
790793
}
791794

792-
void loadLazySpecializationsImpl() const;
795+
void loadExternalSpecializations() const;
793796

794797
template <class EntryType, typename ...ProfileArguments>
795798
typename SpecEntryTraits<EntryType>::DeclType*
796799
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
797800
void *&InsertPos, ProfileArguments &&...ProfileArgs);
798801

802+
void loadLazySpecializationsWithArgs(ArrayRef<TemplateArgument> TemplateArgs);
803+
799804
template <class Derived, class EntryType>
800805
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
801806
EntryType *Entry, void *InsertPos);
@@ -814,9 +819,13 @@ class RedeclarableTemplateDecl : public TemplateDecl,
814819
/// If non-null, points to an array of specializations (including
815820
/// partial specializations) known only by their external declaration IDs.
816821
///
822+
/// These specializations needs to be loaded at once in
823+
/// loadExternalSpecializations to complete the redecl chain or be preparing
824+
/// for template resolution.
825+
///
817826
/// The first value in the array is the number of specializations/partial
818827
/// specializations that follow.
819-
uint32_t *LazySpecializations = nullptr;
828+
uint32_t *ExternalSpecializations = nullptr;
820829

821830
/// The set of "injected" template arguments used within this
822831
/// template.
@@ -850,6 +859,8 @@ class RedeclarableTemplateDecl : public TemplateDecl,
850859
friend class ASTDeclWriter;
851860
friend class ASTReader;
852861
template <class decl_type> friend class RedeclarableTemplate;
862+
friend class ClassTemplateSpecializationDecl;
863+
friend class VarTemplateSpecializationDecl;
853864

854865
/// Retrieves the canonical declaration of this template.
855866
RedeclarableTemplateDecl *getCanonicalDecl() override {
@@ -977,6 +988,7 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> {
977988
class FunctionTemplateDecl : public RedeclarableTemplateDecl {
978989
protected:
979990
friend class FunctionDecl;
991+
friend class FunctionTemplateSpecializationInfo;
980992

981993
/// Data that is common to all of the declarations of a given
982994
/// function template.
@@ -1012,13 +1024,13 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
10121024
void addSpecialization(FunctionTemplateSpecializationInfo* Info,
10131025
void *InsertPos);
10141026

1027+
/// Load any lazily-loaded specializations from the external source.
1028+
void LoadLazySpecializations() const;
1029+
10151030
public:
10161031
friend class ASTDeclReader;
10171032
friend class ASTDeclWriter;
10181033

1019-
/// Load any lazily-loaded specializations from the external source.
1020-
void LoadLazySpecializations() const;
1021-
10221034
/// Get the underlying function declaration of the template.
10231035
FunctionDecl *getTemplatedDecl() const {
10241036
return static_cast<FunctionDecl *>(TemplatedDecl);
@@ -1839,6 +1851,8 @@ class ClassTemplateSpecializationDecl
18391851
LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
18401852
unsigned SpecializationKind : 3;
18411853

1854+
void loadExternalRedecls();
1855+
18421856
protected:
18431857
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
18441858
DeclContext *DC, SourceLocation StartLoc,
@@ -1852,6 +1866,7 @@ class ClassTemplateSpecializationDecl
18521866
public:
18531867
friend class ASTDeclReader;
18541868
friend class ASTDeclWriter;
1869+
friend class ASTReader;
18551870

18561871
static ClassTemplateSpecializationDecl *
18571872
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
@@ -2285,9 +2300,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22852300
friend class ASTDeclReader;
22862301
friend class ASTDeclWriter;
22872302
friend class TemplateDeclInstantiator;
2288-
2289-
/// Load any lazily-loaded specializations from the external source.
2290-
void LoadLazySpecializations() const;
2303+
friend class ClassTemplateSpecializationDecl;
22912304

22922305
/// Get the underlying class declarations of the template.
22932306
CXXRecordDecl *getTemplatedDecl() const {
@@ -2651,6 +2664,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
26512664
LLVM_PREFERRED_TYPE(bool)
26522665
unsigned IsCompleteDefinition : 1;
26532666

2667+
void loadExternalRedecls();
2668+
26542669
protected:
26552670
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
26562671
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -2664,6 +2679,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
26642679
public:
26652680
friend class ASTDeclReader;
26662681
friend class ASTDeclWriter;
2682+
friend class ASTReader;
26672683
friend class VarDecl;
26682684

26692685
static VarTemplateSpecializationDecl *
@@ -3057,8 +3073,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
30573073
friend class ASTDeclReader;
30583074
friend class ASTDeclWriter;
30593075

3060-
/// Load any lazily-loaded specializations from the external source.
3061-
void LoadLazySpecializations() const;
3076+
friend class VarTemplatePartialSpecializationDecl;
30623077

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

clang/include/clang/AST/ExternalASTSource.h

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

153+
/// Load all the external specialzations for the Decl and the corresponding
154+
/// template arguments.
155+
virtual void
156+
LoadExternalSpecializations(const Decl *D,
157+
ArrayRef<TemplateArgument> TemplateArgs);
158+
153159
/// Ensures that the table of all visible declarations inside this
154160
/// context is up to date.
155161
///

clang/include/clang/AST/ODRHash.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class ODRHash {
101101
// Save booleans until the end to lower the size of data to process.
102102
void AddBoolean(bool value);
103103

104+
// Add intergers to ID.
105+
void AddInteger(unsigned Value);
106+
104107
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent);
105108

106109
private:

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+
/// Load all the external specialzations for the Decl and the corresponding
101+
/// template args.
102+
virtual 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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,9 @@ enum DeclCode {
15231523
/// An ImplicitConceptSpecializationDecl record.
15241524
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
15251525

1526+
// A decls specilization record.
1527+
DECL_SPECIALIZATIONS,
1528+
15261529
DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION
15271530
};
15281531

clang/include/clang/Serialization/ASTReader.h

Lines changed: 28 additions & 0 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 SpecializationsLookupTable;
345+
343346
} // namespace reader
344347

345348
} // namespace serialization
@@ -599,6 +602,11 @@ class ASTReader
599602
llvm::DenseMap<const DeclContext *,
600603
serialization::reader::DeclContextLookupTable> Lookups;
601604

605+
/// Map from decls to specialized decls.
606+
llvm::DenseMap<const Decl *,
607+
serialization::reader::SpecializationsLookupTable>
608+
SpecializationsLookups;
609+
602610
// Updates for visible decls can occur for other contexts than just the
603611
// TU, and when we read those update records, the actual context may not
604612
// be available yet, so have this pending map using the ID as a key. It
@@ -640,6 +648,9 @@ class ASTReader
640648
llvm::BitstreamCursor &Cursor,
641649
uint64_t Offset, serialization::DeclID ID);
642650

651+
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
652+
uint64_t Offset, Decl *D);
653+
643654
/// A vector containing identifiers that have already been
644655
/// loaded.
645656
///
@@ -1343,6 +1354,11 @@ class ASTReader
13431354
const serialization::reader::DeclContextLookupTable *
13441355
getLoadedLookupTables(DeclContext *Primary) const;
13451356

1357+
/// Get the loaded specializations lookup tables for \p D,
1358+
/// if any.
1359+
serialization::reader::SpecializationsLookupTable *
1360+
getLoadedSpecializationsLookupTables(const Decl *D);
1361+
13461362
private:
13471363
struct ImportedModule {
13481364
ModuleFile *Mod;
@@ -1982,6 +1998,10 @@ class ASTReader
19821998
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
19831999
DeclarationName Name) override;
19842000

2001+
void
2002+
LoadExternalSpecializations(const Decl *D,
2003+
ArrayRef<TemplateArgument> TemplateArgs) override;
2004+
19852005
/// Read all of the declarations lexically stored in a
19862006
/// declaration context.
19872007
///
@@ -2404,6 +2424,14 @@ class ASTReader
24042424
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
24052425
};
24062426

2427+
/// Get a stable hash for template arguments across compiler invovations.
2428+
/// This is used for loading corresponding specializations lazily according
2429+
/// to the template arguments.
2430+
/// Given it is fine to load additional specializations, we're tolerant to
2431+
/// map different template arguments to the same hash value as long as the
2432+
/// semantically same template arguments get the same hash value.
2433+
unsigned GetTemplateArgsStableHash(ArrayRef<TemplateArgument> TemplateArgs);
2434+
24072435
/// A simple helper class to unpack an integer to bits and consuming
24082436
/// the bits in order.
24092437
class BitsUnpacker {

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,10 @@ class ASTWriter : public ASTDeserializationListener,
527527
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
528528
bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);
529529

530+
uint64_t WriteSpecializationsLookupTable(
531+
const NamedDecl *D,
532+
llvm::SmallVectorImpl<const NamedDecl *> &Specializations);
533+
530534
void GenerateNameLookupTable(const DeclContext *DC,
531535
llvm::SmallVectorImpl<char> &LookupTable);
532536
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
@@ -564,6 +568,8 @@ class ASTWriter : public ASTDeserializationListener,
564568
unsigned DeclEnumAbbrev = 0;
565569
unsigned DeclObjCIvarAbbrev = 0;
566570
unsigned DeclCXXMethodAbbrev = 0;
571+
unsigned DeclSpecializationsAbbrev = 0;
572+
567573
unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
568574
unsigned DeclTemplateCXXMethodAbbrev = 0;
569575
unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;

0 commit comments

Comments
 (0)