[cfe-commits] r155958 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp

Douglas Gregor dgregor at apple.com
Tue May 1 16:07:34 PDT 2012


Author: dgregor
Date: Tue May  1 18:07:34 2012
New Revision: 155958

URL: http://llvm.org/viewvc/llvm-project?rev=155958&view=rev
Log:
The semantic checking that verifies whether an Objective-C method
declared in a subclass has consistent parameter types with a method
having the same selector in a superclass performs a significant number
of lookups into the class hierarchy. In the example in
<rdar://problem/11004361>, we spend 4.7% of -fsyntax-only time in
these lookups.

Optimize away most of the calls to this routine
(Sema::CompareMethodParamsInBaseAndSuper) by first checking whether we
have ever seen *any* method with that selector (using the global
selector table). Since most selectors are unique, we can avoid the
cost of this name lookup in many cases, for a 3.3% speedup.


Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=155958&r1=155957&r2=155958&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue May  1 18:07:34 2012
@@ -2130,12 +2130,15 @@
   void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP);
 
   /// \brief Add the given method to the list of globally-known methods.
-  void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
+  ///
+  /// \returns true if this is the first method in the list with the given
+  /// selector.
+  bool addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
   
 private:
   /// AddMethodToGlobalPool - Add an instance or factory method to the global
   /// pool. See descriptoin of AddInstanceMethodToGlobalPool.
-  void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance);
+  bool AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance);
 
   /// LookupMethodInGlobalPool - Returns the instance or factory method and
   /// optionally warns if there are multiple signatures.
@@ -2148,13 +2151,17 @@
   /// unit are added to a global pool. This allows us to efficiently associate
   /// a selector with a method declaraation for purposes of typechecking
   /// messages sent to "id" (where the class of the object is unknown).
-  void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
-    AddMethodToGlobalPool(Method, impl, /*instance*/true);
+  ///
+  /// Returns true if the method was added, false if a method was already there.
+  bool AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
+    return AddMethodToGlobalPool(Method, impl, /*instance*/true);
   }
 
   /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
-  void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
-    AddMethodToGlobalPool(Method, impl, /*instance*/false);
+  ///
+  /// Returns true if the method was added, false if a method was already there.
+  bool AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
+    return AddMethodToGlobalPool(Method, impl, /*instance*/false);
   }
 
   /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=155958&r1=155957&r2=155958&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue May  1 18:07:34 2012
@@ -1970,12 +1970,12 @@
   return true;
 }
 
-void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) {
+bool Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) {
   // If the list is empty, make it a singleton list.
   if (List->Method == 0) {
     List->Method = Method;
     List->Next = 0;
-    return;
+    return true;
   }
   
   // We've seen a method with this name, see if we have already seen this type
@@ -2004,13 +2004,14 @@
         List->Method = Method;
     }
     
-    return;
+    return false;
   }
   
   // 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>();
   Previous->Next = new (Mem) ObjCMethodList(Method, 0);
+  return false;
 }
 
 /// \brief Read the contents of the method pool for a given selector from
@@ -2020,11 +2021,11 @@
   ExternalSource->ReadMethodPool(Sel);
 }
 
-void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
+bool Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
                                  bool instance) {
   // Ignore methods of invalid containers.
   if (cast<Decl>(Method->getDeclContext())->isInvalidDecl())
-    return;
+    return false;
 
   if (ExternalSource)
     ReadMethodPool(Method->getSelector());
@@ -2037,7 +2038,7 @@
   Method->setDefined(impl);
   
   ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
-  addMethodToGlobalList(&Entry, Method);
+  return addMethodToGlobalList(&Entry, Method);
 }
 
 /// Determines if this is an "acceptable" loose mismatch in the global
@@ -2272,10 +2273,11 @@
         }
         InsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "id".
-        AddInstanceMethodToGlobalPool(Method);
-        // verify that the instance method conforms to the same definition of
-        // parent methods if it shadows one.
-        CompareMethodParamsInBaseAndSuper(ClassDecl, Method, true);
+        if (!AddInstanceMethodToGlobalPool(Method)) {
+          // verify that the instance method conforms to the same definition of
+          // parent methods if it shadows one.
+          CompareMethodParamsInBaseAndSuper(ClassDecl, Method, true);
+        }
       }
     } else {
       /// Check for class method of the same name with incompatible types
@@ -2299,10 +2301,11 @@
         }
         ClsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "Class".
-        AddFactoryMethodToGlobalPool(Method);
-        // verify that the class method conforms to the same definition of
-        // parent methods if it shadows one.
-        CompareMethodParamsInBaseAndSuper(ClassDecl, Method, false);
+        if (!AddFactoryMethodToGlobalPool(Method)) {
+          // verify that the class method conforms to the same definition of
+          // parent methods if it shadows one.
+          CompareMethodParamsInBaseAndSuper(ClassDecl, Method, false);
+        }
       }
     }
   }





More information about the cfe-commits mailing list