[cfe-commits] r134494 - in /cfe/trunk: include/clang/Analysis/Analyses/UninitializedValues.h include/clang/Analysis/AnalysisContext.h include/clang/Sema/AnalysisBasedWarnings.h include/clang/Sema/Sema.h lib/Analysis/UninitializedValues.cpp lib/Parse/ParseAST.cpp lib/Sema/AnalysisBasedWarnings.cpp lib/Sema/Sema.cpp
Ted Kremenek
kremenek at apple.com
Wed Jul 13 20:54:49 PDT 2011
Awesome!
Sent from my iPad
On Jul 6, 2011, at 9:21 AM, Chandler Carruth <chandlerc at gmail.com> wrote:
> Author: chandlerc
> Date: Wed Jul 6 11:21:37 2011
> New Revision: 134494
>
> URL: http://llvm.org/viewvc/llvm-project?rev=134494&view=rev
> Log:
> 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.
>
> Modified:
> cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h
> cfe/trunk/include/clang/Analysis/AnalysisContext.h
> cfe/trunk/include/clang/Sema/AnalysisBasedWarnings.h
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/Analysis/UninitializedValues.cpp
> cfe/trunk/lib/Parse/ParseAST.cpp
> cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
> cfe/trunk/lib/Sema/Sema.cpp
>
> Modified: cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h (original)
> +++ cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h Wed Jul 6 11:21:37 2011
> @@ -32,10 +32,16 @@
> const VarDecl *vd,
> bool isAlwaysUninit) {}
> };
> -
> +
> +struct UninitVariablesAnalysisStats {
> + unsigned NumVariablesAnalyzed;
> + unsigned NumBlockVisits;
> +};
> +
> void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
> AnalysisContext &ac,
> - UninitVariablesHandler &handler);
> + UninitVariablesHandler &handler,
> + UninitVariablesAnalysisStats &stats);
>
> }
> #endif
>
> Modified: cfe/trunk/include/clang/Analysis/AnalysisContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisContext.h?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
> +++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Wed Jul 6 11:21:37 2011
> @@ -107,6 +107,11 @@
>
> void dumpCFG();
>
> + /// \brief Returns true if we have built a CFG for this analysis context.
> + /// Note that this doesn't correspond to whether or not a valid CFG exists, it
> + /// corresponds to whether we *attempted* to build one.
> + bool isCFGBuilt() const { return builtCFG; }
> +
> ParentMap &getParentMap();
> PseudoConstantAnalysis *getPseudoConstantAnalysis();
> LiveVariables *getLiveVariables();
>
> Modified: cfe/trunk/include/clang/Sema/AnalysisBasedWarnings.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AnalysisBasedWarnings.h?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/AnalysisBasedWarnings.h (original)
> +++ cfe/trunk/include/clang/Sema/AnalysisBasedWarnings.h Wed Jul 6 11:21:37 2011
> @@ -49,6 +49,41 @@
> enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
> llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
>
> + /// \name Statistics
> + /// @{
> +
> + /// \brief Number of function CFGs built and analyzed.
> + unsigned NumFunctionsAnalyzed;
> +
> + /// \brief Number of functions for which the CFG could not be successfully
> + /// built.
> + unsigned NumFunctionsWithBadCFGs;
> +
> + /// \brief Total number of blocks across all CFGs.
> + unsigned NumCFGBlocks;
> +
> + /// \brief Largest number of CFG blocks for a single function analyzed.
> + unsigned MaxCFGBlocksPerFunction;
> +
> + /// \brief Total number of CFGs with variables analyzed for uninitialized
> + /// uses.
> + unsigned NumUninitAnalysisFunctions;
> +
> + /// \brief Total number of variables analyzed for uninitialized uses.
> + unsigned NumUninitAnalysisVariables;
> +
> + /// \brief Max number of variables analyzed for uninitialized uses in a single
> + /// function.
> + unsigned MaxUninitAnalysisVariablesPerFunction;
> +
> + /// \brief Total number of block visits during uninitialized use analysis.
> + unsigned NumUninitAnalysisBlockVisits;
> +
> + /// \brief Max number of block visits during uninitialized use analysis of
> + /// a single function.
> + unsigned MaxUninitAnalysisBlockVisitsPerFunction;
> +
> + /// @}
>
> public:
> AnalysisBasedWarnings(Sema &s);
> @@ -57,6 +92,8 @@
> const Decl *D, const BlockExpr *blkExpr);
>
> Policy getDefaultPolicy() { return DefaultPolicy; }
> +
> + void PrintStats() const;
> };
>
> }} // end namespace clang::sema
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Wed Jul 6 11:21:37 2011
> @@ -193,6 +193,9 @@
> Diagnostic &Diags;
> SourceManager &SourceMgr;
>
> + /// \brief Flag indicating whether or not to collect detailed statistics.
> + bool CollectStats;
> +
> /// \brief Source of additional semantic information.
> ExternalSemaSource *ExternalSource;
>
> @@ -689,7 +692,9 @@
> ASTContext &getASTContext() const { return Context; }
> ASTConsumer &getASTConsumer() const { return Consumer; }
> ASTMutationListener *getASTMutationListener() const;
> -
> +
> + void PrintStats() const;
> +
> /// \brief Helper class that creates diagnostics with optional
> /// template instantiation stacks.
> ///
> @@ -5849,8 +5854,6 @@
> llvm::SmallVectorImpl<CodeCompletionResult> &Results);
> //@}
>
> - void PrintStats() const {}
> -
> //===--------------------------------------------------------------------===//
> // Extra semantic analysis beyond the C type system
>
>
> Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UninitializedValues.cpp?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Analysis/UninitializedValues.cpp (original)
> +++ cfe/trunk/lib/Analysis/UninitializedValues.cpp Wed Jul 6 11:21:37 2011
> @@ -654,15 +654,19 @@
> return vals.updateValueVectorWithScratch(block);
> }
>
> -void clang::runUninitializedVariablesAnalysis(const DeclContext &dc,
> - const CFG &cfg,
> - AnalysisContext &ac,
> - UninitVariablesHandler &handler) {
> +void clang::runUninitializedVariablesAnalysis(
> + const DeclContext &dc,
> + const CFG &cfg,
> + AnalysisContext &ac,
> + UninitVariablesHandler &handler,
> + UninitVariablesAnalysisStats &stats) {
> CFGBlockValues vals(cfg);
> vals.computeSetOfDeclarations(dc);
> if (vals.hasNoDeclarations())
> return;
>
> + stats.NumVariablesAnalyzed = vals.getNumEntries();
> +
> // Mark all variables uninitialized at the entry.
> const CFGBlock &entry = cfg.getEntry();
> for (CFGBlock::const_succ_iterator i = entry.succ_begin(),
> @@ -684,7 +688,8 @@
>
> while (const CFGBlock *block = worklist.dequeue()) {
> // Did the block change?
> - bool changed = runOnBlock(block, cfg, ac, vals, wasAnalyzed);
> + bool changed = runOnBlock(block, cfg, ac, vals, wasAnalyzed);
> + ++stats.NumBlockVisits;
> if (changed || !previouslyVisited[block->getBlockID()])
> worklist.enqueueSuccessors(block);
> previouslyVisited[block->getBlockID()] = true;
> @@ -692,11 +697,12 @@
>
> // Run through the blocks one more time, and report uninitialized variabes.
> for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) {
> - if (wasAnalyzed[(*BI)->getBlockID()])
> + if (wasAnalyzed[(*BI)->getBlockID()]) {
> runOnBlock(*BI, cfg, ac, vals, wasAnalyzed, &handler,
> /* flagBlockUses */ true);
> + ++stats.NumBlockVisits;
> + }
> }
> }
>
> UninitVariablesHandler::~UninitVariablesHandler() {}
> -
>
> Modified: cfe/trunk/lib/Parse/ParseAST.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseAST.cpp?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseAST.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseAST.cpp Wed Jul 6 11:21:37 2011
> @@ -57,6 +57,10 @@
> Stmt::CollectingStats(true);
> }
>
> + // Also turn on collection of stats inside of the Sema object.
> + bool OldCollectStats = PrintStats;
> + std::swap(OldCollectStats, S.CollectStats);
> +
> ASTConsumer *Consumer = &S.getASTConsumer();
>
> llvm::OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S));
> @@ -95,7 +99,8 @@
> Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
>
> Consumer->HandleTranslationUnit(S.getASTContext());
> -
> +
> + std::swap(OldCollectStats, S.CollectStats);
> if (PrintStats) {
> llvm::errs() << "\nSTATISTICS:\n";
> P.getActions().PrintStats();
>
> Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
> +++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Wed Jul 6 11:21:37 2011
> @@ -597,7 +597,11 @@
> 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 @@
> != 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";
> }
>
> Modified: cfe/trunk/lib/Sema/Sema.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=134494&r1=134493&r2=134494&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/Sema.cpp (original)
> +++ cfe/trunk/lib/Sema/Sema.cpp Wed Jul 6 11:21:37 2011
> @@ -141,8 +141,8 @@
> : TheTargetAttributesSema(0), FPFeatures(pp.getLangOptions()),
> LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
> Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
> - ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0),
> - PackContext(0), MSStructPragmaOn(false), VisContext(0),
> + CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter),
> + CurContext(0), PackContext(0), MSStructPragmaOn(false), VisContext(0),
> ExprNeedsCleanups(0), LateTemplateParser(0), OpaqueParser(0),
> IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
> GlobalNewDeleteDeclared(false),
> @@ -234,6 +234,15 @@
> return getASTConsumer().GetASTMutationListener();
> }
>
> +/// \brief Print out statistics about the semantic analysis.
> +void Sema::PrintStats() const {
> + llvm::errs() << "\n*** Semantic Analysis Stats:\n";
> + llvm::errs() << NumSFINAEErrors << " SFINAE diagnostics trapped.\n";
> +
> + BumpAlloc.PrintStats();
> + AnalysisWarnings.PrintStats();
> +}
> +
> /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
> /// If there is already an implicit cast, merge into the existing one.
> /// The result is of the given category.
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list