[cfe-commits] r153923 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/ lib/StaticAnalyzer/Core/ lib/StaticAnalyzer/Frontend/ test/Analysis/

Anna Zaks ganna at apple.com
Mon Apr 2 19:05:48 PDT 2012


Author: zaks
Date: Mon Apr  2 21:05:47 2012
New Revision: 153923

URL: http://llvm.org/viewvc/llvm-project?rev=153923&view=rev
Log:
[analyzer] Record the basic blocks covered by the analyzes run.

Store this info inside the function summary generated for all analyzed
functions. This is useful for coverage stats and can be helpful for
analyzer state space search strategies.

Added:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
    cfe/trunk/lib/StaticAnalyzer/Core/FunctionSummary.cpp
Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
    cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
    cfe/trunk/test/Analysis/stats.c

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h Mon Apr  2 21:05:47 2012
@@ -30,33 +30,6 @@
 namespace ento {
   class CheckerManager;
 
-typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls;
-
-class FunctionSummariesTy {
-  struct FunctionSummary {
-    /// True if this function has reached a max block count while inlined from
-    /// at least one call site.
-    bool MayReachMaxBlockCount;
-    FunctionSummary() : MayReachMaxBlockCount(false) {}
-  };
-
-  typedef llvm::DenseMap<const Decl*, FunctionSummary> MapTy;
-  MapTy Map;
-
-public:
-  void markReachedMaxBlockCount(const Decl* D) {
-    Map[D].MayReachMaxBlockCount = true;
-  }
-
-  bool hasReachedMaxBlockCount(const Decl* D) {
-  MapTy::const_iterator I = Map.find(D);
-    if (I != Map.end())
-      return I->second.MayReachMaxBlockCount;
-    return false;
-  }
-
-};
-
 class AnalysisManager : public BugReporterData {
   virtual void anchor();
   AnalysisDeclContextManager AnaCtxMgr;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Mon Apr  2 21:05:47 2012
@@ -18,6 +18,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -83,6 +84,10 @@
   /// AnalysisConsumer. It can be null.
   SetOfDecls *AnalyzedCallees;
 
+  /// The information about functions shared by the whole translation unit.
+  /// (This data is owned by AnalysisConsumer.)
+  FunctionSummariesTy *FunctionSummaries;
+
   void generateNode(const ProgramPoint &Loc,
                     ProgramStateRef State,
                     ExplodedNode *Pred);
@@ -104,11 +109,13 @@
 public:
   /// Construct a CoreEngine object to analyze the provided CFG using
   ///  a DFS exploration of the exploded graph.
-  CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees)
+  CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees,
+             FunctionSummariesTy *FS)
     : SubEng(subengine), G(new ExplodedGraph()),
       WList(WorkList::makeBFS()),
       BCounterFactory(G->getAllocator()),
-      AnalyzedCallees(VisitedCallees) {}
+      AnalyzedCallees(VisitedCallees),
+      FunctionSummaries(FS){}
 
   ~CoreEngine() {
     delete WList;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon Apr  2 21:05:47 2012
@@ -90,10 +90,6 @@
   ///  destructor is called before the rest of the ExprEngine is destroyed.
   GRBugReporter BR;
 
-  /// The information about functions shared by the whole translation unit.
-  /// (This data is owned by AnalysisConsumer.)
-  FunctionSummariesTy *FunctionSummaries;
-
 public:
   ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfDecls *VisitedCallees,
              FunctionSummariesTy *FS);

