[cfe-commits] r39864 - in /cfe/trunk: Lex/MacroExpander.cpp Lex/Preprocessor.cpp include/clang/Lex/MacroExpander.h include/clang/Lex/Preprocessor.h

Chris Lattner sabre at nondot.org
Sat Jul 14 17:25:26 PDT 2007


Author: lattner
Date: Sat Jul 14 19:25:26 2007
New Revision: 39864

URL: http://llvm.org/viewvc/llvm-project?rev=39864&view=rev
Log:
Cache macro expander objects to avoid thrashing malloc in heavy expansion situations.
This doesn't significantly improve carbon.h, but it does speed up
INPUTS/macro_pounder_obj.c by 48%


Modified:
    cfe/trunk/Lex/MacroExpander.cpp
    cfe/trunk/Lex/Preprocessor.cpp
    cfe/trunk/include/clang/Lex/MacroExpander.h
    cfe/trunk/include/clang/Lex/Preprocessor.h

Modified: cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/MacroExpander.cpp?rev=39864&r1=39863&r2=39864&view=diff

==============================================================================
--- cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/trunk/Lex/MacroExpander.cpp Sat Jul 14 19:25:26 2007
@@ -233,13 +233,17 @@
 
 /// Create a macro expander for the specified macro with the specified actual
 /// arguments.  Note that this ctor takes ownership of the ActualArgs pointer.
