[cfe-commits] r39138 - in /cfe/cfe/trunk: Parse/ParseStmt.cpp Parse/Parser.cpp clang.xcodeproj/project.pbxproj include/clang/Parse/Scope.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:27:56 PDT 2007


Author: sabre
Date: Wed Jul 11 11:27:56 2007
New Revision: 39138

URL: http://llvm.org/viewvc/llvm-project?rev=39138&view=rev
Log:
implement trivial scope caching.  This reduces malloc traffic in the common
case, speeding up parsing of this contrived example:

#define A {{}}
#define B A A A A A A A A A A
#define C B B B B B B B B B B
#define D C C C C C C C C C C
#define E D D D D D D D D D D
#define F E E E E E E E E E E
#define G F F F F F F F F F F
#define H G G G G G G G G G G

void foo() {
  H
}

from 7.478s to 4.321s.  GCC requires 8.2s.

Modified:
    cfe/cfe/trunk/Parse/ParseStmt.cpp
    cfe/cfe/trunk/Parse/Parser.cpp
    cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/cfe/trunk/include/clang/Parse/Scope.h

Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=39138&r1=39137&r2=39138&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:27:56 2007
@@ -663,6 +663,7 @@
   
   Scope *S = CurScope->getContinueParent();
   if (!S) {
+    // C99 6.8.6.2p1: A break shall appear only in or as a loop body.
     Diag(ContinueLoc, diag::err_continue_not_in_loop);
     return true;
   }
@@ -683,6 +684,7 @@
 
   Scope *S = CurScope->getBreakParent();
   if (!S) {
+    // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
     Diag(BreakLoc, diag::err_break_not_in_loop_or_switch);
     return true;
   }

Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=39138&r1=39137&r2=39138&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:27:56 2007
@@ -37,11 +37,6 @@
   ParenCount = BracketCount = BraceCount = 0;
 }
 
-Parser::~Parser() {
-  // If we still have scopes active, delete the scope tree.
-  delete CurScope;
-}
-
 ///  Out-of-line virtual destructor to provide home for Action class.
 Action::~Action() {}
 
@@ -186,9 +181,19 @@
 // Scope manipulation
 //===----------------------------------------------------------------------===//
 
+/// ScopeCache - Cache scopes to avoid malloc traffic.
+static SmallVector<Scope*, 16> ScopeCache;
+
 /// EnterScope - Start a new scope.
 void Parser::EnterScope(unsigned ScopeFlags) {
-  CurScope = new Scope(CurScope, ScopeFlags);
+  if (!ScopeCache.empty()) {
+    Scope *N = ScopeCache.back();
+    ScopeCache.pop_back();
+    N->Init(CurScope, ScopeFlags);
+    CurScope = N;
+  } else {
+    CurScope = new Scope(CurScope, ScopeFlags);
+  }
 }
 
 /// ExitScope - Pop a scope off the scope stack.
@@ -200,7 +205,11 @@
   
   Scope *Old = CurScope;
   CurScope = Old->getParent();
-  delete Old;
+  
+  if (ScopeCache.size() == 16)
+    delete Old;
+  else
+    ScopeCache.push_back(Old);
 }
 
 
@@ -210,6 +219,17 @@
 // C99 6.9: External Definitions.
 //===----------------------------------------------------------------------===//
 
+Parser::~Parser() {
+  // If we still have scopes active, delete the scope tree.
+  delete CurScope;
+  
+  // Free the scope cache.
+  while (!ScopeCache.empty()) {
+    delete ScopeCache.back();
+    ScopeCache.pop_back();
+  }
+}
+
 /// Initialize - Warm up the parser.
 ///
 void Parser::Initialize() {

Modified: cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=39138&r1=39137&r2=39138&view=diff

==============================================================================
--- cfe/cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/cfe/trunk/clang.xcodeproj/project.pbxproj Wed Jul 11 11:27:56 2007
@@ -33,6 +33,7 @@
 		DE3460280AFDCD6F00DBC861 /* SemaDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3460270AFDCD6F00DBC861 /* SemaDecl.cpp */; };
 		DE3460310AFDCDC100DBC861 /* SemaDecl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3460300AFDCDC100DBC861 /* SemaDecl.h */; };
 		DE3461270AFE68BE00DBC861 /* MinimalAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */; };
+		DE34621D0AFEB19B00DBC861 /* StmtPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */; };
 		DE46BF280AE0A82D00CC047C /* TargetInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE46BF270AE0A82D00CC047C /* TargetInfo.h */; };
 		DE5932D10AD60FF400BC794C /* clang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5932CD0AD60FF400BC794C /* clang.cpp */; };
 		DE5932D20AD60FF400BC794C /* clang.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE5932CE0AD60FF400BC794C /* clang.h */; };
