rmaz created this revision.
rmaz requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change moves the `addMethodToGlobalList` function to be a
private member function of the `GlobalMethodPool` class. This
is a preparatory step to allow for de-duplication of inserted
methods.

Two public methods are added to handle the existing use cases
for adding methods to a global list: `addMethodsForSelector`
and `addMethod`. The former is required to avoid the overhead
of looking up the `Methods` map for each insert when adding
multiple methods for a single selector when deserializing AST
files. It also allows for modifying the list properties first.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110092

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDeclObjC.cpp
  clang/lib/Serialization/ASTReader.cpp

Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -8178,14 +8178,6 @@
 } // namespace serialization
 } // namespace clang
 
-/// 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]);
-  }
-}
-
 void ASTReader::ReadMethodPool(Selector Sel) {
   // Get the selector generation and update it to the current generation.
   unsigned &Generation = SelectorGeneration[Sel];
@@ -8208,20 +8200,12 @@
     return;
 
   Sema &S = *getSema();
-  Sema::GlobalMethodPool::iterator Pos =
-      S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethodPool::Lists()))
-          .first;
-
-  Pos->second.first.setBits(Visitor.getInstanceBits());
-  Pos->second.first.setHasMoreThanOneDecl(Visitor.instanceHasMoreThanOneDecl());
-  Pos->second.second.setBits(Visitor.getFactoryBits());
-  Pos->second.second.setHasMoreThanOneDecl(Visitor.factoryHasMoreThanOneDecl());
-
-  // Add methods to the global pool *after* setting hasMoreThanOneDecl, since
-  // when building a module we keep every method individually and may need to
-  // update hasMoreThanOneDecl as we add the methods.
-  addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first);
-  addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);
+  S.MethodPool.addMethodsForSelector(Sel, Visitor.getInstanceMethods(), true,
+                                     Visitor.getInstanceBits(),
+                                     Visitor.instanceHasMoreThanOneDecl());
+  S.MethodPool.addMethodsForSelector(Sel, Visitor.getFactoryMethods(), false,
+                                     Visitor.getFactoryBits(),
+                                     Visitor.factoryHasMoreThanOneDecl());
 }
 
 void ASTReader::updateOutOfDateSelector(Selector Sel) {
Index: clang/lib/Sema/SemaDeclObjC.cpp
===================================================================
--- clang/lib/Sema/SemaDeclObjC.cpp
+++ clang/lib/Sema/SemaDeclObjC.cpp
@@ -3300,8 +3300,8 @@
   return MethodInterface == MethodInListInterface;
 }
 
