Skip to content

Commit 71937e9

Browse files
committed
Load Spec lazily
1 parent 5100c8f commit 71937e9

20 files changed

+790
-90
lines changed

interpreter/llvm-project/clang/include/clang/AST/DeclTemplate.h

+32-7
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,11 @@ class FunctionTemplateSpecializationInfo final
519519
return Function.getInt();
520520
}
521521

522+
void loadExternalRedecls();
523+
522524
public:
523525
friend TrailingObjects;
526+
friend class ASTReader;
524527

525528
static FunctionTemplateSpecializationInfo *
526529
Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
@@ -817,13 +820,20 @@ class RedeclarableTemplateDecl : public TemplateDecl,
817820
return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
818821
}
819822

820-
void loadLazySpecializationsImpl() const;
823+
void loadExternalSpecializations() const;
821824

822825
template <class EntryType, typename ...ProfileArguments>
823826
typename SpecEntryTraits<EntryType>::DeclType*
824827
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
825828
void *&InsertPos, ProfileArguments &&...ProfileArgs);
826829

830+
template <class EntryType, typename... ProfileArguments>
831+
typename SpecEntryTraits<EntryType>::DeclType *
832+
findLocalSpecialization(llvm::FoldingSetVector<EntryType> &Specs,
833+
void *&InsertPos, ProfileArguments &&... ProfileArgs);
834+
835+
bool loadLazySpecializationsWithArgs(ArrayRef<TemplateArgument> TemplateArgs);
836+
827837
template <class Derived, class EntryType>
828838
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
829839
EntryType *Entry, void *InsertPos);
@@ -842,9 +852,13 @@ class RedeclarableTemplateDecl : public TemplateDecl,
842852
/// If non-null, points to an array of specializations (including
843853
/// partial specializations) known only by their external declaration IDs.
844854
///
855+
/// These specializations needs to be loaded at once in
856+
/// loadExternalSpecializations to complete the redecl chain or be preparing
857+
/// for template resolution.
858+
///
845859
/// The first value in the array is the number of specializations/partial
846860
/// specializations that follow.
847-
uint32_t *LazySpecializations = nullptr;
861+
uint32_t *ExternalSpecializations = nullptr;
848862

849863
/// The set of "injected" template arguments used within this
850864
/// template.
@@ -878,6 +892,8 @@ class RedeclarableTemplateDecl : public TemplateDecl,
878892
friend class ASTDeclWriter;
879893
friend class ASTReader;
880894
template <class decl_type> friend class RedeclarableTemplate;
895+
friend class ClassTemplateSpecializationDecl;
896+
friend class VarTemplateSpecializationDecl;
881897