-MacroExpander::MacroExpander(LexerToken &Tok, MacroArgs *Actuals,
-                             Preprocessor &pp)
-  : Macro(Tok.getIdentifierInfo()->getMacroInfo()),
-    ActualArgs(Actuals), PP(pp), CurToken(0),
-    InstantiateLoc(Tok.getLocation()),
-    AtStartOfLine(Tok.isAtStartOfLine()),
-    HasLeadingSpace(Tok.hasLeadingSpace()) {
+void MacroExpander::Init(LexerToken &Tok, MacroArgs *Actuals) {
+  // If the client is reusing a macro expander, make sure to free any memory
+  // associated with it.
+  destroy();
+  
+  Macro = Tok.getIdentifierInfo()->getMacroInfo();
+  ActualArgs = Actuals;
+  CurToken = 0;
+  InstantiateLoc = Tok.getLocation();
+  AtStartOfLine = Tok.isAtStartOfLine();
+  HasLeadingSpace = Tok.hasLeadingSpace();
   MacroTokens = &*Macro->tokens_begin();
   NumMacroTokens = Macro->tokens_end()-Macro->tokens_begin();
 
@@ -254,14 +258,23 @@
   Macro->DisableMacro();
 }
 
+
+
 /// Create a macro expander for the specified token stream.  This does not
 /// take ownership of the specified token vector.
-MacroExpander::MacroExpander(const LexerToken *TokArray, unsigned NumToks,
-                             Preprocessor &pp)
-  : Macro(0), ActualArgs(0), PP(pp), MacroTokens(TokArray),
-    NumMacroTokens(NumToks), CurToken(0),
-    InstantiateLoc(SourceLocation()), AtStartOfLine(false), 
-    HasLeadingSpace(false) {
+void MacroExpander::Init(const LexerToken *TokArray, unsigned NumToks) {
+  // If the client is reusing a macro expander, make sure to free any memory
+  // associated with it.
+  destroy();
+  
+  Macro = 0;
+  ActualArgs = 0;
+  MacroTokens = TokArray;
+  NumMacroTokens = NumToks;
+  CurToken = 0;
+  InstantiateLoc = SourceLocation();
+  AtStartOfLine = false;
+  HasLeadingSpace = false;
       
   // Set HasLeadingSpace/AtStartOfLine so that the first token will be
   // returned unmodified.
@@ -272,7 +285,7 @@
 }
 
 
-MacroExpander::~MacroExpander() {
+void MacroExpander::destroy() {
   // If this was a function-like macro that actually uses its arguments, delete
   // the expanded tokens.
   if (Macro && MacroTokens != &*Macro->tokens_begin())

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

==============================================================================
--- cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/Lex/Preprocessor.cpp Sat Jul 14 19:25:26 2007
@@ -48,7 +48,7 @@
     SourceMgr(SM), HeaderInfo(Headers), Identifiers(opts),
     CurLexer(0), CurDirLookup(0), CurMacroExpander(0), Callbacks(0) {
   ScratchBuf = new ScratchBuffer(SourceMgr);
-      
+
   // Clear stats.
   NumDirectives = NumDefined = NumUndefined = NumPragma = 0;
   NumIf = NumElse = NumEndif = 0;
@@ -65,6 +65,7 @@
   // Macro expansion is enabled.
   DisableMacroExpansion = false;
   InMacroArgs = false;
+  NumCachedMacroExpanders = 0;
 
   // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
   // This gets unpoisoned where it is allowed.
@@ -88,6 +89,10 @@
     IncludeMacroStack.pop_back();
   }
   
+  // Free any cached macro expanders.
+  for (unsigned i = 0, e = NumCachedMacroExpanders; i != e; ++i)
+    delete MacroExpanderCache[i];
+  
   // Release pragma information.
   delete PragmaHandlers;
 
@@ -386,7 +391,12 @@
   CurLexer     = 0;
   CurDirLookup = 0;
   
-  CurMacroExpander = new MacroExpander(Tok, Args, *this);
+  if (NumCachedMacroExpanders == 0) {
+    CurMacroExpander = new MacroExpander(Tok, Args, *this);
+  } else {
+    CurMacroExpander = MacroExpanderCache[--NumCachedMacroExpanders];
+    CurMacroExpander->Init(Tok, Args);
+  }
 }
 
 /// EnterTokenStream - Add a "macro" context to the top of the include stack,
@@ -402,7 +412,12 @@
   CurDirLookup = 0;
 
   // Create a macro expander to expand from the specified token stream.
-  CurMacroExpander = new MacroExpander(Toks, NumToks, *this);
+  if (NumCachedMacroExpanders == 0) {
+    CurMacroExpander = new MacroExpander(Toks, NumToks, *this);
+  } else {
+    CurMacroExpander = MacroExpanderCache[--NumCachedMacroExpanders];
+    CurMacroExpander->Init(Toks, NumToks);
+  }
 }
 
 /// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
@@ -410,8 +425,16 @@
 /// state of the top-of-stack lexer is known.
 void Preprocessor::RemoveTopOfLexerStack() {
   assert(!IncludeMacroStack.empty() && "Ran out of stack entries to load");
-  delete CurLexer;
-  delete CurMacroExpander;
+  
+  if (CurMacroExpander) {
+    // Delete or cache the now-dead macro expander.
+    if (NumCachedMacroExpanders == MacroExpanderCacheSize)
+      delete CurMacroExpander;
+    else
+      MacroExpanderCache[NumCachedMacroExpanders++] = CurMacroExpander;
+  } else {
+    delete CurLexer;
+  }
   CurLexer         = IncludeMacroStack.back().TheLexer;
   CurDirLookup     = IncludeMacroStack.back().TheDirLookup;
   CurMacroExpander = IncludeMacroStack.back().TheMacroExpander;
@@ -1047,7 +1070,11 @@
   assert(CurMacroExpander && !CurLexer &&
          "Ending a macro when currently in a #include file!");
 
-  delete CurMacroExpander;
+  // Delete or cache the now-dead macro expander.
+  if (NumCachedMacroExpanders == MacroExpanderCacheSize)
+    delete CurMacroExpander;
+  else
+    MacroExpanderCache[NumCachedMacroExpanders++] = CurMacroExpander;
 
   // Handle this like a #include file being popped off the stack.
   CurMacroExpander = 0;

Modified: cfe/trunk/include/clang/Lex/MacroExpander.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroExpander.h?rev=39864&r1=39863&r2=39864&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/MacroExpander.h (original)
+++ cfe/trunk/include/clang/Lex/MacroExpander.h Sat Jul 14 19:25:26 2007
@@ -141,12 +141,28 @@
 public:
   /// Create a macro expander for the specified macro with the specified actual
   /// arguments.  Note that this ctor takes ownership of the ActualArgs pointer.
-  MacroExpander(LexerToken &Tok, MacroArgs *ActualArgs, Preprocessor &PP);
+  MacroExpander(LexerToken &Tok, MacroArgs *ActualArgs, Preprocessor &pp)
+    : Macro(0), ActualArgs(0), PP(pp) {
+    Init(Tok, ActualArgs);
+  }
+  
+  /// Init - Initialize this macro expander to expand from the specified macro
+  /// with the specified argument information.  Note that this ctor takes
+  /// ownership of the ActualArgs pointer.
+  void Init(LexerToken &Tok, MacroArgs *ActualArgs);
   
   /// Create a macro expander for the specified token stream.  This does not
   /// take ownership of the specified token vector.
-  MacroExpander(const LexerToken *TokArray, unsigned NumToks, Preprocessor &PP);
-  ~MacroExpander();
+  MacroExpander(const LexerToken *TokArray, unsigned NumToks, Preprocessor &pp)
+    : Macro(0), ActualArgs(0), PP(pp) {
+    Init(TokArray, NumToks);
+  }
+  
+  /// Init - Initialize this macro expander with the specified token stream.
+  /// This does not take ownership of the specified token vector.
+  void Init(const LexerToken *TokArray, unsigned NumToks);
+  
+  ~MacroExpander() { destroy(); }
   
   /// isNextTokenLParen - If the next token lexed will pop this macro off the
   /// expansion stack, return 2.  If the next unexpanded token is a '(', return
@@ -157,6 +173,8 @@
   void Lex(LexerToken &Tok);
   
 private:
+  void destroy();
+  
   /// isAtEnd - Return true if the next lex call will pop this macro off the
   /// include stack.
   bool isAtEnd() const {

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=39864&r1=39863&r2=39864&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Sat Jul 14 19:25:26 2007
@@ -114,6 +114,11 @@
   unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
   unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
   unsigned NumSkipped;
+  
+  /// MacroExpanderCache - Cache macro expanders to reduce malloc traffic.
+  enum { MacroExpanderCacheSize = 8 };
+  unsigned NumCachedMacroExpanders;
+  MacroExpander *MacroExpanderCache[MacroExpanderCacheSize];
 public:
   Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target,
                SourceManager &SM, HeaderSearch &Headers);





More information about the cfe-commits mailing list