Skip to content

Commit

Permalink
[Serialization] Code cleanups and polish 83233
Browse files Browse the repository at this point in the history
  • Loading branch information
ChuanqiXu9 committed Mar 5, 2024
1 parent 03e7d56 commit 19617bb
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 234 deletions.
34 changes: 3 additions & 31 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ class TemplateArgumentList final
TemplateArgumentList(const TemplateArgumentList &) = delete;
TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;

/// Create hash for the given arguments.
static unsigned ComputeODRHash(ArrayRef<TemplateArgument> Args);
/// Create stable hash for the given arguments across compiler invocations.
static unsigned ComputeStableHash(ArrayRef<TemplateArgument> Args);

/// Create a new template argument list that copies the given set of
/// template arguments.
Expand Down Expand Up @@ -733,25 +733,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
}

void anchor() override;
struct LazySpecializationInfo {
uint32_t DeclID = ~0U;
unsigned ODRHash = ~0U;
bool IsPartial = false;
LazySpecializationInfo(uint32_t ID, unsigned Hash = ~0U,
bool Partial = false)
: DeclID(ID), ODRHash(Hash), IsPartial(Partial) {}
LazySpecializationInfo() {}
bool operator<(const LazySpecializationInfo &Other) const {
return DeclID < Other.DeclID;
}
bool operator==(const LazySpecializationInfo &Other) const {
assert((DeclID != Other.DeclID || ODRHash == Other.ODRHash) &&
"Hashes differ!");
assert((DeclID != Other.DeclID || IsPartial == Other.IsPartial) &&
"Both must be the same kinds!");
return DeclID == Other.DeclID;
}
};

protected:
template <typename EntryType> struct SpecEntryTraits {
Expand Down Expand Up @@ -795,11 +776,9 @@ class RedeclarableTemplateDecl : public TemplateDecl,

void loadLazySpecializationsImpl(bool OnlyPartial = false) const;

void loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
TemplateParameterList *TPL = nullptr) const;

Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const;

template <class EntryType, typename ...ProfileArguments>
typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
Expand All @@ -820,13 +799,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
InstantiatedFromMember;

/// If non-null, points to an array of specializations (including
/// partial specializations) known only by their external declaration IDs.
///
/// The first value in the array is the number of specializations/partial
/// specializations that follow.
LazySpecializationInfo *LazySpecializations = nullptr;

/// The set of "injected" template arguments used within this
/// template.
///
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/AST/ExternalASTSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {

/// Load all the specializations for the Decl \param D with the same template
/// args specified by \param TemplateArgs.
virtual void
///
/// Return true if any new specializations get loaded. Return false otherwise.
virtual bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs);

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/MultiplexExternalSemaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {

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

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

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ enum ASTRecordTypes {
/// recorded in a preamble.
PP_ASSUME_NONNULL_LOC = 67,

UPDATE_SPECIALIZATION = 68,
CXX_ADDED_TEMPLATE_SPECIALIZATION = 68,
};

/// Record types used within a source manager block.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2006,7 +2006,7 @@ class ASTReader

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

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

Expand Down
85 changes: 40 additions & 45 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,68 +342,50 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
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();
if (auto *Specs = CommonBasePtr->LazySpecializations) {
if (!OnlyPartial)
CommonBasePtr->LazySpecializations = nullptr;
for (uint32_t I = 0, N = Specs[0].DeclID; I != N; ++I) {
// Skip over already loaded specializations.
if (!Specs[I + 1].ODRHash)
continue;
if (!OnlyPartial || Specs[I + 1].IsPartial)
(void)loadLazySpecializationImpl(Specs[I + 1]);
}
}
}

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

uint32_t ID = LazySpecInfo.DeclID;
assert(ID && "Loading already loaded specialization!");
// Note that we loaded the specialization.
LazySpecInfo.DeclID = LazySpecInfo.ODRHash = LazySpecInfo.IsPartial = 0;
return getASTContext().getExternalSource()->GetExternalDecl(ID);
}

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

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

CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
if (auto *Specs = CommonBasePtr->LazySpecializations) {
unsigned Hash = TemplateArgumentList::ComputeODRHash(Args);
for (uint32_t I = 0, N = Specs[0].DeclID; I != N; ++I)
if (Specs[I + 1].ODRHash && Specs[I + 1].ODRHash == Hash)
(void)loadLazySpecializationImpl(Specs[I + 1]);
}
return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), Args);
}

