https://github.com/danix800 updated https://github.com/llvm/llvm-project/pull/114806
>From dfd42c06d94f859ec78ec1e5c3386c0e4016386f Mon Sep 17 00:00:00 2001 From: dingfei <fd...@feysh.com> Date: Mon, 4 Nov 2024 22:37:51 +0800 Subject: [PATCH 1/4] [clang-query] add basic profiling on matching each ASTs Sample output: $ cat test.cql set enable-profile true m binaryOperator(isExpansionInMainFile()) $ cat test.c int test(int i, int j) { return i + j; } $ clang-query --track-memory -f test.cql test.c -- Match #1: {{.*}}/test.c:2:10: note: "root" binds here 2 | return i + j; | ^~~~~ 1 match. ===-------------------------------------------------------------------------=== clang-query matcher profiling ===-------------------------------------------------------------------------=== Total Execution Time: 0.0000 seconds (0.0000 wall clock) ---User Time--- --System Time-- --User+System-- ---Wall Time--- ---Mem--- --- Name --- 0.0000 (100.0%) 0.0000 (100.0%) 0.0000 (100.0%) 0.0000 (100.0%) 224 {{.*}}/test.c 0.0000 (100.0%) 0.0000 (100.0%) 0.0000 (100.0%) 0.0000 (100.0%) 224 Total --- clang-tools-extra/clang-query/CMakeLists.txt | 1 + clang-tools-extra/clang-query/Query.cpp | 26 ++++++++++++-- clang-tools-extra/clang-query/QueryParser.cpp | 5 +++ .../clang-query/QueryProfile.cpp | 24 +++++++++++++ clang-tools-extra/clang-query/QueryProfile.h | 35 +++++++++++++++++++ clang-tools-extra/clang-query/QuerySession.h | 3 +- 6 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 clang-tools-extra/clang-query/QueryProfile.cpp create mode 100644 clang-tools-extra/clang-query/QueryProfile.h diff --git a/clang-tools-extra/clang-query/CMakeLists.txt b/clang-tools-extra/clang-query/CMakeLists.txt index b168a3a8581567..84a1ad6fa33582 100644 --- a/clang-tools-extra/clang-query/CMakeLists.txt +++ b/clang-tools-extra/clang-query/CMakeLists.txt @@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangQuery STATIC Query.cpp QueryParser.cpp + QueryProfile.cpp DEPENDS omp_gen diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp index 282d136aff721a..5b628de3c4deeb 100644 --- a/clang-tools-extra/clang-query/Query.cpp +++ b/clang-tools-extra/clang-query/Query.cpp @@ -8,6 +8,7 @@ #include "Query.h" #include "QueryParser.h" +#include "QueryProfile.h" #include "QuerySession.h" #include "clang/AST/ASTDumper.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -44,6 +45,8 @@ 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 enable-profile (true|false) " + "Set whether to enable matcher profiling,\n" "Set whether to print the current matcher,\n" " set traversal <kind> " "Set traversal kind of clang-query session. Available kinds are:\n" @@ -82,10 +85,13 @@ namespace { struct CollectBoundNodes : MatchFinder::MatchCallback { std::vector<BoundNodes> &Bindings; - CollectBoundNodes(std::vector<BoundNodes> &Bindings) : Bindings(Bindings) {} + StringRef Unit; + CollectBoundNodes(std::vector<BoundNodes> &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; } }; } // namespace @@ -93,8 +99,19 @@ struct CollectBoundNodes : MatchFinder::MatchCallback { bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { unsigned MatchCount = 0; + std::optional<QueryProfile> Profiling; + if (QS.EnableProfile) + Profiling = QueryProfile(); + for (auto &AST : QS.ASTs) { - MatchFinder Finder; + ast_matchers::MatchFinder::MatchFinderOptions FinderOptions; + std::optional<llvm::StringMap<llvm::TimeRecord>> Records; + if (QS.EnableProfile) { + Records.emplace(); + FinderOptions.CheckProfiling.emplace(*Records); + } + + MatchFinder Finder(FinderOptions); std::vector<BoundNodes> Matches; DynTypedMatcher MaybeBoundMatcher = Matcher; if (QS.BindRoot) { @@ -102,7 +119,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 +129,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) + Profiling->Records[OrigSrcName] += (*Records)[OrigSrcName]; if (QS.PrintMatcher) { SmallVector<StringRef, 4> 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/QueryProfile.cpp b/clang-tools-extra/clang-query/QueryProfile.cpp new file mode 100644 index 00000000000000..9b60f0bf1c7f4e --- /dev/null +++ b/clang-tools-extra/clang-query/QueryProfile.cpp @@ -0,0 +1,24 @@ +//===-------- QueryProfile.cpp - clang-query --------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "QueryProfile.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang::query { + +void QueryProfile::printUserFriendlyTable(llvm::raw_ostream &OS) { + TG->print(OS); + OS.flush(); +} + +QueryProfile::~QueryProfiling() { + TG.emplace("clang-query", "clang-query matcher profiling", Records); + printUserFriendlyTable(llvm::errs()); +} + +} // namespace clang::query diff --git a/clang-tools-extra/clang-query/QueryProfile.h b/clang-tools-extra/clang-query/QueryProfile.h new file mode 100644 index 00000000000000..6815dc0245bdc8 --- /dev/null +++ b/clang-tools-extra/clang-query/QueryProfile.h @@ -0,0 +1,35 @@ +//===--------- QueryProfile.h - clang-query ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Timer.h" +#include <optional> + +namespace llvm { +class raw_ostream; +} // namespace llvm + +namespace clang::query { + +class QueryProfile { +public: + llvm::StringMap<llvm::TimeRecord> Records; + QueryProfile() = default; + ~QueryProfile(); + +private: + std::optional<llvm::TimerGroup> TG; + void printUserFriendlyTable(llvm::raw_ostream &OS); +}; + +} // namespace clang::query + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H 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<std::unique_ptr<ASTUnit>> 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<std::unique_ptr<ASTUnit>> ASTs; @@ -36,6 +36,7 @@ class QuerySession { bool BindRoot; bool PrintMatcher; + bool EnableProfile; bool Terminate; TraversalKind TK; >From ccd96f04747ff6809a15df07ddb58d6c378c21fb Mon Sep 17 00:00:00 2001 From: dingfei <fd...@feysh.com> Date: Mon, 4 Nov 2024 22:50:16 +0800 Subject: [PATCH 2/4] fix typos --- clang-tools-extra/clang-query/Query.cpp | 6 +++--- clang-tools-extra/clang-query/QueryProfile.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp index 5b628de3c4deeb..9d5a6a32be7bbf 100644 --- a/clang-tools-extra/clang-query/Query.cpp +++ b/clang-tools-extra/clang-query/Query.cpp @@ -45,9 +45,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 enable-profile (true|false) " - "Set whether to enable matcher profiling,\n" "Set whether to print the current matcher,\n" + " set enable-profile (true|false) " + "Set whether to enable matcher profiling,\n" " set traversal <kind> " "Set traversal kind of clang-query session. Available kinds are:\n" " AsIs " @@ -101,7 +101,7 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { std::optional<QueryProfile> Profiling; if (QS.EnableProfile) - Profiling = QueryProfile(); + Profiling.emplace(); for (auto &AST : QS.ASTs) { ast_matchers::MatchFinder::MatchFinderOptions FinderOptions; diff --git a/clang-tools-extra/clang-query/QueryProfile.cpp b/clang-tools-extra/clang-query/QueryProfile.cpp index 9b60f0bf1c7f4e..aa24e0400dff3c 100644 --- a/clang-tools-extra/clang-query/QueryProfile.cpp +++ b/clang-tools-extra/clang-query/QueryProfile.cpp @@ -16,7 +16,7 @@ void QueryProfile::printUserFriendlyTable(llvm::raw_ostream &OS) { OS.flush(); } -QueryProfile::~QueryProfiling() { +QueryProfile::~QueryProfile() { TG.emplace("clang-query", "clang-query matcher profiling", Records); printUserFriendlyTable(llvm::errs()); } >From 57151c6bec9d8d4c264d865f914f4de73987d4a7 Mon Sep 17 00:00:00 2001 From: dingfei <fd...@feysh.com> Date: Mon, 4 Nov 2024 23:05:47 +0800 Subject: [PATCH 3/4] fix punctuation error in command help text --- clang-tools-extra/clang-query/Query.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp index 9d5a6a32be7bbf..74530937ac04a7 100644 --- a/clang-tools-extra/clang-query/Query.cpp +++ b/clang-tools-extra/clang-query/Query.cpp @@ -45,9 +45,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 whether to enable matcher profiling.\n" " set traversal <kind> " "Set traversal kind of clang-query session. Available kinds are:\n" " AsIs " >From 6b931b85222204b2acdfeaba1e406c8cd58d8d95 Mon Sep 17 00:00:00 2001 From: dingfei <fd...@feysh.com> Date: Tue, 5 Nov 2024 12:14:38 +0800 Subject: [PATCH 4/4] move QueryProfiler into Query.cpp 1. QueryProfiler is very small, no need to expose it; 2. TimerGroup is created when dumping profiling info, no need to be an optional member of QueryProfiler. --- clang-tools-extra/clang-query/CMakeLists.txt | 1 - clang-tools-extra/clang-query/Query.cpp | 28 ++++++++++++--- .../clang-query/QueryProfile.cpp | 24 ------------- clang-tools-extra/clang-query/QueryProfile.h | 35 ------------------- 4 files changed, 24 insertions(+), 64 deletions(-) delete mode 100644 clang-tools-extra/clang-query/QueryProfile.cpp delete mode 100644 clang-tools-extra/clang-query/QueryProfile.h diff --git a/clang-tools-extra/clang-query/CMakeLists.txt b/clang-tools-extra/clang-query/CMakeLists.txt index 84a1ad6fa33582..b168a3a8581567 100644 --- a/clang-tools-extra/clang-query/CMakeLists.txt +++ b/clang-tools-extra/clang-query/CMakeLists.txt @@ -7,7 +7,6 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangQuery STATIC Query.cpp QueryParser.cpp - QueryProfile.cpp DEPENDS omp_gen diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp index 74530937ac04a7..7db11e29661eca 100644 --- a/clang-tools-extra/clang-query/Query.cpp +++ b/clang-tools-extra/clang-query/Query.cpp @@ -8,7 +8,6 @@ #include "Query.h" #include "QueryParser.h" -#include "QueryProfile.h" #include "QuerySession.h" #include "clang/AST/ASTDumper.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -94,14 +93,35 @@ struct CollectBoundNodes : MatchFinder::MatchCallback { StringRef getID() const override { return Unit; } }; +class QueryProfiler { +public: + QueryProfiler() = default; + ~QueryProfiler() { printUserFriendlyTable(llvm::errs()); } + + void addASTUnitRecord(llvm::StringRef Unit, const llvm::TimeRecord &Record) { + Records[Unit] += Record; + } + +private: + void printUserFriendlyTable(llvm::raw_ostream &OS) { + llvm::TimerGroup TG("clang-query", "clang-query matcher profiling", + Records); + TG.print(OS); + OS.flush(); + } + +private: + llvm::StringMap<llvm::TimeRecord> Records; +}; + } // namespace bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { unsigned MatchCount = 0; - std::optional<QueryProfile> Profiling; + std::optional<QueryProfiler> Profiler; if (QS.EnableProfile) - Profiling.emplace(); + Profiler.emplace(); for (auto &AST : QS.ASTs) { ast_matchers::MatchFinder::MatchFinderOptions FinderOptions; @@ -130,7 +150,7 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { Ctx.getParentMapContext().setTraversalKind(QS.TK); Finder.matchAST(Ctx); if (QS.EnableProfile) - Profiling->Records[OrigSrcName] += (*Records)[OrigSrcName]; + Profiler->addASTUnitRecord(OrigSrcName, (*Records)[OrigSrcName]); if (QS.PrintMatcher) { SmallVector<StringRef, 4> Lines; diff --git a/clang-tools-extra/clang-query/QueryProfile.cpp b/clang-tools-extra/clang-query/QueryProfile.cpp deleted file mode 100644 index aa24e0400dff3c..00000000000000 --- a/clang-tools-extra/clang-query/QueryProfile.cpp +++ /dev/null @@ -1,24 +0,0 @@ -//===-------- QueryProfile.cpp - clang-query --------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "QueryProfile.h" -#include "llvm/Support/raw_ostream.h" - -namespace clang::query { - -void QueryProfile::printUserFriendlyTable(llvm::raw_ostream &OS) { - TG->print(OS); - OS.flush(); -} - -QueryProfile::~QueryProfile() { - TG.emplace("clang-query", "clang-query matcher profiling", Records); - printUserFriendlyTable(llvm::errs()); -} - -} // namespace clang::query diff --git a/clang-tools-extra/clang-query/QueryProfile.h b/clang-tools-extra/clang-query/QueryProfile.h deleted file mode 100644 index 6815dc0245bdc8..00000000000000 --- a/clang-tools-extra/clang-query/QueryProfile.h +++ /dev/null @@ -1,35 +0,0 @@ -//===--------- QueryProfile.h - clang-query ---------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H - -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/Timer.h" -#include <optional> - -namespace llvm { -class raw_ostream; -} // namespace llvm - -namespace clang::query { - -class QueryProfile { -public: - llvm::StringMap<llvm::TimeRecord> Records; - QueryProfile() = default; - ~QueryProfile(); - -private: - std::optional<llvm::TimerGroup> TG; - void printUserFriendlyTable(llvm::raw_ostream &OS); -}; - -} // namespace clang::query - -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits