diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp index 282d136aff721a..382aa5d6fe25e2 100644 --- a/clang-tools-extra/clang-query/Query.cpp +++ b/clang-tools-extra/clang-query/Query.cpp @@ -44,7 +44,9 @@ bool HelpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { " set bind-root (true|false) " "Set whether to bind the root matcher to \"root\".\n" " set print-matcher (true|false) " - "Set whether to print the current matcher,\n" + "Set whether to print the current matcher.\n" + " set enable-profile (true|false) " + "Set whether to enable matcher profiling.\n" " set traversal " "Set traversal kind of clang-query session. Available kinds are:\n" " AsIs " @@ -82,10 +84,24 @@ namespace { struct CollectBoundNodes : MatchFinder::MatchCallback { std::vector &Bindings; - CollectBoundNodes(std::vector &Bindings) : Bindings(Bindings) {} + StringRef Unit; + CollectBoundNodes(std::vector &Bindings, StringRef Unit) + : Bindings(Bindings), Unit(Unit) {} void run(const MatchFinder::MatchResult &Result) override { Bindings.push_back(Result.Nodes); } + StringRef getID() const override { return Unit; } +}; + +struct QueryProfiler { + llvm::StringMap Records; + + ~QueryProfiler() { + llvm::TimerGroup TG("clang-query", "clang-query matcher profiling", + Records); + TG.print(llvm::errs()); + llvm::errs().flush(); + } }; } // namespace @@ -93,8 +109,19 @@ struct CollectBoundNodes : MatchFinder::MatchCallback { bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { unsigned MatchCount = 0; + std::optional Profiler; + if (QS.EnableProfile) + Profiler.emplace(); + for (auto &AST : QS.ASTs) { - MatchFinder Finder; + ast_matchers::MatchFinder::MatchFinderOptions FinderOptions; + std::optional> Records; + if (QS.EnableProfile) { + Records.emplace(); + FinderOptions.CheckProfiling.emplace(*Records); + } + + MatchFinder Finder(FinderOptions); std::vector Matches; DynTypedMatcher MaybeBoundMatcher = Matcher; if (QS.BindRoot) { @@ -102,7 +129,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { if (M) MaybeBoundMatcher = *M; } - CollectBoundNodes Collect(Matches); + StringRef OrigSrcName = AST->getOriginalSourceFileName(); + CollectBoundNodes Collect(Matches, OrigSrcName); if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) { OS << "Not a valid top-level matcher.\n"; return false; @@ -111,6 +139,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { ASTContext &Ctx = AST->getASTContext(); Ctx.getParentMapContext().setTraversalKind(QS.TK); Finder.matchAST(Ctx); + if (QS.EnableProfile) + Profiler->Records[OrigSrcName] += (*Records)[OrigSrcName]; if (QS.PrintMatcher) { SmallVector Lines; diff --git a/clang-tools-extra/clang-query/QueryParser.cpp b/clang-tools-extra/clang-query/QueryParser.cpp index 97cb264a611af3..1d5ec281defd40 100644 --- a/clang-tools-extra/clang-query/QueryParser.cpp +++ b/clang-tools-extra/clang-query/QueryParser.cpp @@ -182,6 +182,7 @@ enum ParsedQueryVariable { PQV_Output, PQV_BindRoot, PQV_PrintMatcher, + PQV_EnableProfile, PQV_Traversal }; @@ -285,6 +286,7 @@ QueryRef QueryParser::doParse() { .Case("output", PQV_Output) .Case("bind-root", PQV_BindRoot) .Case("print-matcher", PQV_PrintMatcher) + .Case("enable-profile", PQV_EnableProfile) .Case("traversal", PQV_Traversal) .Default(PQV_Invalid); if (VarStr.empty()) @@ -303,6 +305,9 @@ QueryRef QueryParser::doParse() { case PQV_PrintMatcher: Q = parseSetBool(&QuerySession::PrintMatcher); break; + case PQV_EnableProfile: + Q = parseSetBool(&QuerySession::EnableProfile); + break; case PQV_Traversal: Q = parseSetTraversalKind(&QuerySession::TK); break; diff --git a/clang-tools-extra/clang-query/QuerySession.h b/clang-tools-extra/clang-query/QuerySession.h index 31a4900e26190b..c7d5a64c332008 100644 --- a/clang-tools-extra/clang-query/QuerySession.h +++ b/clang-tools-extra/clang-query/QuerySession.h @@ -26,7 +26,7 @@ class QuerySession { QuerySession(llvm::ArrayRef> ASTs) : ASTs(ASTs), PrintOutput(false), DiagOutput(true), DetailedASTOutput(false), BindRoot(true), PrintMatcher(false), - Terminate(false), TK(TK_AsIs) {} + EnableProfile(false), Terminate(false), TK(TK_AsIs) {} llvm::ArrayRef> ASTs; @@ -36,6 +36,7 @@ class QuerySession { bool BindRoot; bool PrintMatcher; + bool EnableProfile; bool Terminate; TraversalKind TK; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 51ba157ab05deb..abcdcc25705bf5 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -98,7 +98,7 @@ Improvements to clang-doc Improvements to clang-query --------------------------- -The improvements are... +- Added `set enable-profile true/false` command for basic matcher profiling. Improvements to clang-tidy --------------------------