Added: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h?rev=153923&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h (added)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h Mon Apr  2 21:05:47 2012
@@ -0,0 +1,96 @@
+//== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a summary of a function gathered/used by static analyzes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H
+#define LLVM_CLANG_GR_FUNCTIONSUMMARY_H
+
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/BitVector.h"
+
+namespace clang {
+namespace ento {
+typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls;
+
+class FunctionSummariesTy {
+  struct FunctionSummary {
+    /// True if this function has reached a max block count while inlined from
+    /// at least one call site.
+    bool MayReachMaxBlockCount;
+
+    /// Total number of blocks in the function.
+    unsigned TotalBasicBlocks;
+
+    /// Marks the IDs of the basic blocks visited during the analyzes.
+    llvm::BitVector VisitedBasicBlocks;
+
+    FunctionSummary() :
+      MayReachMaxBlockCount(false),
+      TotalBasicBlocks(0),
+      VisitedBasicBlocks(0) {}
+  };
+
+  typedef llvm::DenseMap<const Decl*, FunctionSummary*> MapTy;
+  MapTy Map;
+
+public:
+  ~FunctionSummariesTy();
+
+  MapTy::iterator findOrInsertSummary(const Decl *D) {
+    MapTy::iterator I = Map.find(D);
+    if (I != Map.end())
+      return I;
+    FunctionSummary *DS = new FunctionSummary();
+    I = Map.insert(std::pair<const Decl*, FunctionSummary*>(D, DS)).first;
+    assert(I != Map.end());
+    return I;
+  }
+
+  void markReachedMaxBlockCount(const Decl* D) {
+    MapTy::iterator I = findOrInsertSummary(D);
+    I->second->MayReachMaxBlockCount = true;
+  }
+
+  bool hasReachedMaxBlockCount(const Decl* D) {
+  MapTy::const_iterator I = Map.find(D);
+    if (I != Map.end())
+      return I->second->MayReachMaxBlockCount;
+    return false;
+  }
+
+  void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
+    MapTy::iterator I = findOrInsertSummary(D);
+    llvm::BitVector &Blocks = I->second->VisitedBasicBlocks;
+    assert(ID < TotalIDs);
+    if (TotalIDs > Blocks.size()) {
+      Blocks.resize(TotalIDs);
+      I->second->TotalBasicBlocks = TotalIDs;
+    }
+    Blocks[ID] = true;
+  }
+
+  unsigned getNumVisitedBasicBlocks(const Decl* D) {
+    MapTy::const_iterator I = Map.find(D);
+      if (I != Map.end())
+        return I->second->VisitedBasicBlocks.count();
+    return 0;
+  }
+
+  unsigned getTotalNumBasicBlocks();
+  unsigned getTotalNumVisitedBasicBlocks();
+};
+
+}} // end clang ento namespaces
+
+#endif

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt Mon Apr  2 21:05:47 2012
@@ -22,6 +22,7 @@
   ExprEngineCXX.cpp
   ExprEngineCallAndReturn.cpp
   ExprEngineObjC.cpp
+  FunctionSummary.cpp
   HTMLDiagnostics.cpp
   MemRegion.cpp
   ObjCMessage.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Mon Apr  2 21:05:47 2012
@@ -174,6 +174,11 @@
     assert (Entry->succ_size() == 1 &&
             "Entry block must have 1 successor.");
 
+    // Mark the entry block as visited.
+    FunctionSummaries->markVisitedBasicBlock(Entry->getBlockID(),
+                                             L->getDecl(),
+                                             L->getCFG()->getNumBlockIDs());
+
     // Get the solitary successor.
     const CFGBlock *Succ = *(Entry->succ_begin());
 
@@ -280,6 +285,12 @@
   const CFGBlock *Blk = L.getDst();
   NodeBuilderContext BuilderCtx(*this, Blk, Pred);
 
+  // Mark this block as visited.
+  const LocationContext *LC = Pred->getLocationContext();
+  FunctionSummaries->markVisitedBasicBlock(Blk->getBlockID(),
+                                           LC->getDecl(),
+                                           LC->getCFG()->getNumBlockIDs());
+
   // Check if we are entering the EXIT block.
   if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
 
@@ -312,10 +323,11 @@
                                        ExplodedNode *Pred) {
 
   // Increment the block counter.
+  const LocationContext *LC = Pred->getLocationContext();
+  unsigned BlockId = L.getBlock()->getBlockID();
   BlockCounter Counter = WList->getBlockCounter();
-  Counter = BCounterFactory.IncrementCount(Counter, 
-                             Pred->getLocationContext()->getCurrentStackFrame(),
-                                           L.getBlock()->getBlockID());
+  Counter = BCounterFactory.IncrementCount(Counter, LC->getCurrentStackFrame(),
+                                           BlockId);
   WList->setBlockCounter(Counter);
 
   // Process the entrance of the block.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Apr  2 21:05:47 2012
@@ -71,7 +71,7 @@
                        FunctionSummariesTy *FS)
   : AMgr(mgr),
     AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
