[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 created https://github.com/llvm/llvm-project/pull/83108 This from https://reviews.llvm.org/D41416. And we plan to introduce on disk hash table based on this. See https://github.com/llvm/llvm-project/pull/76774. Following off are cited from https://reviews.llvm.org/D41416: Currently, we load all lazy template specializations when we search whether there is a suitable template specialization for a template. This is especially suboptimal with modules. If module B specializes a template from module A the ASTReader would only read the specialization DeclID. This is observed to be especially pathological when module B is stl. However, the template instantiator (almost immediately after) will call findSpecialization. In turn, findSpecialization will load all lazy specializations to give an answer. This patch teaches findSpecialization to work with lazy specializations without having to deserialize their full content. It provides along with the DeclID an cross-TU stable ODRHash of the template arguments which is enough to decide if we have already specialization and which are the exact ones (we load all decls with the same hash to avoid potential collisions) to deserialize. While we make finding a template specialization more memory-efficient we are far from being done. There are still a few places which trigger eager deserialization of template specializations: the places where we require completion of the redeclaration chain. >From 59e1880df74434e3c446705788d92b5949d99536 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 - clang/lib/AST/DeclTemplate.cpp| 96 +-- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 36 ++--- clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 74 ++--- 7 files changed, 242 insertions(+), 61 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e3b6a7efb1127a..4ed9b58d4ff609 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ 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 struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -uint32_t *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2268,7 +2296,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external sourc
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Chuanqi Xu (ChuanqiXu9) Changes This from https://reviews.llvm.org/D41416. And we plan to introduce on disk hash table based on this. See https://github.com/llvm/llvm-project/pull/76774. Following off are cited from https://reviews.llvm.org/D41416: Currently, we load all lazy template specializations when we search whether there is a suitable template specialization for a template. This is especially suboptimal with modules. If module B specializes a template from module A the ASTReader would only read the specialization DeclID. This is observed to be especially pathological when module B is stl. However, the template instantiator (almost immediately after) will call findSpecialization. In turn, findSpecialization will load all lazy specializations to give an answer. This patch teaches findSpecialization to work with lazy specializations without having to deserialize their full content. It provides along with the DeclID an cross-TU stable ODRHash of the template arguments which is enough to decide if we have already specialization and which are the exact ones (we load all decls with the same hash to avoid potential collisions) to deserialize. While we make finding a template specialization more memory-efficient we are far from being done. There are still a few places which trigger eager deserialization of template specializations: the places where we require completion of the redeclaration chain. --- Patch is 26.57 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/83108.diff 7 Files Affected: - (modified) clang/include/clang/AST/DeclTemplate.h (+32-4) - (modified) clang/lib/AST/DeclTemplate.cpp (+74-22) - (modified) clang/lib/AST/ODRHash.cpp (+15) - (modified) clang/lib/Serialization/ASTReader.cpp (+17-8) - (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+23-13) - (modified) clang/lib/Serialization/ASTWriter.cpp (+19-2) - (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+62-12) ``diff diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e3b6a7efb1127a..4ed9b58d4ff609 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ 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 struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -uint32_t *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2268,7 +2296,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declara
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
ChuanqiXu9 wrote: Personally I feel this patch is good and the testing result from our workload shows it is good too. But it looks like the performance testing results from google @zygoloid @ilya-biryukov is not good. So maybe we need to wait for landing this. (It will be great if @ilya-biryukov would like to test again) https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 1ecbab56dcbb78268c8d19af34a50591f90b12a0 59e1880df74434e3c446705788d92b5949d99536 -- clang/include/clang/AST/DeclTemplate.h clang/lib/AST/DeclTemplate.cpp clang/lib/AST/ODRHash.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterDecl.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 4ed9b58d4f..51caef54ba 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -739,8 +739,8 @@ class RedeclarableTemplateDecl : public TemplateDecl, bool IsPartial = false; LazySpecializationInfo(uint32_t ID, unsigned Hash = ~0U, bool Partial = false) - : DeclID(ID), ODRHash(Hash), IsPartial(Partial) { } -LazySpecializationInfo() { } +: DeclID(ID), ODRHash(Hash), IsPartial(Partial) {} +LazySpecializationInfo() {} bool operator<(const LazySpecializationInfo &Other) const { return DeclID < Other.DeclID; } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 1babe39ee2..aa2368783d 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -16,12 +16,12 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/ODRHash.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" -#include "clang/AST/ODRHash.h" -#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -334,7 +334,7 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c } void RedeclarableTemplateDecl::loadLazySpecializationsImpl( - bool OnlyPartial/*=false*/) const { +bool OnlyPartial /*=false*/) const { // Grab the most recent declaration to ensure we've loaded any lazy // redeclarations of this template. CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); @@ -343,16 +343,16 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl( 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) + if (!Specs[I + 1].ODRHash) continue; - if (!OnlyPartial || Specs[I+1].IsPartial) -(void)loadLazySpecializationImpl(Specs[I+1]); + if (!OnlyPartial || Specs[I + 1].IsPartial) +(void)loadLazySpecializationImpl(Specs[I + 1]); } } } Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl( - LazySpecializationInfo &LazySpecInfo) const { +LazySpecializationInfo &LazySpecInfo) const { uint32_t ID = LazySpecInfo.DeclID; assert(ID && "Loading already loaded specialization!"); // Note that we loaded the specialization. @@ -360,16 +360,14 @@ Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl( return getASTContext().getExternalSource()->GetExternalDecl(ID); } -void -RedeclarableTemplateDecl::loadLazySpecializationsImpl(ArrayRef - Args, - TemplateParameterList *TPL) const { +void RedeclarableTemplateDecl::loadLazySpecializationsImpl( +ArrayRef Args, TemplateParameterList *TPL) const { 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]); + if (Specs[I + 1].ODRHash && Specs[I + 1].ODRHash == Hash) +(void)loadLazySpecializationImpl(Specs[I + 1]); } } @@ -546,7 +544,7 @@ ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, } void ClassTemplateDecl::LoadLazySpecializations( - bool OnlyPartial/*=false*/) const { +bool OnlyPartial /*=false*/) const { loadLazySpecializationsImpl(OnlyPartial); } @@ -1275,7 +1273,7 @@ VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, } void VarTemplateDecl::LoadLazySpecializations( - bool OnlyPartial/*=false*/) const { +bool OnlyPartial /*=false*/) const {
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
vgvassilev wrote: > Personally I feel this patch is good and the testing result from our workload > shows it is good too. But it looks like the performance testing results from > google @zygoloid @ilya-biryukov is not good. So maybe we need to wait for > landing this. (It will be great if @ilya-biryukov would like to test again) Thanks for putting this up. I was planning to do so, however, locally I got: ``` Clang :: CXX/module/basic/basic.link/p2.cppm Clang :: Driver/clang_f_opts.c Clang :: Driver/darwin-header-search-libcxx.cpp Clang :: Index/crash-recovery-modules.m Clang :: Modules/ExtDebugInfo.cpp Clang :: Modules/cxx-templates.cpp Clang :: Modules/odr_hash.cpp Clang :: Modules/using-directive-redecl.cpp Clang :: Modules/using-directive.cpp Clang :: PCH/chain-late-anonymous-namespace.cpp Clang :: PCH/cxx-namespaces.cpp Clang :: PCH/namespaces.cpp ``` I believe some tests require just adjusting the reference files, but others may need some debugging. https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
ChuanqiXu9 wrote: Weird. I only see two failures in my local environment: ``` Failed Tests (2): Clang :: Modules/cxx-templates.cpp Clang :: Modules/odr_hash.cpp ``` And I saw both of them in my patch. It is simply order mismatches. https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
vgvassilev wrote: > Weird. I only see two failures in my local environment: > > ``` > Failed Tests (2): > Clang :: Modules/cxx-templates.cpp > Clang :: Modules/odr_hash.cpp > ``` > > And I saw both of them in my patch. It is simply order mismatches. Ha, ok. I know that my system constantly have some tests that fail even fro the master but I thought these were real. If we don't see them in the bots then that's probably a problem only on my side... https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/83108 >From 59e1880df74434e3c446705788d92b5949d99536 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH 1/3] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 - clang/lib/AST/DeclTemplate.cpp| 96 +-- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 36 ++--- clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 74 ++--- 7 files changed, 242 insertions(+), 61 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e3b6a7efb1127a..4ed9b58d4ff609 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ 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 struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -uint32_t *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2268,7 +2296,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { @@ -3039,7 +3067,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { friend class ASTDeclWriter; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 3c217d6a6a5ae3..1babe39ee2a7e5 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -20,6 +20,8 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" +#include "clang/AST/ODRHash.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -331,16 +333,43 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c return Common; } -void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { +void RedeclarableTemplateDecl::loadLazySpecializationsImpl( + bool Onl
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/83108 >From 2a9dfdab30467bef5361cea743be0dc215011685 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH 1/3] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 - clang/lib/AST/DeclTemplate.cpp| 96 +-- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 36 ++--- clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 74 ++--- 7 files changed, 242 insertions(+), 61 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e3b6a7efb1127a..4ed9b58d4ff609 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ 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 struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -uint32_t *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2268,7 +2296,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { @@ -3039,7 +3067,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { friend class ASTDeclWriter; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 3c217d6a6a5ae3..1babe39ee2a7e5 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -20,6 +20,8 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" +#include "clang/AST/ODRHash.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -331,16 +333,43 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c return Common; } -void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { +void RedeclarableTemplateDecl::loadLazySpecializationsImpl( + bool Onl
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/83108 >From 270cdac974482a9852fa8c1bff517d444a5f51f2 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH 1/2] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 +++- clang/lib/AST/DeclTemplate.cpp| 100 +- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 46 ++ clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 76 +--- clang/test/Modules/cxx-templates.cpp | 8 +- clang/test/Modules/odr_hash.cpp | 4 +- 9 files changed, 255 insertions(+), 76 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 5b6a6b40b28ef8..d76c2937063696 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -729,6 +732,26 @@ class RedeclarableTemplateDecl : public TemplateDecl, } void anchor() override; + struct LazySpecializationInfo { +GlobalDeclID DeclID = GlobalDeclID(); +unsigned ODRHash = ~0U; +bool IsPartial = false; +LazySpecializationInfo(GlobalDeclID 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 struct SpecEntryTraits { using DeclType = EntryType; @@ -769,7 +792,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -796,7 +824,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -GlobalDeclID *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2279,7 +2307,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { @@ -3023,7 +3051,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { friend class ASTDeclWriter; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 722c7fcf0b0df7..021454c7707413 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -20,6 +20,8 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" +#include "clang/AST/ODRHash.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -331,17 +333,46 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c return Common; } -void RedeclarableTemplateDecl::loadLazySpecializatio
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/83108 >From be1c83fb885536c3e65657c6549bd20dd29d9649 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH 1/3] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 +++- clang/lib/AST/DeclTemplate.cpp| 100 +- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 46 ++ clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 76 +--- 7 files changed, 249 insertions(+), 70 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 3ee03eebdb8ca4..24578cfdaa7c7c 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ class RedeclarableTemplateDecl : public TemplateDecl, } void anchor() override; + struct LazySpecializationInfo { +GlobalDeclID DeclID = GlobalDeclID(); +unsigned ODRHash = ~0U; +bool IsPartial = false; +LazySpecializationInfo(GlobalDeclID 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 struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -GlobalDeclID *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2284,7 +2312,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { @@ -3056,7 +3084,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { friend class ASTDeclWriter; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index d27a30e0c5fce1..1afd7b4550c917 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -20,6 +20,8 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" +#include "clang/AST/ODRHash.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -331,17 +333,46 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c return Common; } -void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { +void RedeclarableTemplateDecl::loadLazySpecializationsImpl( +
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
ChuanqiXu9 wrote: Rebased with main. https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/83108 >From 1f7c6650f739092a1b8908de3793aa8bbdc7de34 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH 1/2] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 +++- clang/lib/AST/DeclTemplate.cpp| 100 +- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 46 ++ clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 76 +--- clang/test/Modules/cxx-templates.cpp | 8 +- clang/test/Modules/odr_hash.cpp | 4 +- 9 files changed, 255 insertions(+), 76 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 5b6a6b40b28ef..d76c293706369 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -729,6 +732,26 @@ class RedeclarableTemplateDecl : public TemplateDecl, } void anchor() override; + struct LazySpecializationInfo { +GlobalDeclID DeclID = GlobalDeclID(); +unsigned ODRHash = ~0U; +bool IsPartial = false; +LazySpecializationInfo(GlobalDeclID 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 struct SpecEntryTraits { using DeclType = EntryType; @@ -769,7 +792,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -796,7 +824,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -GlobalDeclID *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2279,7 +2307,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { @@ -3023,7 +3051,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { friend class ASTDeclWriter; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 722c7fcf0b0df..021454c770741 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -20,6 +20,8 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" +#include "clang/AST/ODRHash.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -331,17 +333,46 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c return Common; } -void RedeclarableTemplateDecl::loadLazySpecializationsIm