template<class EntryType, typename... ProfileArguments>
static
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
RedeclarableTemplateDecl::findSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
ASTContext &Context,
ProfileArguments&&... ProfileArgs) {
using SETraits = SpecEntryTraits<EntryType>;

loadLazySpecializationsImpl(std::forward<ProfileArguments>(ProfileArgs)...);
using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;

llvm::FoldingSetNodeID ID;
EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
getASTContext());
Context);
EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
}


template<class EntryType, typename... ProfileArguments>
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
RedeclarableTemplateDecl::findSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
ProfileArguments&&... ProfileArgs) {

if (auto *Found = findSpecializationLocally(Specs, InsertPos, getASTContext(),
std::forward<ProfileArguments>(ProfileArgs)...))
return Found;

if (!loadLazySpecializationsImpl(std::forward<ProfileArguments>(ProfileArgs)...))
return nullptr;

return findSpecializationLocally(Specs, InsertPos, getASTContext(),
std::forward<ProfileArguments>(ProfileArgs)...);
}

template<class Derived, class EntryType>
void RedeclarableTemplateDecl::addSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
Expand Down Expand Up @@ -939,7 +921,20 @@ TemplateArgumentList::CreateCopy(ASTContext &Context,
return new (Mem) TemplateArgumentList(Args);
}

unsigned TemplateArgumentList::ComputeODRHash(ArrayRef<TemplateArgument> Args) {
unsigned
TemplateArgumentList::ComputeStableHash(ArrayRef<TemplateArgument> Args) {
// FIXME: ODR hashing may not be the best mechanism to hash the template
// arguments. ODR hashing is (or perhaps, should be) about determining whether
// two things are spelled the same way and have the same meaning (as required
// by the C++ ODR), whereas what we want here is whether they have the same
// meaning regardless of spelling. Maybe we can get away with reusing ODR
// hashing anyway, on the basis that any canonical, non-dependent template
// argument should have the same (invented) spelling in every translation
// unit, but it is not sure that's true in all cases. There may still be cases
// where the canonical type includes some aspect of "whatever we saw first",
// in which case the ODR hash can differ across translation units for
// non-dependent, canonical template arguments that are spelled differently
// but have the same meaning. But it is not easy to raise examples.
ODRHash Hasher;
for (TemplateArgument TA : Args)
Hasher.AddTemplateArgument(TA);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/ExternalASTSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,

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

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

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

Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Sema/MultiplexExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,12 @@ void MultiplexExternalSemaSource::LoadExternalSpecializations(
Sources[i]->LoadExternalSpecializations(D, OnlyPartial);
}

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

void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Serialization/ASTCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ namespace serialization {

enum DeclUpdateKind {
UPD_CXX_ADDED_IMPLICIT_MEMBER,
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
UPD_CXX_ADDED_FUNCTION_DEFINITION,
UPD_CXX_ADDED_VAR_DEFINITION,
Expand Down
17 changes: 12 additions & 5 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3499,7 +3499,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;
}

case UPDATE_SPECIALIZATION: {
case CXX_ADDED_TEMPLATE_SPECIALIZATION: {
unsigned Idx = 0;
serialization::DeclID ID = ReadDeclID(F, Record, Idx);
auto *Data = (const unsigned char *)Blob.data();
Expand Down Expand Up @@ -7964,23 +7964,30 @@ void ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
GetDecl(Info.ID);
}

void ASTReader::LoadExternalSpecializations(
bool ASTReader::LoadExternalSpecializations(
const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
assert(D);

auto It = SpecializationsLookups.find(D);
if (It == SpecializationsLookups.end())
return;
return false;

Deserializing LookupResults(this);
auto HashValue = TemplateArgumentList::ComputeODRHash(TemplateArgs);
auto HashValue = TemplateArgumentList::ComputeStableHash(TemplateArgs);

// Get Decl may violate the iterator from SpecializationsLookups
llvm::SmallVector<serialization::reader::LazySpecializationInfo, 8> Infos =
It->second.Table.find(HashValue);

for (auto &Info : Infos)
bool NewSpecsFound = false;
for (auto &Info : Infos) {
if (GetExistingDecl(Info.ID))
continue;
NewSpecsFound = true;
GetDecl(Info.ID);
}

return NewSpecsFound;
}

void ASTReader::FindExternalLexicalDecls(
Expand Down
Loading

0 comments on commit 19617bb

Please sign in to comment.