iains created this revision. Herald added a project: All. iains added reviewers: urnathan, ChuanqiXu. iains published this revision for review. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When deciding if a global module fragement decl is unused, we have to account for the case that it is emitted as part of the module initializer. In order to make this more efficient, modify the container used to cache the module intializer decls. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D126691 Files: clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -1148,7 +1148,7 @@ LazyInitializers.clear(); for (auto ID : LazyInits) - Initializers.push_back(Source->GetExternalDecl(ID)); + Initializers.insert(Source->GetExternalDecl(ID)); assert(LazyInitializers.empty() && "GetExternalDecl for lazy module initializer added more inits"); @@ -1177,7 +1177,7 @@ auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; - Inits->Initializers.push_back(D); + Inits->Initializers.insert(D); } void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs) { @@ -1195,7 +1195,17 @@ auto *Inits = It->second; Inits->resolve(*this); - return Inits->Initializers; + return Inits->Initializers.getArrayRef(); +} + +bool ASTContext::moduleInitializerContains(Module *M, const Decl *D) { + auto It = ModuleInitializers.find(M); + if (It == ModuleInitializers.end()) + return false; + + auto *Inits = It->second; + Inits->resolve(*this); + return Inits->Initializers.contains(const_cast<Decl *>(D)); } ExternCContextDecl *ASTContext::getExternCContextDecl() const { Index: clang/include/clang/AST/ASTContext.h =================================================================== --- clang/include/clang/AST/ASTContext.h +++ clang/include/clang/AST/ASTContext.h @@ -53,6 +53,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -465,7 +466,7 @@ /// a non-constant initializer), or an ImportDecl (which recursively triggers /// initialization of another module). struct PerModuleInitializers { - llvm::SmallVector<Decl*, 4> Initializers; + llvm::SmallSetVector<Decl *, 4> Initializers; llvm::SmallVector<uint32_t, 4> LazyInitializers; void resolve(ASTContext &Ctx); @@ -1078,6 +1079,9 @@ /// Get the initializations to perform when importing a module, if any. ArrayRef<Decl*> getModuleInitializers(Module *M); + /// Does the module initializer array contain this decl. + bool moduleInitializerContains(Module *M, const Decl *D); + /// Set the (C++20) module we are building. void setModuleForCodeGen(Module *M) { TopLevelModule = M; }
Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -1148,7 +1148,7 @@ LazyInitializers.clear(); for (auto ID : LazyInits) - Initializers.push_back(Source->GetExternalDecl(ID)); + Initializers.insert(Source->GetExternalDecl(ID)); assert(LazyInitializers.empty() && "GetExternalDecl for lazy module initializer added more inits"); @@ -1177,7 +1177,7 @@ auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; - Inits->Initializers.push_back(D); + Inits->Initializers.insert(D); } void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs) { @@ -1195,7 +1195,17 @@ auto *Inits = It->second; Inits->resolve(*this); - return Inits->Initializers; + return Inits->Initializers.getArrayRef(); +} + +bool ASTContext::moduleInitializerContains(Module *M, const Decl *D) { + auto It = ModuleInitializers.find(M); + if (It == ModuleInitializers.end()) + return false; + + auto *Inits = It->second; + Inits->resolve(*this); + return Inits->Initializers.contains(const_cast<Decl *>(D)); } ExternCContextDecl *ASTContext::getExternCContextDecl() const { Index: clang/include/clang/AST/ASTContext.h =================================================================== --- clang/include/clang/AST/ASTContext.h +++ clang/include/clang/AST/ASTContext.h @@ -53,6 +53,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -465,7 +466,7 @@ /// a non-constant initializer), or an ImportDecl (which recursively triggers /// initialization of another module). struct PerModuleInitializers { - llvm::SmallVector<Decl*, 4> Initializers; + llvm::SmallSetVector<Decl *, 4> Initializers; llvm::SmallVector<uint32_t, 4> LazyInitializers; void resolve(ASTContext &Ctx); @@ -1078,6 +1079,9 @@ /// Get the initializations to perform when importing a module, if any. ArrayRef<Decl*> getModuleInitializers(Module *M); + /// Does the module initializer array contain this decl. + bool moduleInitializerContains(Module *M, const Decl *D); + /// Set the (C++20) module we are building. void setModuleForCodeGen(Module *M) { TopLevelModule = M; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits