[cfe-commits] r62675 - in /cfe/trunk: include/clang/Basic/IdentifierTable.h lib/Basic/IdentifierTable.cpp lib/Lex/Lexer.cpp lib/Lex/PTHLexer.cpp lib/Lex/Preprocessor.cpp lib/Lex/TokenLexer.cpp

Chris Lattner sabre at nondot.org
Tue Jan 20 23:43:11 PST 2009


Author: lattner
Date: Wed Jan 21 01:43:11 2009
New Revision: 62675

URL: http://llvm.org/viewvc/llvm-project?rev=62675&view=rev
Log:
Add a bit to IdentifierInfo that acts as a simple predicate which
tells us whether Preprocessor::HandleIdentifier needs to be called.
Because this method is only rarely needed, this saves a call and a
bunch of random checks.  This drops the time in HandleIdentifier 
from 3.52ms to .98ms on cocoa.h on my machine.


Modified:
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/lib/Basic/IdentifierTable.cpp
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Lex/PTHLexer.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/lib/Lex/TokenLexer.cpp

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=62675&r1=62674&r2=62675&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Wed Jan 21 01:43:11 2009
@@ -57,7 +57,8 @@
   bool IsExtension            : 1; // True if identifier is a lang extension.
   bool IsPoisoned             : 1; // True if identifier is poisoned.
   bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
-  // 9 bits left in 32-bit word.
+  bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
+  // 8 bits left in 32-bit word.
   void *FETokenInfo;               // Managed by the language front-end.
   llvm::StringMapEntry<IdentifierInfo*> *Entry;
   
@@ -107,13 +108,28 @@
   bool hasMacroDefinition() const {
     return HasMacro;
   }
-  void setHasMacroDefinition(bool Val) { HasMacro = Val; }
+  void setHasMacroDefinition(bool Val) {
+    if (HasMacro == Val) return;
+    
+    HasMacro = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
   
   /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
   /// can be used to cause the lexer to map identifiers to source-language
   /// tokens.
   tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
-  void setTokenID(tok::TokenKind ID) { TokenID = ID; }
+  void setTokenID(tok::TokenKind ID) {
+    TokenID = ID;
+  
+    if (ID != tok::identifier)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
   
   /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
   /// For example, "define" will return tok::pp_define.
@@ -149,19 +165,36 @@
   /// language token is an extension.  This controls extension warnings, and is
   /// only valid if a custom token ID is set.
   bool isExtensionToken() const { return IsExtension; }
-  void setIsExtensionToken(bool Val) { IsExtension = Val; }
+  void setIsExtensionToken(bool Val) {
+    IsExtension = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
   
   /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
   /// Preprocessor will emit an error every time this token is used.
-  void setIsPoisoned(bool Value = true) { IsPoisoned = Value; }
+  void setIsPoisoned(bool Value = true) {
+    IsPoisoned = Value;
+    if (Value)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
   
   /// isPoisoned - Return true if this token has been poisoned.
   bool isPoisoned() const { return IsPoisoned; }
   
   /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
   /// this identifier is a C++ alternate representation of an operator.
-  void setIsCPlusPlusOperatorKeyword(bool Val = true)
-    { IsCPPOperatorKeyword = Val; }
+  void setIsCPlusPlusOperatorKeyword(bool Val = true) {
+    IsCPPOperatorKeyword = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
   bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
 
   /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
@@ -169,12 +202,31 @@
   template<typename T>
   T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
   void setFETokenInfo(void *T) { FETokenInfo = T; }
+
+  /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier
+  /// must be called on a token of this identifier.  If this returns false, we
+  /// know that HandleIdentifier will not affect the token.
+  bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
   
   /// Emit - Serialize this IdentifierInfo to a bitstream.
   void Emit(llvm::Serializer& S) const;
   
   /// Read - Deserialize an IdentifierInfo object from a bitstream.
   void Read(llvm::Deserializer& D);  
+  
+private:
+  /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
+  /// several special (but rare) things to identifiers of various sorts.  For
+  /// example, it changes the "for" keyword token from tok::identifier to
+  /// tok::for.
+  ///
+  /// This method is very tied to the definition of HandleIdentifier.  Any
+  /// change to it should be reflected here.
+  void RecomputeNeedsHandleIdentifier() {
+    NeedsHandleIdentifier =
+      (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
+       isExtensionToken()) || getTokenID() != tok::identifier;
+  }
 };
 
 /// IdentifierInfoLookup - An abstract class used by IdentifierTable that

Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=62675&r1=62674&r2=62675&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Wed Jan 21 01:43:11 2009
@@ -32,6 +32,7 @@
   IsExtension = false;
   IsPoisoned = false;
   IsCPPOperatorKeyword = false;
+  NeedsHandleIdentifier = false;
   FETokenInfo = 0;
   Entry = 0;
 }

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=62675&r1=62674&r2=62675&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Wed Jan 21 01:43:11 2009
@@ -560,7 +560,9 @@
     
     // Finally, now that we know we have an identifier, pass this off to the
     // preprocessor, which may macro expand it or something.
-    return PP->HandleIdentifier(Result);
+    if (Result.getIdentifierInfo()->isHandleIdentifierCase())
+      PP->HandleIdentifier(Result);
+    return;
   }
   
   // Otherwise, $,\,? in identifier found.  Enter slower path.

Modified: cfe/trunk/lib/Lex/PTHLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PTHLexer.cpp?rev=62675&r1=62674&r2=62675&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PTHLexer.cpp (original)
+++ cfe/trunk/lib/Lex/PTHLexer.cpp Wed Jan 21 01:43:11 2009
@@ -143,7 +143,9 @@
 
   if (TKind == tok::identifier) {
     MIOpt.ReadToken();
-    return PP->HandleIdentifier(Tok);
+    if (Tok.getIdentifierInfo()->isHandleIdentifierCase())
+      PP->HandleIdentifier(Tok);
+    return;
   }
   
   if (TKind == tok::eof) {

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=62675&r1=62674&r2=62675&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Wed Jan 21 01:43:11 2009
@@ -718,6 +718,11 @@
 /// HandleIdentifier - This callback is invoked when the lexer reads an
 /// identifier.  This callback looks up the identifier in the map and/or
 /// potentially macro expands it or turns it into a named token (like 'for').
+///
+/// Note that callers of this method are guarded by checking the
+/// IdentifierInfo's 'isHandleIdentifierCase' bit.  If this method changes, the
+/// IdentifierInfo methods that compute these properties will need to change to
+/// match.
 void Preprocessor::HandleIdentifier(Token &Identifier) {
   assert(Identifier.getIdentifierInfo() &&
          "Can't handle identifiers without identifier info!");

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=62675&r1=62674&r2=62675&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Wed Jan 21 01:43:11 2009
@@ -326,8 +326,9 @@
   }
   
   // Handle recursive expansion!
-  if (Tok.getIdentifierInfo() && !DisableMacroExpansion)
-    return PP.HandleIdentifier(Tok);
+  if (Tok.getIdentifierInfo() && !DisableMacroExpansion &&
+      Tok.getIdentifierInfo()->isHandleIdentifierCase())
+    PP.HandleIdentifier(Tok);
 
   // Otherwise, return a normal token.
 }





More information about the cfe-commits mailing list