rmaz created this revision. rmaz requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This diff will de-duplicate methods read from AST files before inserting them in to a global method pool list. When reading ObjCMethodDecl from AST files we can end up with a significant amount of duplication when modules contain redeclarations of system framework methods. For instance a common pattern is to redeclare `-(instancetype)init` with `NS_UNAVAILABLE`, which results in the entire ObjCMethodList for `init` being serialized in each module with this redeclaration. Measuring this against our codebase for files that use `-fmodules` shows an overall 19% compile time improvement, and in some cases as much as 79% for files with a lot of modular dependencies. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D109632 Files: clang/lib/Serialization/ASTReader.cpp Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -8181,8 +8181,18 @@ /// Add the given set of methods to the method list. static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods, ObjCMethodList &List) { - for (unsigned I = 0, N = Methods.size(); I != N; ++I) { - S.addMethodToGlobalList(&List, Methods[I]); + // Methods from visited modules can contain a lot of duplicates + // when redeclaring methods from system frameworks, for example + // when marking -(instancetype)init as NS_UNAVAILABLE. + llvm::DenseSet<ObjCMethodDecl *> seen; + for (auto *L = &List; L; L = L->getNext()) { + seen.insert(L->getMethod()); + } + + for (auto *M : Methods) { + if (seen.insert(M).second) { + S.addMethodToGlobalList(&List, M); + } } }
Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -8181,8 +8181,18 @@ /// Add the given set of methods to the method list. static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods, ObjCMethodList &List) { - for (unsigned I = 0, N = Methods.size(); I != N; ++I) { - S.addMethodToGlobalList(&List, Methods[I]); + // Methods from visited modules can contain a lot of duplicates + // when redeclaring methods from system frameworks, for example + // when marking -(instancetype)init as NS_UNAVAILABLE. + llvm::DenseSet<ObjCMethodDecl *> seen; + for (auto *L = &List; L; L = L->getNext()) { + seen.insert(L->getMethod()); + } + + for (auto *M : Methods) { + if (seen.insert(M).second) { + S.addMethodToGlobalList(&List, M); + } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits