mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 15:46:45 +00:00
[clang-query] add basic profiling on matching each ASTs (#114806)
We've found that basic profiling could help improving/optimizing when developing clang-tidy checks. This PR adds an extra command ``` set enable-profile (true|false) Set whether to enable matcher profiling. ``` which enables profiling queries on each file. 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 ```
This commit is contained in:
parent
f6948e8f9d
commit
03f06b9710
@ -44,7 +44,9 @@ bool HelpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
|
|||||||
" set bind-root (true|false) "
|
" set bind-root (true|false) "
|
||||||
"Set whether to bind the root matcher to \"root\".\n"
|
"Set whether to bind the root matcher to \"root\".\n"
|
||||||
" set print-matcher (true|false) "
|
" 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 <kind> "
|
" set traversal <kind> "
|
||||||
"Set traversal kind of clang-query session. Available kinds are:\n"
|
"Set traversal kind of clang-query session. Available kinds are:\n"
|
||||||
" AsIs "
|
" AsIs "
|
||||||
@ -82,10 +84,24 @@ namespace {
|
|||||||
|
|
||||||
struct CollectBoundNodes : MatchFinder::MatchCallback {
|
struct CollectBoundNodes : MatchFinder::MatchCallback {
|
||||||
std::vector<BoundNodes> &Bindings;
|
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 {
|
void run(const MatchFinder::MatchResult &Result) override {
|
||||||
Bindings.push_back(Result.Nodes);
|
Bindings.push_back(Result.Nodes);
|
||||||
}
|
}
|
||||||
|
StringRef getID() const override { return Unit; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueryProfiler {
|
||||||
|
llvm::StringMap<llvm::TimeRecord> Records;
|
||||||
|
|
||||||
|
~QueryProfiler() {
|
||||||
|
llvm::TimerGroup TG("clang-query", "clang-query matcher profiling",
|
||||||
|
Records);
|
||||||
|
TG.print(llvm::errs());
|
||||||
|
llvm::errs().flush();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -93,8 +109,19 @@ struct CollectBoundNodes : MatchFinder::MatchCallback {
|
|||||||
bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
|
bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
|
||||||
unsigned MatchCount = 0;
|
unsigned MatchCount = 0;
|
||||||
|
|
||||||
|
std::optional<QueryProfiler> Profiler;
|
||||||
|
if (QS.EnableProfile)
|
||||||
|
Profiler.emplace();
|
||||||
|
|
||||||
for (auto &AST : QS.ASTs) {
|
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;
|
std::vector<BoundNodes> Matches;
|
||||||
DynTypedMatcher MaybeBoundMatcher = Matcher;
|
DynTypedMatcher MaybeBoundMatcher = Matcher;
|
||||||
if (QS.BindRoot) {
|
if (QS.BindRoot) {
|
||||||
@ -102,7 +129,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
|
|||||||
if (M)
|
if (M)
|
||||||
MaybeBoundMatcher = *M;
|
MaybeBoundMatcher = *M;
|
||||||
}
|
}
|
||||||
CollectBoundNodes Collect(Matches);
|
StringRef OrigSrcName = AST->getOriginalSourceFileName();
|
||||||
|
CollectBoundNodes Collect(Matches, OrigSrcName);
|
||||||
if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
|
if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
|
||||||
OS << "Not a valid top-level matcher.\n";
|
OS << "Not a valid top-level matcher.\n";
|
||||||
return false;
|
return false;
|
||||||
@ -111,6 +139,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
|
|||||||
ASTContext &Ctx = AST->getASTContext();
|
ASTContext &Ctx = AST->getASTContext();
|
||||||
Ctx.getParentMapContext().setTraversalKind(QS.TK);
|
Ctx.getParentMapContext().setTraversalKind(QS.TK);
|
||||||
Finder.matchAST(Ctx);
|
Finder.matchAST(Ctx);
|
||||||
|
if (QS.EnableProfile)
|
||||||
|
Profiler->Records[OrigSrcName] += (*Records)[OrigSrcName];
|
||||||
|
|
||||||
if (QS.PrintMatcher) {
|
if (QS.PrintMatcher) {
|
||||||
SmallVector<StringRef, 4> Lines;
|
SmallVector<StringRef, 4> Lines;
|
||||||
|
@ -182,6 +182,7 @@ enum ParsedQueryVariable {
|
|||||||
PQV_Output,
|
PQV_Output,
|
||||||
PQV_BindRoot,
|
PQV_BindRoot,
|
||||||
PQV_PrintMatcher,
|
PQV_PrintMatcher,
|
||||||
|
PQV_EnableProfile,
|
||||||
PQV_Traversal
|
PQV_Traversal
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -285,6 +286,7 @@ QueryRef QueryParser::doParse() {
|
|||||||
.Case("output", PQV_Output)
|
.Case("output", PQV_Output)
|
||||||
.Case("bind-root", PQV_BindRoot)
|
.Case("bind-root", PQV_BindRoot)
|
||||||
.Case("print-matcher", PQV_PrintMatcher)
|
.Case("print-matcher", PQV_PrintMatcher)
|
||||||
|
.Case("enable-profile", PQV_EnableProfile)
|
||||||
.Case("traversal", PQV_Traversal)
|
.Case("traversal", PQV_Traversal)
|
||||||
.Default(PQV_Invalid);
|
.Default(PQV_Invalid);
|
||||||
if (VarStr.empty())
|
if (VarStr.empty())
|
||||||
@ -303,6 +305,9 @@ QueryRef QueryParser::doParse() {
|
|||||||
case PQV_PrintMatcher:
|
case PQV_PrintMatcher:
|
||||||
Q = parseSetBool(&QuerySession::PrintMatcher);
|
Q = parseSetBool(&QuerySession::PrintMatcher);
|
||||||
break;
|
break;
|
||||||
|
case PQV_EnableProfile:
|
||||||
|
Q = parseSetBool(&QuerySession::EnableProfile);
|
||||||
|
break;
|
||||||
case PQV_Traversal:
|
case PQV_Traversal:
|
||||||
Q = parseSetTraversalKind(&QuerySession::TK);
|
Q = parseSetTraversalKind(&QuerySession::TK);
|
||||||
break;
|
break;
|
||||||
|
@ -26,7 +26,7 @@ public:
|
|||||||
QuerySession(llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs)
|
QuerySession(llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs)
|
||||||
: ASTs(ASTs), PrintOutput(false), DiagOutput(true),
|
: ASTs(ASTs), PrintOutput(false), DiagOutput(true),
|
||||||
DetailedASTOutput(false), BindRoot(true), PrintMatcher(false),
|
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;
|
llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs;
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ public:
|
|||||||
|
|
||||||
bool BindRoot;
|
bool BindRoot;
|
||||||
bool PrintMatcher;
|
bool PrintMatcher;
|
||||||
|
bool EnableProfile;
|
||||||
bool Terminate;
|
bool Terminate;
|
||||||
|
|
||||||
TraversalKind TK;
|
TraversalKind TK;
|
||||||
|
@ -98,7 +98,7 @@ Improvements to clang-doc
|
|||||||
Improvements to clang-query
|
Improvements to clang-query
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
The improvements are...
|
- Added `set enable-profile true/false` command for basic matcher profiling.
|
||||||
|
|
||||||
Improvements to clang-tidy
|
Improvements to clang-tidy
|
||||||
--------------------------
|
--------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user