882898
/// Retrieves the canonical declaration of this template.
883899
RedeclarableTemplateDecl *getCanonicalDecl() override {
@@ -1005,6 +1021,7 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> {
10051021
class FunctionTemplateDecl : public RedeclarableTemplateDecl {
10061022
protected:
10071023
friend class FunctionDecl;
1024+
friend class FunctionTemplateSpecializationInfo;
10081025

10091026
/// Data that is common to all of the declarations of a given
10101027
/// function template.
@@ -1040,13 +1057,13 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
10401057
void addSpecialization(FunctionTemplateSpecializationInfo* Info,
10411058
void *InsertPos);
10421059

1060+
/// Load any lazily-loaded specializations from the external source.
1061+
void LoadLazySpecializations() const;
1062+
10431063
public:
10441064
friend class ASTDeclReader;
10451065
friend class ASTDeclWriter;
10461066

1047-
/// Load any lazily-loaded specializations from the external source.
1048-
void LoadLazySpecializations() const;
1049-
10501067
/// Get the underlying function declaration of the template.
10511068
FunctionDecl *getTemplatedDecl() const {
10521069
return static_cast<FunctionDecl *>(TemplatedDecl);
@@ -1884,6 +1901,8 @@ class ClassTemplateSpecializationDecl
18841901
/// Really a value of type TemplateSpecializationKind.
18851902
unsigned SpecializationKind : 3;
18861903

1904+
void loadExternalRedecls();
1905+
18871906
protected:
18881907
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
18891908
DeclContext *DC, SourceLocation StartLoc,
@@ -1897,6 +1916,7 @@ class ClassTemplateSpecializationDecl
18971916
public:
18981917
friend class ASTDeclReader;
18991918
friend class ASTDeclWriter;
1919+
friend class ASTReader;
19001920

19011921
static ClassTemplateSpecializationDecl *
19021922
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
@@ -2325,6 +2345,9 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
23252345
friend class ASTDeclReader;
23262346
friend class ASTDeclWriter;
23272347

2348+
friend class TemplateDeclInstantiator;
2349+
friend class ClassTemplateSpecializationDecl;
2350+
23282351
/// Load any lazily-loaded specializations from the external source.
23292352
void LoadLazySpecializations() const;
23302353

@@ -2767,6 +2790,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
27672790
/// no initializer.
27682791
unsigned IsCompleteDefinition : 1;
27692792

2793+
void loadExternalRedecls();
2794+
27702795
protected:
27712796
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
27722797
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -2780,6 +2805,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
27802805
public:
27812806
friend class ASTDeclReader;
27822807
friend class ASTDeclWriter;
2808+
friend class ASTReader;
27832809
friend class VarDecl;
27842810

27852811
static VarTemplateSpecializationDecl *
@@ -3185,8 +3211,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
31853211
friend class ASTDeclReader;
31863212
friend class ASTDeclWriter;
31873213

3188-
/// Load any lazily-loaded specializations from the external source.
3189-
void LoadLazySpecializations() const;
3214+
friend class VarTemplatePartialSpecializationDecl;
31903215

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

interpreter/llvm-project/clang/include/clang/AST/ExternalASTSource.h

+9
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,15 @@ 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 bool
156+
LoadExternalSpecializations(const Decl *D,
157+
ArrayRef<TemplateArgument> TemplateArgs);
158+
159+
/// Load all the external specializations for the Decl D.
160+
virtual void LoadAllExternalSpecializations(const Decl *D);
161+
153162
/// Ensures that the table of all visible declarations inside this
154163
/// context is up to date.
155164
///

interpreter/llvm-project/clang/include/clang/AST/ODRHash.h

+3
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:

interpreter/llvm-project/clang/include/clang/Basic/LangOptions.def

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS syntax")
175175
COMPATIBLE_LANGOPT(CPlusPlusModules, 1, 0, "C++ modules syntax")
176176
BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 3, CMK_None,
177177
"compiling a module interface")
178+
COMPATIBLE_LANGOPT(LoadExternalSpecializationsLazily, 1, 0, "Load External Specializations Lazily")
178179
BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
179180
BENIGN_LANGOPT(BuildingPCHWithObjectFile, 1, 0, "building a pch which has a corresponding object file")
180181
BENIGN_LANGOPT(CacheGeneratedPCH, 1, 0, "cache generated PCH files in memory")

interpreter/llvm-project/clang/include/clang/Driver/Options.td

+10-1
Original file line numberDiff line numberDiff line change
@@ -2307,8 +2307,17 @@ defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
23072307
PosFlag<SetTrue, [], "Look up implicit modules in the prebuilt module path">,
23082308
NegFlag<SetFalse>, BothFlags<[NoXarchOption, CC1Option]>>;
23092309

2310+
defm load_external_specializations_lazily : BoolOption<"f", "load-external-specializations-lazily",
2311+
LangOpts<"LoadExternalSpecializationsLazily">, DefaultFalse,
2312+
PosFlag<SetTrue, [],
2313+
"Load required external specialization only when required.">,
2314+
NegFlag<SetFalse>>,
2315+
BothFlags<[CoreOption, CC1Option]>,
2316+
Group<f_clang_Group>;
2317+
23102318
def fmodule_output_EQ : Joined<["-"], "fmodule-output=">, Flags<[NoXarchOption, CC1Option]>,
2311-
HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
2319+
HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
2320+
23122321
def fmodule_output : Flag<["-"], "fmodule-output">, Flags<[NoXarchOption, CC1Option]>,
23132322
HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
23142323

interpreter/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h

+8
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ 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 bool
103+
LoadExternalSpecializations(const Decl *D,
104+
ArrayRef<TemplateArgument> TemplateArgs) override;
105+
106+
void LoadAllExternalSpecializations(const Decl *D) override;
107+
100108
/// Ensures that the table of all visible declarations inside this
101109
/// context is up to date.
102110
void completeVisibleDeclsMap(const DeclContext *DC) override;

interpreter/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h

+5
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,8 @@ enum ASTRecordTypes {
702702
/// Record code for an unterminated \#pragma clang assume_nonnull begin
703703
/// recorded in a preamble.
704704
PP_ASSUME_NONNULL_LOC = 67,
705+
706+
UPDATE_SPECIALIZATION = 68,
705707
};
706708

707709
/// Record types used within a source manager block.
@@ -1523,6 +1525,9 @@ enum DeclCode {
15231525
/// An ImplicitConceptSpecializationDecl record.
15241526
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
15251527

1528+
// A decls specilization record.
1529+
DECL_SPECIALIZATIONS,
1530+
15261531
DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION
15271532
};
15281533

interpreter/llvm-project/clang/include/clang/Serialization/ASTReader.h

+39-3
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,9 @@ class ASTIdentifierLookupTrait;
341341
/// The on-disk hash table(s) used for DeclContext name lookup.
342342
struct DeclContextLookupTable;
343343

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

346349
} // namespace serialization
@@ -596,21 +599,30 @@ class ASTReader
596599
llvm::DenseMap<const DeclContext *,
597600
serialization::reader::DeclContextLookupTable> Lookups;
598601

602+
/// Map from decls to specialized decls.
603+
llvm::DenseMap<const Decl *,
604+
serialization::reader::SpecializationsLookupTable>
605+
SpecializationsLookups;
606+
599607
// Updates for visible decls can occur for other contexts than just the
600608
// TU, and when we read those update records, the actual context may not
601609
// be available yet, so have this pending map using the ID as a key. It
602-
// will be realized when the context is actually loaded.
603-
struct PendingVisibleUpdate {
610+
// will be realized when the data is actually loaded.
611+
struct UpdateData {
604612
ModuleFile *Mod;
605613
const unsigned char *Data;
606614
};
607-
using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
615+
using DeclContextVisibleUpdates = SmallVector<UpdateData, 1>;
608616

609617
/// Updates to the visible declarations of declaration contexts that
610618
/// haven't been loaded yet.
611619
llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
612620
PendingVisibleUpdates;
613621

622+
using SpecializationsUpdate = SmallVector<UpdateData, 1>;
623+
llvm::DenseMap<serialization::DeclID, SpecializationsUpdate>
624+
PendingSpecializationsUpdates;
625+
614626
/// The set of C++ or Objective-C classes that have forward
615627
/// declarations that have not yet been linked to their definitions.
616628
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
@@ -637,6 +649,11 @@ class ASTReader
637649
llvm::BitstreamCursor &Cursor,
638650
uint64_t Offset, serialization::DeclID ID);
639651

652+
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
653+
uint64_t Offset, Decl *D);
654+
void AddSpecializations(const Decl *D, const unsigned char *Data,
655+
ModuleFile &M);
656+
640657
/// A vector containing identifiers that have already been
641658
/// loaded.
642659
///
@@ -1327,6 +1344,11 @@ class ASTReader
13271344
const serialization::reader::DeclContextLookupTable *
13281345
getLoadedLookupTables(DeclContext *Primary) const;
13291346

1347+
/// Get the loaded specializations lookup tables for \p D,
1348+
/// if any.
1349+
serialization::reader::SpecializationsLookupTable *
1350+
getLoadedSpecializationsLookupTables(const Decl *D);
1351+
13301352
private:
13311353
struct ImportedModule {
13321354
ModuleFile *Mod;
@@ -1969,6 +1991,12 @@ class ASTReader
19691991
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
19701992
DeclarationName Name) override;
19711993

1994+
bool
1995+
LoadExternalSpecializations(const Decl *D,
1996+
ArrayRef<TemplateArgument> TemplateArgs) override;
1997+
1998+
void LoadAllExternalSpecializations(const Decl *D) override;
1999+
19722000
/// Read all of the declarations lexically stored in a
19732001
/// declaration context.
19742002
///
@@ -2376,6 +2404,14 @@ class ASTReader
23762404
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
23772405
};
23782406

