aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
diff options
context:
space:
mode:
authorArseniy Zaostrovnykh <necto.ne@gmail.com>2025-03-17 08:23:31 +0100
committerGitHub <noreply@github.com>2025-03-17 08:23:31 +0100
commit57e36419b251f7e5a86566c86b4d61fbd605db5c (patch)
tree88565f12713dfca0bd0f149be29256047ce4bfdf /clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
parentc3f6d2c024968d21157aa0a523ef1f1e61a07441 (diff)
downloadllvm-57e36419b251f7e5a86566c86b4d61fbd605db5c.zip
llvm-57e36419b251f7e5a86566c86b4d61fbd605db5c.tar.gz
llvm-57e36419b251f7e5a86566c86b4d61fbd605db5c.tar.bz2
[analyzer] Introduce per-entry-point statistics (#131175)
So far CSA was relying on the LLVM Statistic package that allowed us to gather some data about analysis of an entire translation unit. However, the translation unit consists of a collection of loosely related entry points. Aggregating data across multiple such entry points is often counter productive. This change introduces a new lightweight always-on facility to collect Boolean or numerical statistics for each entry point and dump them in a CSV format. Such format makes it easy to aggregate data across multiple translation units and analyze it with common data-processing tools. We break down the existing statistics that were collected on the per-TU basis into values per entry point. Additionally, we enable the statistics unconditionally (STATISTIC -> ALWAYS_ENABLED_STATISTIC) to facilitate their use (you can gather the data with a simple run-time flag rather than having to recompile the analyzer). These statistics are very light and add virtually no overhead. Co-authored-by: Balazs Benics <benicsbalazs@gmail.com> CPP-6160
Diffstat (limited to 'clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp34
1 files changed, 22 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 8a4bb35..b4222ed 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -32,10 +32,10 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/ScopeExit.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
@@ -51,17 +51,18 @@ using namespace ento;
#define DEBUG_TYPE "AnalysisConsumer"
-STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
-STATISTIC(NumFunctionsAnalyzed,
- "The # of functions and blocks analyzed (as top level "
- "with inlining turned on).");
-STATISTIC(NumBlocksInAnalyzedFunctions,
- "The # of basic blocks in the analyzed functions.");
-STATISTIC(NumVisitedBlocksInAnalyzedFunctions,
- "The # of visited basic blocks in the analyzed functions.");
-STATISTIC(PercentReachableBlocks, "The % of reachable basic blocks.");
-STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
-
+STAT_COUNTER(NumFunctionTopLevel, "The # of functions at top level.");
+ALWAYS_ENABLED_STATISTIC(NumFunctionsAnalyzed,
+ "The # of functions and blocks analyzed (as top level "
+ "with inlining turned on).");
+ALWAYS_ENABLED_STATISTIC(NumBlocksInAnalyzedFunctions,
+ "The # of basic blocks in the analyzed functions.");
+ALWAYS_ENABLED_STATISTIC(
+ NumVisitedBlocksInAnalyzedFunctions,
+ "The # of visited basic blocks in the analyzed functions.");
+ALWAYS_ENABLED_STATISTIC(PercentReachableBlocks,
+ "The % of reachable basic blocks.");
+STAT_MAX(MaxCFGSize, "The maximum number of basic blocks in a function.");
//===----------------------------------------------------------------------===//
// AnalysisConsumer declaration.
//===----------------------------------------------------------------------===//
@@ -128,7 +129,9 @@ public:
PP(CI.getPreprocessor()), OutDir(outdir), Opts(opts), Plugins(plugins),
Injector(std::move(injector)), CTU(CI),
MacroExpansions(CI.getLangOpts()) {
+ EntryPointStat::lockRegistry();
DigestAnalyzerOptions();
+
if (Opts.AnalyzerDisplayProgress || Opts.PrintStats ||
Opts.ShouldSerializeStats) {
AnalyzerTimers = std::make_unique<llvm::TimerGroup>(
@@ -653,6 +656,10 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
PercentReachableBlocks =
(FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) /
NumBlocksInAnalyzedFunctions;
+
+ if (!Opts.DumpEntryPointStatsToCSV.empty()) {
+ EntryPointStat::dumpStatsAsCSV(Opts.DumpEntryPointStatsToCSV);
+ }
}
AnalysisConsumer::AnalysisMode
@@ -688,6 +695,8 @@ AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
return Mode;
}
+static UnsignedEPStat PathRunningTime("PathRunningTime");
+
void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
ExprEngine::InliningModes IMode,
SetOfConstDecls *VisitedCallees) {
@@ -732,6 +741,7 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
RunPathSensitiveChecks(D, IMode, VisitedCallees);
+ EntryPointStat::takeSnapshot(D);
if (IMode != ExprEngine::Inline_Minimal)
NumFunctionsAnalyzed++;
}