Awesome! Sent from my iPad
On Jul 6, 2011, at 9:21 AM, Chandler Carruth <[email protected]> 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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
