Author: sbenza Date: Mon Dec 8 14:17:58 2014 New Revision: 223690 URL: http://llvm.org/viewvc/llvm-project?rev=223690&view=rev Log: Fix isInstantiated and isInTemplateInstantiation to not recreate the matchers on each call.
Summary: 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%. Reviewers: klimek Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D6564 Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=223690&r1=223689&r2=223690&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon Dec 8 14:17:58 2014 @@ -3159,12 +3159,10 @@ AST_POLYMORPHIC_MATCHER( /// \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 @@ AST_MATCHER(Decl, isInstantiated) { /// 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 Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=223690&r1=223689&r2=223690&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Dec 8 14:17:58 2014 @@ -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 @@ private: 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. Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h?rev=223690&r1=223689&r2=223690&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h Mon Dec 8 14:17:58 2014 @@ -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
