diff options
author | Arseniy Zaostrovnykh <necto.ne@gmail.com> | 2025-03-17 08:23:31 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-17 08:23:31 +0100 |
commit | 57e36419b251f7e5a86566c86b4d61fbd605db5c (patch) | |
tree | 88565f12713dfca0bd0f149be29256047ce4bfdf /clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp | |
parent | c3f6d2c024968d21157aa0a523ef1f1e61a07441 (diff) | |
download | llvm-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.cpp | 34 |
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++; } |