Yesterday I discovered that 78% of all selectors in "Cocoa.h" take 0/1 argument.

This motivated implementing a devious clattner inspired solution:-)

This approach uses a small value "Selector" class to point to an IdentifierInfo for the 0/1 case. For multi-keyword selectors, we instantiate a MultiKeywordSelector object (previously known as SelectorInfo). Now, the incremental cost for selectors is only 24,800 for Cocoa.h! This saves 156,592 bytes, or 86%!! The size reduction is also the result of getting rid of the AST slot, which was not strictly necessary (we will associate a selector with it's method using another table...most likely in Sema).

This change was critical to make now, before we have too many clients.

I still need to add some comments to the Selector class...will likely add later today/tomorrow.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42452 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 45762ac..28682cc 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1178,23 +1178,23 @@
 /// Declared in protocol, and those referenced by it.
 ///
 static void CheckProtocolMethodDefs(Sema* objSema, ObjcProtocolDecl *PDecl,
-             const llvm::DenseMap<const SelectorInfo*, char>& InsMap,
-             const llvm::DenseMap<const SelectorInfo*, char>& ClsMap) {
+             const llvm::DenseMap<void *, char>& InsMap,
+             const llvm::DenseMap<void *, char>& ClsMap) {
   // check unimplemented instance methods.
   ObjcMethodDecl** methods = PDecl->getInsMethods();
   for (int j = 0; j < PDecl->getNumInsMethods(); j++)
-    if (!InsMap.count(methods[j]->getSelector())) {
+    if (!InsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
       llvm::SmallString<128> buf;
       objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-                    methods[j]->getSelector()->getName(buf));
+                    methods[j]->getSelector().getName(buf));
     }
   // check unimplemented class methods
   methods = PDecl->getClsMethods();
   for (int j = 0; j < PDecl->getNumClsMethods(); j++)
-    if (!ClsMap.count(methods[j]->getSelector())) {
+    if (!ClsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
       llvm::SmallString<128> buf;
       objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-                    methods[j]->getSelector()->getName(buf));
+                    methods[j]->getSelector().getName(buf));
     }
   
   // Check on this protocols's referenced protocols, recursively
@@ -1206,35 +1206,35 @@
 static void ImplMethodsVsClassMethods(Sema* objSema, 
 				      ObjcImplementationDecl* IMPDecl, 
                                       ObjcInterfaceDecl* IDecl) {
-  llvm::DenseMap<const SelectorInfo*, char> InsMap;
+  llvm::DenseMap<void *, char> InsMap;
   // Check and see if instance methods in class interface have been
   // implemented in the implementation class.
   ObjcMethodDecl **methods = IMPDecl->getInsMethods();
   for (int i=0; i < IMPDecl->getNumInsMethods(); i++) {
-    InsMap[methods[i]->getSelector()] = 'a';
+    InsMap[methods[i]->getSelector().getAsOpaquePtr()] = 'a';
   }
   
   methods = IDecl->getInsMethods();
   for (int j = 0; j < IDecl->getNumInsMethods(); j++)
-    if (!InsMap.count(methods[j]->getSelector())) {
+    if (!InsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
       llvm::SmallString<128> buf;
       objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           	    methods[j]->getSelector()->getName(buf));
+           	    methods[j]->getSelector().getName(buf));
     }
-  llvm::DenseMap<const SelectorInfo*, char> ClsMap;
+  llvm::DenseMap<void *, char> ClsMap;
   // Check and see if class methods in class interface have been
   // implemented in the implementation class.
   methods = IMPDecl->getClsMethods();
   for (int i=0; i < IMPDecl->getNumClsMethods(); i++) {
-    ClsMap[methods[i]->getSelector()] = 'a';
+    ClsMap[methods[i]->getSelector().getAsOpaquePtr()] = 'a';
   }
   
   methods = IDecl->getClsMethods();
   for (int j = 0; j < IDecl->getNumClsMethods(); j++)
-    if (!ClsMap.count(methods[j]->getSelector())) {
+    if (!ClsMap.count(methods[j]->getSelector().getAsOpaquePtr())) {
       llvm::SmallString<128> buf;
       objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
-           	    methods[j]->getSelector()->getName(buf));
+           	    methods[j]->getSelector().getName(buf));
     }
   
   // Check the protocol list for unimplemented methods in the @implementation
@@ -1650,14 +1650,14 @@
 }
 
 Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
-    tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
+    tok::TokenKind MethodType, TypeTy *ReturnType, Selector Sel,
     // optional arguments. The number of types/arguments is obtained
     // from the Sel.getNumArgs().
     TypeTy **ArgTypes, IdentifierInfo **ArgNames,
     AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind) {
   llvm::SmallVector<ParmVarDecl*, 16> Params;
 
-  for (unsigned i = 0; i < Sel->getNumArgs(); i++) {
+  for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
     // FIXME: arg->AttrList must be stored too!
     ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i], 
 					 QualType::getFromOpaquePtr(ArgTypes[i]), 
@@ -1668,7 +1668,7 @@
   ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, Sel,
                                       resultDeclType, 0, -1, AttrList, 
                                       MethodType == tok::minus);
-  ObjcMethod->setMethodParams(&Params[0], Sel->getNumArgs());
+  ObjcMethod->setMethodParams(&Params[0], Sel.getNumArgs());
   if (MethodDeclKind == tok::objc_optional)
     ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
   else