aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-07-06 16:21:37 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-07-06 16:21:37 +0000
commit5d98994c7749312a43ce6adf45537979a98e7afd (patch)
treeeab8032acb17e8615e5120a3fb52a1b8ca91c125 /lib/Sema/AnalysisBasedWarnings.cpp
parent786dcd9dca76e3780fdb9642c0db33ed13db1187 (diff)
Build up statistics about the work done for analysis based warnings.
Special detail is added for uninitialized variable analysis as this has serious performance problems than need to be tracked. Computing some of this data is expensive, for example walking the CFG to determine its size. To avoid doing that unless the stats data is going to be used, we thread a bit into the Sema object to track whether detailed stats should be collected or not. This bit is used to avoid computations whereever the computations are likely to be more expensive than checking the state of the flag. Thus, counters are in some cases unconditionally updated, but the more expensive (and less frequent) aggregation steps are skipped. With this patch, we're able to see that for 'gcc.c': *** Analysis Based Warnings Stats: 232 functions analyzed (0 w/o CFGs). 7151 CFG blocks built. 30 average CFG blocks per function. 1167 max CFG blocks per function. 163 functions analyzed for uninitialiazed variables 640 variables analyzed. 3 average variables per function. 94 max variables per function. 96409 block visits. 591 average block visits per function. 61546 max block visits per function. And for the reduced testcase in PR10183: *** Analysis Based Warnings Stats: 98 functions analyzed (0 w/o CFGs). 8526 CFG blocks built. 87 average CFG blocks per function. 7277 max CFG blocks per function. 68 functions analyzed for uninitialiazed variables 1359 variables analyzed. 19 average variables per function. 1196 max variables per function. 2540494 block visits. 37360 average block visits per function. 2536495 max block visits per function. That last number is the somewhat scary one that indicates the problem in PR10183. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134494 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp68
1 files changed, 66 insertions, 2 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index e560ef8a5c..8a4634df2f 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -597,7 +597,11 @@ clang::sema::AnalysisBasedWarnings::Policy::Policy() {
enableCheckUnreachable = 0;
}
-clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s) {
+clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
+ : S(s),
+ NumFunctionsAnalyzed(0),
+ NumCFGBlocks(0),
+ MaxCFGBlocksPerFunction(0) {
Diagnostic &D = S.getDiagnostics();
DefaultPolicy.enableCheckUnreachable = (unsigned)
(D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) !=
@@ -713,8 +717,68 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
!= Diagnostic::Ignored) {
if (CFG *cfg = AC.getCFG()) {
UninitValsDiagReporter reporter(S);
+ UninitVariablesAnalysisStats stats = {};
runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,
- reporter);
+ reporter, stats);
+
+ if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {
+ ++NumUninitAnalysisFunctions;
+ NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
+ NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
+ MaxUninitAnalysisVariablesPerFunction =
+ std::max(MaxUninitAnalysisVariablesPerFunction,
+ stats.NumVariablesAnalyzed);
+ MaxUninitAnalysisBlockVisitsPerFunction =
+ std::max(MaxUninitAnalysisBlockVisitsPerFunction,
+ stats.NumBlockVisits);
+ }
+ }
+ }
+
+ // Collect statistics about the CFG if it was built.
+ if (S.CollectStats && AC.isCFGBuilt()) {
+ ++NumFunctionsAnalyzed;
+ if (CFG *cfg = AC.getCFG()) {
+ // If we successfully built a CFG for this context, record some more
+ // detail information about it.
+ unsigned NumBlocks = std::distance(cfg->begin(), cfg->end());
+ NumCFGBlocks += NumBlocks;
+ MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
+ NumBlocks);
+ } else {
+ ++NumFunctionsWithBadCFGs;
}
}
}
+
+void clang::sema::AnalysisBasedWarnings::PrintStats() const {
+ llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";
+
+ unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
+ unsigned AvgCFGBlocksPerFunction =
+ !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
+ llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
+ << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
+ << " " << NumCFGBlocks << " CFG blocks built.\n"
+ << " " << AvgCFGBlocksPerFunction
+ << " average CFG blocks per function.\n"
+ << " " << MaxCFGBlocksPerFunction
+ << " max CFG blocks per function.\n";
+
+ unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
+ : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
+ unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
+ : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
+ llvm::errs() << NumUninitAnalysisFunctions
+ << " functions analyzed for uninitialiazed variables\n"
+ << " " << NumUninitAnalysisVariables << " variables analyzed.\n"
+ << " " << AvgUninitVariablesPerFunction
+ << " average variables per function.\n"
+ << " " << MaxUninitAnalysisVariablesPerFunction
+ << " max variables per function.\n"
+ << " " << NumUninitAnalysisBlockVisits << " block visits.\n"
+ << " " << AvgUninitBlockVisitsPerFunction
+ << " average block visits per function.\n"
+ << " " << MaxUninitAnalysisBlockVisitsPerFunction
+ << " max block visits per function.\n";
+}