-    Engine(*this, VisitedCallees),
+    Engine(*this, VisitedCallees, FS),
     G(Engine.getGraph()),
     StateMgr(getContext(), mgr.getStoreManagerCreator(),
              mgr.getConstraintManagerCreator(), G.getAllocator(),
@@ -82,7 +82,7 @@
     currentStmt(NULL), currentStmtIdx(0), currentBuilderContext(0),
     NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
     RaiseSel(GetNullarySelector("raise", getContext())),
-    ObjCGCEnabled(gcEnabled), BR(mgr, *this), FunctionSummaries(FS) {
+    ObjCGCEnabled(gcEnabled), BR(mgr, *this) {
   
   if (mgr.shouldEagerlyTrimExplodedGraph()) {
     // Enable eager node reclaimation when constructing the ExplodedGraph.  
@@ -1051,7 +1051,7 @@
     const LocationContext *RootLC =
                         (*G.roots_begin())->getLocation().getLocationContext();
     if (RootLC->getCurrentStackFrame() != CalleeSF) {
-      FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
+      Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
 
       // Re-run the call evaluation without inlining it, by storing the
       // no-inlining policy in the state and enqueuing the new work item on

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Mon Apr  2 21:05:47 2012
@@ -138,7 +138,7 @@
         == AMgr.InlineMaxStackDepth)
     return false;
 
-  if (FunctionSummaries->hasReachedMaxBlockCount(FD))
+  if (Engine.FunctionSummaries->hasReachedMaxBlockCount(FD))
     return false;
 
   if (CalleeCFG->getNumBlockIDs() > AMgr.InlineMaxFunctionSize)

Added: cfe/trunk/lib/StaticAnalyzer/Core/FunctionSummary.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/FunctionSummary.cpp?rev=153923&view=auto
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/FunctionSummary.cpp (added)
+++ cfe/trunk/lib/StaticAnalyzer/Core/FunctionSummary.cpp Mon Apr  2 21:05:47 2012
@@ -0,0 +1,38 @@
+//== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a summary of a function gathered/used by static analyzes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
+using namespace clang;
+using namespace ento;
+
+FunctionSummariesTy::~FunctionSummariesTy() {
+  for (MapTy::iterator I = Map.begin(), E = Map.end(); I != E; ++I) {
+    delete(I->second);
+  }
+}
+
+unsigned FunctionSummariesTy::getTotalNumBasicBlocks() {
+  unsigned Total = 0;
+  for (MapTy::iterator I = Map.begin(), E = Map.end(); I != E; ++I) {
+    Total += I->second->TotalBasicBlocks;
+  }
+  return Total;
+}
+
+unsigned FunctionSummariesTy::getTotalNumVisitedBasicBlocks() {
+  unsigned Total = 0;
+  for (MapTy::iterator I = Map.begin(), E = Map.end(); I != E; ++I) {
+    Total += I->second->VisitedBasicBlocks.count();
+  }
+  return Total;
+}

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Mon Apr  2 21:05:47 2012
@@ -53,6 +53,9 @@
 
 STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
 STATISTIC(NumFunctionsAnalyzed, "The # of functions analysed (as top level).");
+STATISTIC(NumBlocksInAnalyzedFunctions,
+                     "The # of basic blocks in the analyzed functions.");
+STATISTIC(PercentReachableBlocks, "The % of reachable basic blocks.");
 
 //===----------------------------------------------------------------------===//
 // Special PathDiagnosticConsumers.
@@ -122,6 +125,13 @@
   }
 
   ~AnalysisConsumer() {
+    // Count how many basic blocks we have not covered.
+    NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks();
+    if (NumBlocksInAnalyzedFunctions > 0)
+      PercentReachableBlocks =
+        (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) /
+          NumBlocksInAnalyzedFunctions;
+
     if (Opts.PrintStats)
       delete TUTotalTimer;
   }

Modified: cfe/trunk/test/Analysis/stats.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/stats.c?rev=153923&r1=153922&r2=153923&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/stats.c (original)
+++ cfe/trunk/test/Analysis/stats.c Mon Apr  2 21:05:47 2012
@@ -4,4 +4,5 @@
   int x;
 }
 // CHECK: ... Statistics Collected ...
+// CHECK:100 AnalysisConsumer - The % of reachable basic blocks.
 // CHECK:The # of times RemoveDeadBindings is called





More information about the cfe-commits mailing list