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