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/Lex/IdentifierTable.cpp b/Lex/IdentifierTable.cpp
index de68435..9a03d3f 100644
--- a/Lex/IdentifierTable.cpp
+++ b/Lex/IdentifierTable.cpp
@@ -33,27 +33,33 @@
   return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword;
 }
 
-char *SelectorInfo::getName(llvm::SmallVectorImpl<char> &methodName) {
-  int len=0;
+char *MultiKeywordSelector::getName(llvm::SmallVectorImpl<char> &methodName) {
   methodName[0] = '\0';
-  if (NumArgs) {
-    keyword_iterator KeyIter = keyword_begin();
-    for (unsigned int i = 0; i < NumArgs; i++) {
-      if (KeyIter[i]) {
-        unsigned KeyLen = strlen(KeyIter[i]->getName());
-        methodName.append(KeyIter[i]->getName(), KeyIter[i]->getName()+KeyLen);
-        len += KeyLen;
-      }
-      methodName.push_back(':');
-      len++;
+  keyword_iterator KeyIter = keyword_begin();
+  for (unsigned int i = 0; i < NumArgs; i++) {
+    if (KeyIter[i]) {
+      unsigned KeyLen = strlen(KeyIter[i]->getName());
+      methodName.append(KeyIter[i]->getName(), KeyIter[i]->getName()+KeyLen);
     }
-  } else {
-    IdentifierInfo **UnaryInfo = reinterpret_cast<IdentifierInfo **>(this+1);
-    unsigned NameLen = strlen(UnaryInfo[0]->getName());
-    methodName.append(UnaryInfo[0]->getName(), UnaryInfo[0]->getName()+NameLen);
-    len += NameLen;
+    methodName.push_back(':');
   }
-  methodName[len] = '\0';
+  methodName.push_back('\0');
+  return &methodName[0];
+}
+
+char *Selector::getName(llvm::SmallVectorImpl<char> &methodName) {
+  methodName[0] = '\0';
+  IdentifierInfo *II = getAsIdentifierInfo();
+  if (II) {
+    unsigned NameLen = strlen(II->getName());
+    methodName.append(II->getName(), II->getName()+NameLen);
+    if (getNumArgs() == 1)
+      methodName.push_back(':');
+    methodName.push_back('\0');
+  } else { // We have a multiple keyword selector (no embedded flags).
+    MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+    SI->getName(methodName);
+  }
   return &methodName[0];
 }