Hi klimek,

Skip some unnecessary type checks wrt DynTypedNodes.
Add DynTypedNode::getUnchecked() to skip the runtime check when the type
is known.
Speed up DynTypedNode::operator== by using isSame() instead of
isBaseOf().
Skip the type check in MatcherInterface<T>::matches(). All calls come
from DynTypedMatcher::matches(), which already did the type check.
This change speeds up our clang-tidy benchmark by ~4%.

http://reviews.llvm.org/D6468

Files:
  include/clang/AST/ASTTypeTraits.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
Index: include/clang/AST/ASTTypeTraits.h
===================================================================
--- include/clang/AST/ASTTypeTraits.h
+++ include/clang/AST/ASTTypeTraits.h
@@ -145,6 +145,8 @@
   template <class T> struct KindToKindId {
     static const NodeKindId Id = NKI_None;
   };
+  template <class T>
+  struct KindToKindId<const T> : KindToKindId<T> {};
 
   /// \brief Per kind info.
   struct KindInfo {
@@ -221,6 +223,14 @@
     return BaseConverter<T>::get(NodeKind, Storage.buffer);
   }
 
+  /// \brief Retrieve the stored node as type \c T.
+  ///
+  /// Similar to \c get(), but asserts that the type is what we are expecting.
+  template <typename T>
+  const T &getUnchecked() const {
+    return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
+  }
+
   ASTNodeKind getNodeKind() const { return NodeKind; }
 
   /// \brief Returns a pointer that identifies the stored AST node.
@@ -251,14 +261,13 @@
     return getMemoizationData() < Other.getMemoizationData();
   }
   bool operator==(const DynTypedNode &Other) const {
-    if (!NodeKind.isBaseOf(Other.NodeKind) &&
-        !Other.NodeKind.isBaseOf(NodeKind))
+    if (!NodeKind.isSame(Other.NodeKind))
       return false;
 
     // FIXME: Implement for other types.
-    if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) {
-      return *get<QualType>() == *Other.get<QualType>();
-    }
+    if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
+      return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
+    
     assert(getMemoizationData() && Other.getMemoizationData());
     return getMemoizationData() == Other.getMemoizationData();
   }
@@ -274,10 +283,15 @@
   /// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
   template <typename T, typename BaseT> struct DynCastPtrConverter {
     static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
-      if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
-        return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+      if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind)) {
+        return cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+      }
       return nullptr;
     }
+    static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
+      assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
+      return *cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+    }
     static DynTypedNode create(const BaseT &Node) {
       DynTypedNode Result;
       Result.NodeKind = ASTNodeKind::getFromNode(Node);
@@ -294,6 +308,10 @@
         return *reinterpret_cast<T *const *>(Storage);
       return nullptr;
     }
+    static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
+      assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
+      return **reinterpret_cast<T *const *>(Storage);
+    }
     static DynTypedNode create(const T &Node) {
       DynTypedNode Result;
       Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
@@ -310,6 +328,10 @@
         return reinterpret_cast<const T *>(Storage);
       return nullptr;
     }
+    static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
+      assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
+      return *reinterpret_cast<const T *>(Storage);
+    }
     static DynTypedNode create(const T &Node) {
       DynTypedNode Result;
       Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -218,10 +218,7 @@
   bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
                   ASTMatchFinder *Finder,
                   BoundNodesTreeBuilder *Builder) const override {
-    if (const T *Node = DynNode.get<T>()) {
-      return matches(*Node, Finder, Builder);
-    }
-    return false;
+    return matches(DynNode.getUnchecked<T>(), Finder, Builder);
   }
 };
 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to