2407+
/// Get a stable hash for template arguments across compiler invovations.
2408+
/// This is used for loading corresponding specializations lazily according
2409+
/// to the template arguments.
2410+
/// Given it is fine to load additional specializations, we're tolerant to
2411+
/// map different template arguments to the same hash value as long as the
2412+
/// semantically same template arguments get the same hash value.
2413+
unsigned GetTemplateArgsStableHash(ArrayRef<TemplateArgument> TemplateArgs);
2414+
23792415
} // namespace clang
23802416

23812417
#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H

interpreter/llvm-project/clang/include/clang/Serialization/ASTWriter.h

+13
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ class ASTWriter : public ASTDeserializationListener,
373373
/// record containing modifications to them.
374374
DeclUpdateMap DeclUpdates;
375375

376+
using SpecializationUpdateMap =
377+
llvm::MapVector<const NamedDecl *, SmallVector<const NamedDecl *>>;
378+
SpecializationUpdateMap SpecializationsUpdates;
379+
376380
using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
377381

378382
/// Map of first declarations from a chained PCH that point to the
@@ -517,6 +521,13 @@ class ASTWriter : public ASTDeserializationListener,
517521
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
518522
bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);
519523

524+
void GenerateSpecializationsLookupTable(
525+
const NamedDecl *D, llvm::SmallVectorImpl<const NamedDecl *> &Specs,
526+
llvm::SmallVectorImpl<char> &LookupTable);
527+
uint64_t WriteSpecializationsLookupTable(
528+
const NamedDecl *D,
529+
llvm::SmallVectorImpl<const NamedDecl *> &Specializations);
530+
520531
void GenerateNameLookupTable(const DeclContext *DC,
521532
llvm::SmallVectorImpl<char> &LookupTable);
522533
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
@@ -528,6 +539,7 @@ class ASTWriter : public ASTDeserializationListener,
528539
void WriteReferencedSelectorsPool(Sema &SemaRef);
529540
void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
530541
bool IsModule);
542+
void WriteSpecializationsUpdates();
531543
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
532544
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
533545
void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
@@ -554,6 +566,7 @@ class ASTWriter : public ASTDeserializationListener,
554566
unsigned DeclEnumAbbrev = 0;
555567
unsigned DeclObjCIvarAbbrev = 0;
556568
unsigned DeclCXXMethodAbbrev = 0;
569+
unsigned DeclSpecializationsAbbrev = 0;
557570

558571
unsigned DeclRefExprAbbrev = 0;
559572
unsigned CharacterLiteralAbbrev = 0;

0 commit comments

Comments
 (0)