-void Sema::addMethodToGlobalList(ObjCMethodList *List,
-                                 ObjCMethodDecl *Method) {
+void Sema::GlobalMethodPool::addMethodToGlobalList(ObjCMethodList *List,
+                                                   ObjCMethodDecl *Method) {
   // Record at the head of the list whether there were 0, 1, or >= 2 methods
   // inside categories.
   if (ObjCCategoryDecl *CD =
@@ -3322,11 +3322,11 @@
   ObjCMethodList *ListWithSameDeclaration = nullptr;
   for (; List; Previous = List, List = List->getNext()) {
     // If we are building a module, keep all of the methods.
-    if (getLangOpts().isCompilingModule())
+    if (SemaRef.getLangOpts().isCompilingModule())
       continue;
 
-    bool SameDeclaration = MatchTwoMethodDeclarations(Method,
-                                                      List->getMethod());
+    bool SameDeclaration =
+        SemaRef.MatchTwoMethodDeclarations(Method, List->getMethod());
     // Looking for method with a type bound requires the correct context exists.
     // We need to insert a method into the list if the context is different.
     // If the method's declaration matches the list
@@ -3389,7 +3389,7 @@
 
   // We have a new signature for an existing method - add it.
   // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
-  ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
+  ObjCMethodList *Mem = SemaRef.BumpAlloc.Allocate<ObjCMethodList>();
 
   // We insert it right before ListWithSameDeclaration.
   if (ListWithSameDeclaration) {
@@ -3425,17 +3425,9 @@
   if (ExternalSource)
     ReadMethodPool(Method->getSelector());
 
-  GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
-  if (Pos == MethodPool.end())
-    Pos = MethodPool
-              .insert(std::make_pair(Method->getSelector(),
-                                     GlobalMethodPool::Lists()))
-              .first;
-
   Method->setDefined(impl);
-
-  ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
-  addMethodToGlobalList(&Entry, Method);
+  assert(Method->isInstanceMethod() == instance);
+  MethodPool.addMethod(Method);
 }
 
 /// Determines if this is an "acceptable" loose mismatch in the global
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -196,7 +196,7 @@
       ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),
       ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),
       DictionaryWithObjectsMethod(nullptr), GlobalNewDeleteDeclared(false),
-      TUKind(TUKind), NumSFINAEErrors(0),
+      TUKind(TUKind), NumSFINAEErrors(0), MethodPool(*this),
       FullyCheckedComparisonCategories(
           static_cast<unsigned>(ComparisonCategoryType::Last) + 1),
       SatisfactionCache(Context), AccessCheckingSFINAE(false),
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1421,19 +1421,51 @@
 
   class GlobalMethodPool {
   public:
+    GlobalMethodPool(Sema &S) : SemaRef(S) {}
+    GlobalMethodPool() = delete;
     using Lists = std::pair<ObjCMethodList, ObjCMethodList>;
     using iterator = llvm::DenseMap<Selector, Lists>::iterator;
     iterator begin() { return Methods.begin(); }
     iterator end() { return Methods.end(); }
     iterator find(Selector Sel) { return Methods.find(Sel); }
-    std::pair<iterator, bool> insert(std::pair<Selector, Lists> &&Val) {
-      return Methods.insert(Val);
-    }
     int count(Selector Sel) const { return Methods.count(Sel); }
     bool empty() const { return Methods.empty(); }
 
+    void addMethodsForSelector(Selector Sel, ArrayRef<ObjCMethodDecl *> Decls,
+                               bool Instance, unsigned Bits,
+                               bool HasMoreThanOneDecl) {
+      if (Decls.empty())
+        return;
+
+      auto Pos = Methods.insert(std::make_pair(Sel, Lists())).first;
+      auto &List = Instance ? Pos->second.first : Pos->second.second;
+      List.setBits(Bits);
+      List.setHasMoreThanOneDecl(HasMoreThanOneDecl);
+
+      // Add methods to the global list *after* setting hasMoreThanOneDecl,
+      // since when building a module we keep every method individually and may
+      // need to update hasMoreThanOneDecl as we add the methods.
+      for (auto *D : Decls) {
+        addMethodToGlobalList(&List, D);
+      }
+    }
+
+    void addMethod(ObjCMethodDecl *Method) {
+      auto Pos = Methods.find(Method->getSelector());
+      if (Pos == Methods.end()) {
+        Pos = Methods.insert(std::make_pair(Method->getSelector(), Lists()))
+                  .first;
+      }
+
+      auto &List =
+          Method->isInstanceMethod() ? Pos->second.first : Pos->second.second;
+      addMethodToGlobalList(&List, Method);
+    }
+
   private:
+    Sema &SemaRef;
     llvm::DenseMap<Selector, Lists> Methods;
+    void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
   };
 
   /// Method Pool - allows efficient lookup when typechecking messages to "id".
@@ -4505,9 +4537,6 @@
   /// warns each time an exact match is found.
   void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP);
 
-  /// Add the given method to the list of globally-known methods.
-  void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
-
   /// Returns default addr space for method qualifiers.
   LangAS getDefaultCXXMethodAddrSpace() const;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D110092: [clang][NF... Richard Howell via Phabricator via cfe-commits

Reply via email to