Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Serialization] Introduce OnDiskHashTable for specializations #83233

Open
wants to merge 1 commit into
base: users/ChuanqiXu9/D41416
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions clang/include/clang/AST/ExternalASTSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);

/// Load all the external specializations for the Decl \param D if \param
/// OnlyPartial is false. Otherwise, load all the external **partial**
/// specializations for the \param D.
virtual void LoadExternalSpecializations(const Decl *D, bool OnlyPartial);

/// Load all the specializations for the Decl \param D with the same template
/// args specified by \param TemplateArgs.
virtual void
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs);

/// Ensures that the table of all visible declarations inside this
/// context is up to date.
///
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/MultiplexExternalSemaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;

void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;

void
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

/// Ensures that the table of all visible declarations inside this
/// context is up to date.
void completeVisibleDeclsMap(const DeclContext *DC) override;
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,9 @@ enum ASTRecordTypes {
/// Record code for lexical and visible block for delayed namespace in
/// reduced BMI.
DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD = 68,

/// Record code for updated specialization
UPDATE_SPECIALIZATION = 69,
};

/// Record types used within a source manager block.
Expand Down Expand Up @@ -1451,6 +1454,9 @@ enum DeclCode {
/// A HLSLBufferDecl record.
DECL_HLSL_BUFFER,

// A decls specilization record.
DECL_SPECIALIZATIONS,

/// An ImplicitConceptSpecializationDecl record.
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,

Expand Down
34 changes: 31 additions & 3 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,9 @@ class ASTIdentifierLookupTrait;
/// The on-disk hash table(s) used for DeclContext name lookup.
struct DeclContextLookupTable;

/// The on-disk hash table(s) used for specialization decls.
struct LazySpecializationInfoLookupTable;

} // namespace reader

} // namespace serialization
Expand Down Expand Up @@ -618,20 +621,29 @@ class ASTReader
llvm::DenseMap<const DeclContext *,
serialization::reader::DeclContextLookupTable> Lookups;

/// Map from decls to specialized decls.
llvm::DenseMap<const Decl *,
serialization::reader::LazySpecializationInfoLookupTable>
SpecializationsLookups;

// Updates for visible decls can occur for other contexts than just the
// TU, and when we read those update records, the actual context may not
// be available yet, so have this pending map using the ID as a key. It
// will be realized when the context is actually loaded.
struct PendingVisibleUpdate {
// will be realized when the data is actually loaded.
struct UpdateData {
ModuleFile *Mod;
const unsigned char *Data;
};
using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
using DeclContextVisibleUpdates = SmallVector<UpdateData, 1>;

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

using SpecializationsUpdate = SmallVector<UpdateData, 1>;
llvm::DenseMap<GlobalDeclID, SpecializationsUpdate>
PendingSpecializationsUpdates;

/// The set of C++ or Objective-C classes that have forward
/// declarations that have not yet been linked to their definitions.
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
Expand All @@ -658,6 +670,11 @@ class ASTReader
llvm::BitstreamCursor &Cursor,
uint64_t Offset, GlobalDeclID ID);

bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
uint64_t Offset, Decl *D);
void AddSpecializations(const Decl *D, const unsigned char *Data,
ModuleFile &M);

/// A vector containing identifiers that have already been
/// loaded.
///
Expand Down Expand Up @@ -1360,6 +1377,11 @@ class ASTReader
const serialization::reader::DeclContextLookupTable *
getLoadedLookupTables(DeclContext *Primary) const;

/// Get the loaded specializations lookup tables for \p D,
/// if any.
serialization::reader::LazySpecializationInfoLookupTable *
getLoadedSpecializationsLookupTables(const Decl *D);

private:
struct ImportedModule {
ModuleFile *Mod;
Expand Down Expand Up @@ -1989,6 +2011,12 @@ class ASTReader
unsigned BlockID,
uint64_t *StartOfBlockOffset = nullptr);

void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;

void
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

/// Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
Expand Down
15 changes: 15 additions & 0 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,12 @@ class ASTWriter : public ASTDeserializationListener,
/// Only meaningful for reduced BMI.
DeclUpdateMap DeclUpdatesFromGMF;

/// Mapping from decl templates and its new specialization in the
/// current TU.
using SpecializationUpdateMap =
llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
SpecializationUpdateMap SpecializationsUpdates;

using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;

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

void GenerateSpecializationInfoLookupTable(
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteSpecializationInfoLookupTable(
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations);

void GenerateNameLookupTable(const DeclContext *DC,
llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
Expand All @@ -560,6 +572,7 @@ class ASTWriter : public ASTDeserializationListener,
void WriteDeclAndTypes(ASTContext &Context);
void PrepareWritingSpecialDecls(Sema &SemaRef);
void WriteSpecialDeclRecords(Sema &SemaRef);
void WriteSpecializationsUpdates();
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
Expand All @@ -586,6 +599,8 @@ class ASTWriter : public ASTDeserializationListener,
unsigned DeclEnumAbbrev = 0;
unsigned DeclObjCIvarAbbrev = 0;
unsigned DeclCXXMethodAbbrev = 0;
unsigned DeclSpecializationsAbbrev = 0;

unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
unsigned DeclTemplateCXXMethodAbbrev = 0;
unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,14 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c

void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
bool OnlyPartial /*=false*/) const {
auto *ExternalSource = getASTContext().getExternalSource();
if (!ExternalSource)
return;

ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
OnlyPartial);
return;

// Grab the most recent declaration to ensure we've loaded any lazy
// redeclarations of this template.
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
Expand All @@ -354,6 +362,8 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(

Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(
LazySpecializationInfo &LazySpecInfo) const {
llvm_unreachable("We don't use LazySpecializationInfo any more");

GlobalDeclID ID = LazySpecInfo.DeclID;
assert(ID.isValid() && "Loading already loaded specialization!");
// Note that we loaded the specialization.
Expand All @@ -364,6 +374,13 @@ Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(

void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
auto *ExternalSource = getASTContext().getExternalSource();
if (!ExternalSource)
return;

ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), Args);
return;

CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
if (auto *Specs = CommonBasePtr->LazySpecializations) {
unsigned Hash = TemplateArgumentList::ComputeODRHash(Args);
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/ExternalASTSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
return false;
}

void ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) {}

void ExternalASTSource::LoadExternalSpecializations(
const Decl *D, ArrayRef<TemplateArgument>) {}

void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {}

void ExternalASTSource::FindExternalLexicalDecls(
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Sema/MultiplexExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
return AnyDeclsFound;
}

void MultiplexExternalSemaSource::LoadExternalSpecializations(
const Decl *D, bool OnlyPartial) {
for (size_t i = 0; i < Sources.size(); ++i)
Sources[i]->LoadExternalSpecializations(D, OnlyPartial);
}

void MultiplexExternalSemaSource::LoadExternalSpecializations(
const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
for (size_t i = 0; i < Sources.size(); ++i)
Sources[i]->LoadExternalSpecializations(D, TemplateArgs);
}

void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->completeVisibleDeclsMap(DC);
Expand Down