Author: george.karpenkov Date: Fri Feb 9 17:49:20 2018 New Revision: 324793
URL: http://llvm.org/viewvc/llvm-project?rev=324793&view=rev Log: [analyzer] Serialize statistics to plist when serialize-stats=true is set Differential Revision: https://reviews.llvm.org/D43131 Added: cfe/trunk/test/Analysis/plist-stats-output.c Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp cfe/trunk/test/Analysis/analyzer-config.c cfe/trunk/test/Analysis/analyzer-config.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=324793&r1=324792&r2=324793&view=diff ============================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Feb 9 17:49:20 2018 @@ -277,6 +277,8 @@ private: /// \sa StableReportFilename Optional<bool> StableReportFilename; + Optional<bool> SerializeStats; + /// \sa getGraphTrimInterval Optional<unsigned> GraphTrimInterval; @@ -538,6 +540,14 @@ public: /// which accepts the values "true" and "false". Default = false bool shouldWriteStableReportFilename(); + /// \return Whether the analyzer should + /// serialize statistics to plist output. + /// Statistics would be serialized in JSON format inside the main dictionary + /// under the \c statistics key. + /// Available only if compiled in assert mode or with LLVM statistics + /// explicitly enabled. + bool shouldSerializeStats(); + /// Returns whether irrelevant parts of a bug report path should be pruned /// out of the final output. /// Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=324793&r1=324792&r2=324793&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Fri Feb 9 17:49:20 2018 @@ -287,6 +287,12 @@ bool AnalyzerOptions::shouldWriteStableR /* Default = */ false); } +bool AnalyzerOptions::shouldSerializeStats() { + return getBooleanOption(SerializeStats, + "serialize-stats", + /* Default = */ false); +} + int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal, const CheckerBase *C, bool SearchInParents) { Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=324793&r1=324792&r2=324793&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Fri Feb 9 17:49:20 2018 @@ -16,9 +16,12 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/Core/HTMLRewrite.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" #include "clang/StaticAnalyzer/Core/IssueHash.h" #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" +#include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" using namespace clang; @@ -30,6 +33,7 @@ namespace { const std::string OutputFile; const LangOptions &LangOpts; const bool SupportsCrossFileDiagnostics; + const bool SerializeStatistics; public: PlistDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string& prefix, @@ -61,7 +65,8 @@ PlistDiagnostics::PlistDiagnostics(Analy bool supportsMultipleFiles) : OutputFile(output), LangOpts(LO), - SupportsCrossFileDiagnostics(supportsMultipleFiles) {} + SupportsCrossFileDiagnostics(supportsMultipleFiles), + SerializeStatistics(AnalyzerOpts.shouldSerializeStats()) {} void ento::createPlistDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C, @@ -484,6 +489,15 @@ void PlistDiagnostics::FlushDiagnosticsI o << " </array>\n"; + if (llvm::AreStatisticsEnabled() && SerializeStatistics) { + o << " <key>statistics</key>\n"; + std::string stats; + llvm::raw_string_ostream os(stats); + llvm::PrintStatisticsJSON(os); + os.flush(); + EmitString(o, html::EscapeText(stats)) << '\n'; + } + // Finish. o << "</dict>\n</plist>"; } Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=324793&r1=324792&r2=324793&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Fri Feb 9 17:49:20 2018 @@ -188,7 +188,8 @@ public: std::unique_ptr<AnalysisManager> Mgr; /// Time the analyzes time of each translation unit. - static llvm::Timer* TUTotalTimer; + std::unique_ptr<llvm::TimerGroup> AnalyzerTimers; + std::unique_ptr<llvm::Timer> TUTotalTimer; /// The information about analyzed functions shared throughout the /// translation unit. @@ -201,15 +202,17 @@ public: OutDir(outdir), Opts(std::move(opts)), Plugins(plugins), Injector(injector) { DigestAnalyzerOptions(); - if (Opts->PrintStats) { - llvm::EnableStatistics(false); - TUTotalTimer = new llvm::Timer("time", "Analyzer Total Time"); + if (Opts->PrintStats || Opts->shouldSerializeStats()) { + AnalyzerTimers = llvm::make_unique<llvm::TimerGroup>( + "analyzer", "Analyzer timers"); + TUTotalTimer = llvm::make_unique<llvm::Timer>( + "time", "Analyzer total time", *AnalyzerTimers); + llvm::EnableStatistics(/* PrintOnExit= */ false); } } ~AnalysisConsumer() override { if (Opts->PrintStats) { - delete TUTotalTimer; llvm::PrintStatistics(); } } @@ -394,8 +397,6 @@ private: //===----------------------------------------------------------------------===// // AnalysisConsumer implementation. //===----------------------------------------------------------------------===// -llvm::Timer* AnalysisConsumer::TUTotalTimer = nullptr; - bool AnalysisConsumer::HandleTopLevelDecl(DeclGroupRef DG) { storeTopLevelDecls(DG); return true; @@ -557,12 +558,6 @@ void AnalysisConsumer::HandleTranslation RecVisitorBR = nullptr; } - // Explicitly destroy the PathDiagnosticConsumer. This will flush its output. - // FIXME: This should be replaced with something that doesn't rely on - // side-effects in PathDiagnosticConsumer's destructor. This is required when - // used with option -disable-free. - Mgr.reset(); - if (TUTotalTimer) TUTotalTimer->stopTimer(); // Count how many basic blocks we have not covered. @@ -574,6 +569,11 @@ void AnalysisConsumer::HandleTranslation (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) / NumBlocksInAnalyzedFunctions; + // Explicitly destroy the PathDiagnosticConsumer. This will flush its output. + // FIXME: This should be replaced with something that doesn't rely on + // side-effects in PathDiagnosticConsumer's destructor. This is required when + // used with option -disable-free. + Mgr.reset(); } std::string AnalysisConsumer::getFunctionName(const Decl *D) { Modified: cfe/trunk/test/Analysis/analyzer-config.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.c?rev=324793&r1=324792&r2=324793&view=diff ============================================================================== --- cfe/trunk/test/Analysis/analyzer-config.c (original) +++ cfe/trunk/test/Analysis/analyzer-config.c Fri Feb 9 17:49:20 2018 @@ -30,6 +30,7 @@ void foo() { // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep // CHECK-NEXT: region-store-small-struct-limit = 2 +// CHECK-NEXT: serialize-stats = false // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] Modified: cfe/trunk/test/Analysis/analyzer-config.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.cpp?rev=324793&r1=324792&r2=324793&view=diff ============================================================================== --- cfe/trunk/test/Analysis/analyzer-config.cpp (original) +++ cfe/trunk/test/Analysis/analyzer-config.cpp Fri Feb 9 17:49:20 2018 @@ -41,6 +41,7 @@ public: // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep // CHECK-NEXT: region-store-small-struct-limit = 2 +// CHECK-NEXT: serialize-stats = false // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] Added: cfe/trunk/test/Analysis/plist-stats-output.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-stats-output.c?rev=324793&view=auto ============================================================================== --- cfe/trunk/test/Analysis/plist-stats-output.c (added) +++ cfe/trunk/test/Analysis/plist-stats-output.c Fri Feb 9 17:49:20 2018 @@ -0,0 +1,14 @@ +// RUN: %clang_analyze_cc1 %s -analyzer-checker=core -analyzer-output=plist -analyzer-config serialize-stats=true -o %t.plist +// REQUIRES: asserts +// RUN: FileCheck --input-file=%t.plist %s + +int foo() {} + + +// CHECK: <key>diagnostics</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>statistics</key> +// CHECK-NEXT: <string>{ +// CHECK: } +// CHECK-NEXT: </string> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits