[cfe-commits] r152411 - in /cfe/trunk: include/clang/AST/Stmt.h lib/AST/Expr.cpp lib/AST/Stmt.cpp

Daniel Dunbar daniel at zuster.org
Fri Mar 9 07:39:20 PST 2012


Author: ddunbar
Date: Fri Mar  9 09:39:19 2012
New Revision: 152411

URL: http://llvm.org/viewvc/llvm-project?rev=152411&view=rev
Log:
[AST] Reimplement Stmt::getLoc{Start,End} to dispatch to subclass overloads.
 - getSourceRange() can be very expensive, we should try to avoid it if at all possible.

In conjunction with the previous commit I measured a ~2% speedup on 403.gcc/combine.c and a 3% speedup on OmniGroupFrameworks/NSBezierPath-OAExtensions.m.

Modified:
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/Stmt.cpp

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=152411&r1=152410&r2=152411&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Fri Mar  9 09:39:19 2012
@@ -348,8 +348,8 @@
   /// clients will have a pointer to the respective SourceManager.
   SourceRange getSourceRange() const;
 
-  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
-  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
+  SourceLocation getLocStart() const;
+  SourceLocation getLocEnd() const;
 
   // global temp stats (until we have a per-module visitor)
   static void addStmtClass(const StmtClass s);

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=152411&r1=152410&r2=152411&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Mar  9 09:39:19 2012
@@ -94,6 +94,8 @@
 
 // Amusing macro metaprogramming hack: check whether a class provides
 // a more specific implementation of getExprLoc().
+//
+// See also Stmt.cpp:{getLocStart(),getLocEnd()}.
 namespace {
   /// This implementation is used when a class provides a custom
   /// implementation of getExprLoc.
@@ -110,7 +112,7 @@
   template <class E>
   SourceLocation getExprLocImpl(const Expr *expr,
                                 SourceLocation (Expr::*v)() const) {
-    return static_cast<const E*>(expr)->getSourceRange().getBegin();
+    return static_cast<const E*>(expr)->getLocStart();
   }
 }
 

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=152411&r1=152410&r2=152411&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Fri Mar  9 09:39:19 2012
@@ -176,6 +176,72 @@
   llvm_unreachable("unknown statement kind!");
 }
 
+// Amusing macro metaprogramming hack: check whether a class provides
+// a more specific implementation of getLocStart() and getLocEnd().
+//
+// See also Expr.cpp:getExprLoc().
+namespace {
+  /// This implementation is used when a class provides a custom
+  /// implementation of getLocStart.
+  template <class S, class T>
+  SourceLocation getLocStartImpl(const Stmt *stmt,
+                                 SourceLocation (T::*v)() const) {
+    return static_cast<const S*>(stmt)->getLocStart();
+  }
+
+  /// This implementation is used when a class doesn't provide a custom
+  /// implementation of getLocStart.  Overload resolution should pick it over
+  /// the implementation above because it's more specialized according to
+  /// function template partial ordering.
+  template <class S>
+  SourceLocation getLocStartImpl(const Stmt *stmt,
+                                SourceLocation (Stmt::*v)() const) {
+    return static_cast<const S*>(stmt)->getSourceRange().getBegin();
+  }
+
+  /// This implementation is used when a class provides a custom
+  /// implementation of getLocEnd.
+  template <class S, class T>
+  SourceLocation getLocEndImpl(const Stmt *stmt,
+                               SourceLocation (T::*v)() const) {
+    return static_cast<const S*>(stmt)->getLocEnd();
+  }
+
+  /// This implementation is used when a class doesn't provide a custom
+  /// implementation of getLocEnd.  Overload resolution should pick it over
+  /// the implementation above because it's more specialized according to
+  /// function template partial ordering.
+  template <class S>
+  SourceLocation getLocEndImpl(const Stmt *stmt,
+                               SourceLocation (Stmt::*v)() const) {
+    return static_cast<const S*>(stmt)->getSourceRange().getEnd();
+  }
+}
+
+SourceLocation Stmt::getLocStart() const {
+  switch (getStmtClass()) {
+  case Stmt::NoStmtClass: llvm_unreachable("statement without class");
+#define ABSTRACT_STMT(type)
+#define STMT(type, base) \
+  case Stmt::type##Class: \
+    return getLocStartImpl<type>(this, &type::getLocStart);
+#include "clang/AST/StmtNodes.inc"
+  }
+  llvm_unreachable("unknown statement kind");
+}
+
+SourceLocation Stmt::getLocEnd() const {
+  switch (getStmtClass()) {
+  case Stmt::NoStmtClass: llvm_unreachable("statement without class");
+#define ABSTRACT_STMT(type)
+#define STMT(type, base) \
+  case Stmt::type##Class: \
+    return getLocEndImpl<type>(this, &type::getLocEnd);
+#include "clang/AST/StmtNodes.inc"
+  }
+  llvm_unreachable("unknown statement kind");
+}
+
 void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
   if (this->Body)
     C.Deallocate(Body);





More information about the cfe-commits mailing list