[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