Skip to content

Commit dfd42c0

Browse files
committed
[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
1 parent 77b7d9d commit dfd42c0

File tree

6 files changed

+90
-4
lines changed

6 files changed

+90
-4
lines changed

clang-tools-extra/clang-query/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
77
add_clang_library(clangQuery STATIC
88
Query.cpp
99
QueryParser.cpp
10+
QueryProfile.cpp
1011

1112
DEPENDS
1213
omp_gen

clang-tools-extra/clang-query/Query.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "Query.h"
1010
#include "QueryParser.h"
11+
#include "QueryProfile.h"
1112
#include "QuerySession.h"
1213
#include "clang/AST/ASTDumper.h"
1314
#include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -44,6 +45,8 @@ bool HelpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
4445
" set bind-root (true|false) "
4546
"Set whether to bind the root matcher to \"root\".\n"
4647
" set print-matcher (true|false) "
48+
" set enable-profile (true|false) "
49+
"Set whether to enable matcher profiling,\n"
4750
"Set whether to print the current matcher,\n"
4851
" set traversal <kind> "
4952
"Set traversal kind of clang-query session. Available kinds are:\n"
@@ -82,27 +85,42 @@ namespace {
8285

8386
struct CollectBoundNodes : MatchFinder::MatchCallback {
8487
std::vector<BoundNodes> &Bindings;
85-
CollectBoundNodes(std::vector<BoundNodes> &Bindings) : Bindings(Bindings) {}
88+
StringRef Unit;
89+
CollectBoundNodes(std::vector<BoundNodes> &Bindings, StringRef Unit)
90+
: Bindings(Bindings), Unit(Unit) {}
8691
void run(const MatchFinder::MatchResult &Result) override {
8792
Bindings.push_back(Result.Nodes);
8893
}
94+
StringRef getID() const override { return Unit; }
8995
};
9096

9197
} // namespace
9298

9399
bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
94100
unsigned MatchCount = 0;
95101

102+
std::optional<QueryProfile> Profiling;
103+
if (QS.EnableProfile)
104+
Profiling = QueryProfile();
105+
96106
for (auto &AST : QS.ASTs) {
97-
MatchFinder Finder;
107+
ast_matchers::MatchFinder::MatchFinderOptions FinderOptions;
108+
std::optional<llvm::StringMap<llvm::TimeRecord>> Records;
109+
if (QS.EnableProfile) {
110+
Records.emplace();
111+
FinderOptions.CheckProfiling.emplace(*Records);
112+
}
113+
114+
MatchFinder Finder(FinderOptions);
98115
std::vector<BoundNodes> Matches;
99116
DynTypedMatcher MaybeBoundMatcher = Matcher;
100117
if (QS.BindRoot) {
101118
std::optional<DynTypedMatcher> M = Matcher.tryBind("root");
102119
if (M)
103120
MaybeBoundMatcher = *M;
104121
}
105-
CollectBoundNodes Collect(Matches);
122+
StringRef OrigSrcName = AST->getOriginalSourceFileName();
123+
CollectBoundNodes Collect(Matches, OrigSrcName);
106124
if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
107125
OS << "Not a valid top-level matcher.\n";
108126
return false;
@@ -111,6 +129,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
111129
ASTContext &Ctx = AST->getASTContext();
112130
Ctx.getParentMapContext().setTraversalKind(QS.TK);
113131
Finder.matchAST(Ctx);
132+
if (QS.EnableProfile)
133+
Profiling->Records[OrigSrcName] += (*Records)[OrigSrcName];
114134

115135
if (QS.PrintMatcher) {
116136
SmallVector<StringRef, 4> Lines;

clang-tools-extra/clang-query/QueryParser.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ enum ParsedQueryVariable {
182182
PQV_Output,
183183
PQV_BindRoot,
184184
PQV_PrintMatcher,
185+
PQV_EnableProfile,
185186
PQV_Traversal
186187
};
187188

@@ -285,6 +286,7 @@ QueryRef QueryParser::doParse() {
285286
.Case("output", PQV_Output)
286287
.Case("bind-root", PQV_BindRoot)
287288
.Case("print-matcher", PQV_PrintMatcher)
289+
.Case("enable-profile", PQV_EnableProfile)
288290
.Case("traversal", PQV_Traversal)
289291
.Default(PQV_Invalid);
290292
if (VarStr.empty())
@@ -303,6 +305,9 @@ QueryRef QueryParser::doParse() {
303305
case PQV_PrintMatcher:
304306
Q = parseSetBool(&QuerySession::PrintMatcher);
305307
break;
308+
case PQV_EnableProfile:
309+
Q = parseSetBool(&QuerySession::EnableProfile);
310+
break;
306311
case PQV_Traversal:
307312
Q = parseSetTraversalKind(&QuerySession::TK);
308313
break;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===-------- QueryProfile.cpp - clang-query --------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "QueryProfile.h"
10+
#include "llvm/Support/raw_ostream.h"
11+
12+
namespace clang::query {
13+
14+
void QueryProfile::printUserFriendlyTable(llvm::raw_ostream &OS) {
15+
TG->print(OS);
16+
OS.flush();
17+
}
18+
19+
QueryProfile::~QueryProfiling() {
20+
TG.emplace("clang-query", "clang-query matcher profiling", Records);
21+
printUserFriendlyTable(llvm::errs());
22+
}
23+
24+
} // namespace clang::query
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===--------- QueryProfile.h - clang-query ---------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H
11+
12+
#include "llvm/ADT/StringMap.h"
13+
#include "llvm/Support/Timer.h"
14+
#include <optional>
15+
16+
namespace llvm {
17+
class raw_ostream;
18+
} // namespace llvm
19+
20+
namespace clang::query {
21+
22+
class QueryProfile {
23+
public:
24+
llvm::StringMap<llvm::TimeRecord> Records;
25+
QueryProfile() = default;
26+
~QueryProfile();
27+
28+
private:
29+
std::optional<llvm::TimerGroup> TG;
30+
void printUserFriendlyTable(llvm::raw_ostream &OS);
31+
};
32+
33+
} // namespace clang::query
34+
35+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H

clang-tools-extra/clang-query/QuerySession.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class QuerySession {
2626
QuerySession(llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs)
2727
: ASTs(ASTs), PrintOutput(false), DiagOutput(true),
2828
DetailedASTOutput(false), BindRoot(true), PrintMatcher(false),
29-
Terminate(false), TK(TK_AsIs) {}
29+
EnableProfile(false), Terminate(false), TK(TK_AsIs) {}
3030

3131
llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs;
3232

@@ -36,6 +36,7 @@ class QuerySession {
3636

3737
bool BindRoot;
3838
bool PrintMatcher;
39+
bool EnableProfile;
3940
bool Terminate;
4041

4142
TraversalKind TK;

0 commit comments

Comments
 (0)