@@ -154,6 +155,7 @@
 		DE3460270AFDCD6F00DBC861 /* SemaDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDecl.cpp; path = Parse/SemaDecl.cpp; sourceTree = "<group>"; };
 		DE3460300AFDCDC100DBC861 /* SemaDecl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SemaDecl.h; path = clang/Parse/SemaDecl.h; sourceTree = "<group>"; };
 		DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MinimalAction.cpp; path = Parse/MinimalAction.cpp; sourceTree = "<group>"; };
+		DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = StmtPrinter.cpp; path = AST/StmtPrinter.cpp; sourceTree = "<group>"; };
 		DE46BF270AE0A82D00CC047C /* TargetInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetInfo.h; sourceTree = "<group>"; };
 		DE5932CD0AD60FF400BC794C /* clang.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = clang.cpp; path = Driver/clang.cpp; sourceTree = "<group>"; };
 		DE5932CE0AD60FF400BC794C /* clang.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = clang.h; path = Driver/clang.h; sourceTree = "<group>"; };
@@ -311,6 +313,7 @@
 				DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */,
 				DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
 				DE3452400AEF1A2D00DBC861 /* Stmt.cpp */,
+				DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */,
 				DE345C560AFC69E800DBC861 /* StmtVisitor.cpp */,
 			);
 			name = AST;
@@ -467,6 +470,7 @@
 				DE3460130AFDCCDA00DBC861 /* ParseExpr.cpp in Sources */,
 				DE3460280AFDCD6F00DBC861 /* SemaDecl.cpp in Sources */,
 				DE3461270AFE68BE00DBC861 /* MinimalAction.cpp in Sources */,
+				DE34621D0AFEB19B00DBC861 /* StmtPrinter.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: cfe/cfe/trunk/include/clang/Parse/Scope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Scope.h?rev=39138&r1=39137&r2=39138&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Scope.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Scope.h Wed Jul 11 11:27:56 2007
@@ -20,7 +20,6 @@
 namespace llvm {
 namespace clang {
 
-  
 /// Scope - A scope is a transient data structure that is used while parsing the
 /// program.  It assists with resolving identifiers to the appropriate
 /// declaration.
@@ -80,24 +79,8 @@
   /// implement these semantics.
   SmallVector<Action::DeclTy*, 32> DeclsInScope;
 public:
-  Scope(Scope *parent, unsigned ScopeFlags)
-    : AnyParent(parent), Depth(AnyParent ? AnyParent->Depth+1 : 0),
-      Flags(ScopeFlags){
-    assert((Flags & (HasBreak|HasContinue)) == 0 &&
-           "These flags can't be set in ctor!");
-    
-    if (AnyParent) {
-      FnParent       = AnyParent->FnParent;
-      BreakParent    = AnyParent->BreakParent;
-      ContinueParent = AnyParent->ContinueParent;
-    } else {
-      FnParent = BreakParent = ContinueParent = 0;
-    }
-
-    // If this scope is a function or contains breaks/continues, remember it.
-    if (Flags & FnScope)       FnParent = this;
-    if (Flags & BreakScope)    BreakParent = this;
-    if (Flags & ContinueScope) ContinueParent = this;
+  Scope(Scope *Parent, unsigned ScopeFlags) {
+    Init(Parent, ScopeFlags);
   }
   
   /// getParent - Return the scope that this is nested in.
@@ -130,6 +113,32 @@
     DeclsInScope.push_back(D);
   }
   
+  
+  
+  /// Init - This is used by the parser to implement scope caching.
+  ///
+  void Init(Scope *Parent, unsigned ScopeFlags) {
+    assert((ScopeFlags & (HasBreak|HasContinue)) == 0 &&
+           "These flags can't be set in ctor!");
+    AnyParent = Parent;
+    Depth = AnyParent ? AnyParent->Depth+1 : 0;
+    Flags = ScopeFlags;
+    
+    if (AnyParent) {
+      FnParent       = AnyParent->FnParent;
+      BreakParent    = AnyParent->BreakParent;
+      ContinueParent = AnyParent->ContinueParent;
+    } else {
+      FnParent = BreakParent = ContinueParent = 0;
+    }
+    
+    // If this scope is a function or contains breaks/continues, remember it.
+    if (Flags & FnScope)       FnParent = this;
+    if (Flags & BreakScope)    BreakParent = this;
+    if (Flags & ContinueScope) ContinueParent = this;
+    
+    DeclsInScope.clear();
+  }      
 };
     
 }  // end namespace clang





More information about the cfe-commits mailing list