r219792 - Speed up hasName() matcher.
Alexander Kornienko
alexfh at google.com
Thu Oct 16 01:13:35 PDT 2014
Sorry for not chiming in earlier. A few nits.
On Wed, Oct 15, 2014 at 4:58 PM, Samuel Benzaquen <sbenza at google.com> wrote:
> Author: sbenza
> Date: Wed Oct 15 09:58:46 2014
> New Revision: 219792
>
> URL: http://llvm.org/viewvc/llvm-project?rev=219792&view=rev
> Log:
> Speed up hasName() matcher.
>
> Summary:
> Speed up hasName() matcher by skipping the expensive generation of the
> fully qualified name unless we need it.
> In the common case of matching an unqualified name, we don't need to
> generate the full name. We might not even need to copy any string at
> all.
> This change speeds up our clang-tidy benchmark by ~10%
>
> Reviewers: klimek
>
> Subscribers: klimek, cfe-commits
>
> Differential Revision: http://reviews.llvm.org/D5776
>
> Modified:
> cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
> cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=219792&r1=219791&r2=219792&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed Oct 15 09:58:46
> 2014
> @@ -1591,16 +1591,8 @@ inline internal::Matcher<Stmt> sizeOfExp
> /// \code
> /// namespace a { namespace b { class X; } }
> /// \endcode
> -AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
> - assert(!Name.empty());
> - const std::string FullNameString = "::" +
> Node.getQualifiedNameAsString();
> - const StringRef FullName = FullNameString;
> - const StringRef Pattern = Name;
> - if (Pattern.startswith("::")) {
> - return FullName == Pattern;
> - } else {
> - return FullName.endswith(("::" + Pattern).str());
> - }
> +inline internal::Matcher<NamedDecl> hasName(StringRef Name) {
> + return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Name));
> }
>
> /// \brief Matches NamedDecl nodes whose fully qualified names contain
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=219792&r1=219791&r2=219792&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Wed Oct 15
> 09:58:46 2014
> @@ -574,6 +574,33 @@ private:
> std::string Name;
> };
>
> +/// \brief Matches named declarations with a specific name.
> +///
> +/// See \c hasName() in ASTMatchers.h for details.
> +class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
> + public:
> + explicit HasNameMatcher(StringRef Name);
> +
> + bool matchesNode(const NamedDecl &Node) const override;
> +
> + private:
> + /// \brief Unqualified match routine.
> + ///
> + /// It is much faster than the full match, but it only works for
> unqualified
> + /// matches.
> + bool matchesNodeUnqualified(const NamedDecl &Node) const;
> +
> + /// \brief Full match routine
> + ///
> + /// It generates the fully qualified name of the declaration (which is
> + /// expensive) before trying to match.
> + /// It is slower but simple and works on all cases.
> + bool matchesNodeFull(const NamedDecl &Node) const;
> +
> + const bool UseUnqualifiedMatch;
> + const std::string Name;
> +};
> +
> /// \brief Matches declarations for QualType and CallExpr.
> ///
> /// Type argument DeclMatcherT is required by
> PolymorphicMatcherWithParam1 but
>
> Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=219792&r1=219791&r2=219792&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Wed Oct 15 09:58:46
> 2014
> @@ -13,6 +13,7 @@
>
> #include "clang/ASTMatchers/ASTMatchers.h"
> #include "clang/ASTMatchers/ASTMatchersInternal.h"
> +#include "llvm/ADT/SmallString.h"
> #include "llvm/Support/ManagedStatic.h"
>
> namespace clang {
> @@ -221,6 +222,51 @@ bool AnyOfVariadicOperator(const ast_typ
> return false;
> }
>
> +HasNameMatcher::HasNameMatcher(StringRef NameRef)
> + : UseUnqualifiedMatch(NameRef.find("::") == NameRef.npos),
> Name(NameRef) {
> + assert(!Name.empty());
> +}
> +
> +bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
> + assert(UseUnqualifiedMatch);
> + if (Node.getIdentifier()) {
> + // Simple name.
> + return Name == Node.getName();
> + } else if (Node.getDeclName()) {
>
http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return
> + // Name needs to be constructed.
> + llvm::SmallString<128> NodeName;
> + llvm::raw_svector_ostream OS(NodeName);
> + Node.printName(OS);
> + return Name == OS.str();
> + } else {
>
http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return
> + return false;
> + }
> +}
> +
> +bool HasNameMatcher::matchesNodeFull(const NamedDecl &Node) const {
> + llvm::SmallString<128> NodeName = StringRef("::");
> + llvm::raw_svector_ostream OS(NodeName);
> + Node.printQualifiedName(OS);
> + const StringRef FullName = OS.str();
> + const StringRef Pattern = Name;
> + if (Pattern.startswith("::")) {
> + return FullName == Pattern;
> + } else {
>
http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return
> + return FullName.endswith(("::" + Pattern).str());
>
If this shows on the profile, we can also avoid creating a temporary string
here:
return FullName.endswith(Pattern) &&
FullName.drop_back(Pattern.size()).endswith("::");
> + }
> +}
> +
> +bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
> + // FIXME: There is still room for improvement, but it would require
> copying a
> + // lot of the logic from NamedDecl::printQualifiedName(). The
> benchmarks do
> + // not show like that extra complexity is needed right now.
> + if (UseUnqualifiedMatch) {
> + assert(matchesNodeUnqualified(Node) == matchesNodeFull(Node));
> + return matchesNodeUnqualified(Node);
> + }
> + return matchesNodeFull(Node);
> +}
> +
> } // end namespace internal
> } // end namespace ast_matchers
> } // end namespace clang
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141016/6ae8cbd6/attachment.html>
More information about the cfe-commits
mailing list