@@ -555,7 +555,25 @@ namespace {
555555
556556using MacroDefinitionsMap =
557557 llvm::StringMap<std::pair<StringRef, bool /* IsUndef*/ >>;
558- using DeclsMap = llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8 >>;
558+
559+ class DeclsSet {
560+ SmallVector<NamedDecl *, 64 > Decls;
561+ llvm::SmallPtrSet<NamedDecl *, 8 > Found;
562+
563+ public:
564+ operator ArrayRef<NamedDecl*>() const { return Decls; }
565+
566+ bool empty () const { return Decls.empty (); }
567+
568+ bool insert (NamedDecl *ND) {
569+ auto [_, Inserted] = Found.insert (ND);
570+ if (Inserted)
571+ Decls.push_back (ND);
572+ return Inserted;
573+ }
574+ };
575+
576+ using DeclsMap = llvm::DenseMap<DeclarationName, DeclsSet>;
559577
560578} // namespace
561579
@@ -8702,14 +8720,22 @@ bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
87028720 return false ;
87038721
87048722 // Load the list of declarations.
8705- SmallVector<NamedDecl *, 64 > Decls;
8706- llvm::SmallPtrSet<NamedDecl *, 8 > Found;
8723+ DeclsSet DS;
87078724
87088725 auto Find = [&, this ](auto &&Table, auto &&Key) {
87098726 for (GlobalDeclID ID : Table.find (Key)) {
87108727 NamedDecl *ND = cast<NamedDecl>(GetDecl (ID));
8711- if (ND->getDeclName () == Name && Found.insert (ND).second )
8712- Decls.push_back (ND);
8728+ if (ND->getDeclName () != Name)
8729+ continue ;
8730+ // Special case for namespaces: There can be a lot of redeclarations of
8731+ // some namespaces, and we import a "key declaration" per imported module.
8732+ // Since all declarations of a namespace are essentially interchangeable,
8733+ // we can optimize namespace look-up by only storing the key declaration
8734+ // of the current TU, rather than storing N key declarations where N is
8735+ // the # of imported modules that declare that namespace.
8736+ if (isa<NamespaceDecl>(ND))
8737+ ND = cast<NamedDecl>(getKeyDeclaration (ND));
8738+ DS.insert (ND);
87138739 }
87148740 };
87158741
@@ -8744,8 +8770,8 @@ bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
87448770 Find (It->second .Table , Name);
87458771 }
87468772
8747- SetExternalVisibleDeclsForName (DC, Name, Decls );
8748- return !Decls .empty ();
8773+ SetExternalVisibleDeclsForName (DC, Name, DS );
8774+ return !DS .empty ();
87498775}
87508776
87518777void ASTReader::completeVisibleDeclsMap (const DeclContext *DC) {
@@ -8763,7 +8789,15 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
87638789
87648790 for (GlobalDeclID ID : It->second .Table .findAll ()) {
87658791 NamedDecl *ND = cast<NamedDecl>(GetDecl (ID));
8766- Decls[ND->getDeclName ()].push_back (ND);
8792+ // Special case for namespaces: There can be a lot of redeclarations of
8793+ // some namespaces, and we import a "key declaration" per imported module.
8794+ // Since all declarations of a namespace are essentially interchangeable,
8795+ // we can optimize namespace look-up by only storing the key declaration
8796+ // of the current TU, rather than storing N key declarations where N is
8797+ // the # of imported modules that declare that namespace.
8798+ if (isa<NamespaceDecl>(ND))
8799+ ND = cast<NamedDecl>(getKeyDeclaration (ND));
8800+ Decls[ND->getDeclName ()].insert (ND);
87678801 }
87688802
87698803 // FIXME: Why a PCH test is failing if we remove the iterator after findAll?
@@ -8773,9 +8807,9 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
87738807 findAll (ModuleLocalLookups, NumModuleLocalVisibleDeclContexts);
87748808 findAll (TULocalLookups, NumTULocalVisibleDeclContexts);
87758809
8776- for (DeclsMap::iterator I = Decls. begin (), E = Decls. end (); I != E; ++I) {
8777- SetExternalVisibleDeclsForName (DC, I-> first , I-> second );
8778- }
8810+ for (auto &[Name, DS] : Decls)
8811+ SetExternalVisibleDeclsForName (DC, Name, DS );
8812+
87798813 const_cast <DeclContext *>(DC)->setHasExternalVisibleStorage (false );
87808814}
87818815
0 commit comments