[cfe-commits] r42452 - in /cfe/trunk: AST/Expr.cpp Lex/IdentifierTable.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/AST/ASTContext.h include/clang/AST/Decl.h include/clang/AST/Expr.h include/clang/Lex/IdentifierTable.h include/clang/Lex/Preprocessor.h include/clang/Parse/Action.h include/clang/Parse/Parser.h

Steve Naroff snaroff at apple.com
Fri Oct 5 11:46:30 PDT 2007


With the exception of DenseMap, Commit 42643 should address all of  
your issues below (thanks for the feedback).

I will make the DenseMap change separately.

snaroff

On Oct 3, 2007, at 10:42 PM, Chris Lattner wrote:

> On Sep 28, 2007, at 3:22 PM, Steve Naroff wrote:
>> Author: snaroff
>> Date: Fri Sep 28 17:22:11 2007
>> New Revision: 42452
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=42452&view=rev
>> Log:
>>
>> 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).
>
> Very nice Steve!  Some comments:
>
>> ===================================================================== 
>> =========
>> --- cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
>> +++ cfe/trunk/include/clang/Lex/IdentifierTable.h Fri Sep 28  
>> 17:22:11 2007
>> @@ -170,28 +170,24 @@
>>    void AddKeywords(const LangOptions &LangOpts);
>>  };
>>
>> +/// MultiKeywordSelector - One of these variable length records  
>> is kept for each
>> +/// parsed selector (similar in spirit to IdentifierInfo). We use  
>> a folding set
>> +/// to unique aggregate names (keyword selectors in ObjC parlance).
>> +class MultiKeywordSelector : public llvm::FoldingSetNode {
>
> I don't think there is any reason to export the definition of  
> MultiKeywordSelector in the header file.  Can you make it just  
> forward-declared here and suck the definition/implementation into  
> IdentifierTable.cpp?  Clients should never interact with  
> MultiKeywordSelector, they should only interact with Selector.
>
> Ahh, I see you added this later:
> /// The only reason it appears in this header is FoldingSet needs  
> to see it:-(
>
> Presumably this is because Preprocessor contains:
>   /// Selectors - This table contains all the selectors in the  
> program. Unlike
>   /// IdentifierTable above, this table *isn't* populated by the  
> preprocessor.
>   /// It is declared/instantiated here because it's role/lifetime is
>   /// conceptually similar the IdentifierTable. In addition, the  
> current control
>   /// flow (in clang::ParseAST()), make it convenient to put here.
>   /// FIXME: Make sure the lifetime of Identifiers/Selectors  
> *isn't* tied to
>   /// the lifetime fo the preprocessor.
>   llvm::FoldingSet<MultiKeywordSelector> Selectors;
>
> This declaration is unfortunate for two reasons:
> 1. it requires MultiKeywordSelector to be exported out of  
> IdentifierTable.cpp, and
> 2. it requires preprocessor and IdentifierTable.h to #include  
> FoldingSet.h
>
> Instead of doing this, I'd suggest adding the following to  
> IdentifierTable.h:
>
> class SelectorUniquingTable {
>   void *Impl;  // Actually a FoldingSet<MultiKeywordSelector>*
>   SelectorUniquingTable(const SelectorUniquingTable&); // DISABLED:  
> DO NOT IMPLEMENT
>   void operator=(const SelectorUniquingTable&); // DISABLED: DO NOT  
> IMPLEMENT
> public:
>   SelectorUniquingTable();  // new's the foldingset
>   ~SelectorUniquingTable();  // delete's the foldingset
>
>   Selector getSelector(unsigned nKeys, IdentifierInfo **IIV);
>   Selector getUnarySelector(IdentifierInfo *ID);
>   Selector getNullarySelector(IdentifierInfo *ID);
> };
>
> With this definition, Parser can contain an instance of  
> SelectorUniquingTable instead of a folding set, getting rid of the  
> #include of FoldingSet.h and allowing MultiKeywordSelector to  
> become private to the .cpp file.
>
> Another benefit is that stuff like this (from Selector and  
> MultiKeywordSelector):
>> +  friend class Parser; // only the Parser can create these.
>
> can now befriend the SelectorUniquingTable class instead, fixing a  
> layering problem (because ideally IdentifierTable will sink into  
> libbasic).
>
>
>> +  IdentifierInfo *getIdentifierInfoForSlot(unsigned i) {
>> +    assert((i < NumArgs) && "getIdentifierInfoForSlot(): illegal  
>> index");
>> +    return keyword_begin()[i];
>> +  }
>
> This method should be const.
>
> +  friend class llvm::FoldingSet<MultiKeywordSelector>;
>
> This can go away when it is in the .cpp file, because all the  
> access can be public.
>
>> +class Selector {
>
> The selector class needs a comment above it.
>
>> +  // Derive the full selector name, placing the result into  
>> methodBuffer.
>> +  // As a convenience, a pointer to the first character is returned.
>> +  // Example usage: llvm::SmallString<128> mbuf; Selector->getName 
>> (mbuf);
>> +  char *getName(llvm::SmallVectorImpl<char> &methodBuffer);
>
> Why is this implemented in ParseObjc.cpp?  It seems like it should  
> be in IdentifierTable.cpp.
>
>>
>> Modified: cfe/trunk/Sema/SemaDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/ 
>> SemaDecl.cpp?rev=42452&r1=42451&r2=42452&view=diff
>>
>> ===================================================================== 
>> =========
>> --- cfe/trunk/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/Sema/SemaDecl.cpp Fri Sep 28 17:22:11 2007
>>
>> @@ -1206,35 +1206,35 @@
>>  static void ImplMethodsVsClassMethods(Sema* objSema,
>>  				      ObjcImplementationDecl* IMPDecl,
>>                                        ObjcInterfaceDecl* IDecl) {
>> -  llvm::DenseMap<const SelectorInfo*, char> InsMap;
>> +  llvm::DenseMap<void *, char> InsMap;
>
> Since this code was written, a new llvm::DenseSet was added.  You  
> should be able to switch this to use DenseSet, which makes it more  
> obvious what you're doing here.
>
> Also, instead of using .getAsOpaquePtr(), I think it would make  
> sense to teach the hash table how to handle Selectors.  It seems  
> useful to other people and can be added easily to IdentifierInfo.h.
>
>> ===================================================================== 
>> =========
>> --- cfe/trunk/include/clang/AST/Expr.h (original)
>> +++ cfe/trunk/include/clang/AST/Expr.h Fri Sep 28 17:22:11 2007
>> @@ -1100,12 +1101,17 @@
>>    Expr *getReceiver() { return SubExprs[RECEIVER]; }
>>
>>    /// getNumArgs - Return the number of actual arguments to this  
>> call.
>> +  unsigned getNumArgs() const { return SelName.getNumArgs(); }
>> +
>> +/// getArg - Return the specified argument.
>> +  Expr *getArg(unsigned Arg) {
>> +    assert(Arg < SelName.getNumArgs() && "Arg access out of  
>> range!");
>> +    return SubExprs[Arg+ARGS_START];
>> +  }
>
> Funky comment indentation.
>
> Overall, huge leap forward!
>
> -Chris
>




More information about the cfe-commits mailing list