Hi klimek,
Store the result matcher after the first call and reuse it later on.
Recreating the matchers just to use them once incurs in a lot of
unnecessary temporary memory allocations.
This change speeds up our clang-tidy benchmarks by ~2%.
http://reviews.llvm.org/D6564
Files:
include/clang/ASTMatchers/ASTMatchers.h
include/clang/ASTMatchers/ASTMatchersInternal.h
include/clang/ASTMatchers/ASTMatchersMacros.h
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3159,12 +3159,10 @@
/// \endcode
/// functionDecl(isInstantiated())
/// matches 'A(int) {...};' and 'A(unsigned) {...}'.
-AST_MATCHER(Decl, isInstantiated) {
+AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
auto IsInstantiation = decl(anyOf(recordDecl(isTemplateInstantiation()),
functionDecl(isTemplateInstantiation())));
- auto InnerMatcher =
- decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
- return InnerMatcher.matches(Node, Finder, Builder);
+ return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
}
/// \brief Matches statements inside of a template instantiation.
@@ -3181,11 +3179,10 @@
/// unless(stmt(isInTemplateInstantiation()))
/// will NOT match j += 42; as it's shared between the template definition and
/// instantiation.
-AST_MATCHER(Stmt, isInTemplateInstantiation) {
- auto InnerMatcher =
- stmt(hasAncestor(decl(anyOf(recordDecl(isTemplateInstantiation()),
- functionDecl(isTemplateInstantiation())))));
- return InnerMatcher.matches(Node, Finder, Builder);
+AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) {
+ return stmt(
+ hasAncestor(decl(anyOf(recordDecl(isTemplateInstantiation()),
+ functionDecl(isTemplateInstantiation())))));
}
/// \brief Matches explicit template specializations of function, class, or
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -44,6 +44,7 @@
#include "clang/AST/Type.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/VariadicFunction.h"
+#include "llvm/Support/ManagedStatic.h"
#include <map>
#include <string>
#include <vector>
@@ -1620,6 +1621,23 @@
const Matcher<InnerTBase> InnerMatcher;
};
+/// \brief A simple memoizer of T(*)() functions.
+///
+/// It will call the passed 'Func' template parameter at most once.
+/// Used to support AST_MATCHER_FUNCTION() macro.
+template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
+ struct Wrapper {
+ Wrapper() : M(Func()) {}
+ Matcher M;
+ };
+
+public:
+ static const Matcher &getInstance() {
+ static llvm::ManagedStatic<Wrapper> Instance;
+ return Instance->M;
+ }
+};
+
// Define the create() method out of line to silence a GCC warning about
// the struct "Func" having greater visibility than its base, which comes from
// using the flag -fvisibility-inlines-hidden.
Index: include/clang/ASTMatchers/ASTMatchersMacros.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersMacros.h
+++ include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -37,6 +37,17 @@
#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
+/// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) {
+/// defines a zero parameter function named DefineMatcher() that returns a
+/// ReturnType object.
+#define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \
+ inline ReturnType DefineMatcher##_getInstance(); \
+ inline ReturnType DefineMatcher() { \
+ return internal::MemoizedMatcher< \
+ ReturnType, DefineMatcher##_getInstance>::getInstance(); \
+ } \
+ inline ReturnType DefineMatcher##_getInstance()
+
/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
/// defines a single-parameter function named DefineMatcher() that returns a
/// ReturnType object.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits