aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
diff options
context:
space:
mode:
authorArseniy Zaostrovnykh <necto.ne@gmail.com>2025-02-05 17:22:18 +0100
committerGitHub <noreply@github.com>2025-02-05 17:22:18 +0100
commitc1d5be8f7fa24b95e652593f9a780005e6604920 (patch)
tree64b90a9095557fddecbd70fe23a750328911ca34 /clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
parent925d347c5a43fd4864c7cb142e4069a1d494cd11 (diff)
downloadllvm-c1d5be8f7fa24b95e652593f9a780005e6604920.zip
llvm-c1d5be8f7fa24b95e652593f9a780005e6604920.tar.gz
llvm-c1d5be8f7fa24b95e652593f9a780005e6604920.tar.bz2
[analyzer] Add time-trace scopes for high-level analyzer steps (#125508)
Specifically, add a scope for - each work-list step, - each entry point, - each checker run within a step, and - bug-suppression phase at the end of the analysis of an entry-point. These scopes add no perceptible run-time overhead when time-tracing is disabled. You can enable it and generate a time trace using the `-ftime-trace=file.json` option. See also the RFC: https://discourse.llvm.org/t/analyzer-rfc-ftime-trace-time-scopes-for-steps-and-entry-points/84343 -- CPP-6065
Diffstat (limited to 'clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp45
1 files changed, 37 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 91c9b08..189d7d6 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -39,6 +39,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
@@ -358,9 +359,40 @@ private:
/// Print \p S to stderr if \c Opts.AnalyzerDisplayProgress is set.
void reportAnalyzerProgress(StringRef S);
-}; // namespace
-} // end anonymous namespace
+};
+std::string timeTraceScopeDeclName(StringRef FunName, const Decl *D) {
+ if (llvm::timeTraceProfilerEnabled()) {
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ return (FunName + " " + ND->getQualifiedNameAsString()).str();
+ return (FunName + " <anonymous> ").str();
+ }
+ return "";
+}
+
+llvm::TimeTraceMetadata timeTraceScopeDeclMetadata(const Decl *D) {
+ // If time-trace profiler is not enabled, this function is never called.
+ assert(llvm::timeTraceProfilerEnabled());
+ if (const auto &Loc = D->getBeginLoc(); Loc.isValid()) {
+ const auto &SM = D->getASTContext().getSourceManager();
+ std::string DeclName = AnalysisDeclContext::getFunctionName(D);
+ return llvm::TimeTraceMetadata{
+ std::move(DeclName), SM.getFilename(Loc).str(),
+ static_cast<int>(SM.getExpansionLineNumber(Loc))};
+ }
+ return llvm::TimeTraceMetadata{"", ""};
+}
+
+void flushReports(llvm::Timer *BugReporterTimer, BugReporter &BR) {
+ llvm::TimeTraceScope TCS{"Flushing reports"};
+ // Display warnings.
+ if (BugReporterTimer)
+ BugReporterTimer->startTimer();
+ BR.FlushReports();
+ if (BugReporterTimer)
+ BugReporterTimer->stopTimer();
+}
+} // namespace
//===----------------------------------------------------------------------===//
// AnalysisConsumer implementation.
@@ -658,6 +690,8 @@ AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
ExprEngine::InliningModes IMode,
SetOfConstDecls *VisitedCallees) {
+ llvm::TimeTraceScope TCS(timeTraceScopeDeclName("HandleCode", D),
+ [D]() { return timeTraceScopeDeclMetadata(D); });
if (!D->hasBody())
return;
Mode = getModeForDecl(D, Mode);
@@ -742,12 +776,7 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
if (Mgr->options.visualizeExplodedGraphWithGraphViz)
Eng.ViewGraph(Mgr->options.TrimGraph);
- // Display warnings.
- if (BugReporterTimer)
- BugReporterTimer->startTimer();
- Eng.getBugReporter().FlushReports();
- if (BugReporterTimer)
- BugReporterTimer->stopTimer();
+ flushReports(BugReporterTimer.get(), Eng.getBugReporter());
}
//===----------------------------------------------------------------------===//