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
  • [PATCH] D126691: ASTContext: P... Iain Sandoe via Phabricator via cfe-commits

Reply via email to