]> granicus.if.org Git - clang/commitdiff
[analyzer] Replace -analyzer-no-eagerly-trim-egraph with graph-trim-interval.
authorJordan Rose <jordan_rose@apple.com>
Tue, 23 Oct 2012 23:59:05 +0000 (23:59 +0000)
committerJordan Rose <jordan_rose@apple.com>
Tue, 23 Oct 2012 23:59:05 +0000 (23:59 +0000)
After every 1000 CFGElements processed, the ExplodedGraph trims out nodes
that satisfy a number of criteria for being "boring" (single predecessor,
single successor, and more). Rather than controlling this with a cc1 option,
which can only disable this behavior, we now have an analyzer-config option,
'graph-trim-interval', which can change this interval from 1000 to something
else. Setting the value to 0 disables reclamation.

The next commit relies on this behavior to actually test anything.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166528 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
lib/Frontend/CompilerInvocation.cpp
lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
lib/StaticAnalyzer/Core/ExplodedGraph.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/analyzer-config.c
test/Analysis/analyzer-config.cpp

index e260beab815e892bd8a27105ed0857a691cc3ed8..0c54ecc50a7c29f43997960780ebcad71dbdf9b9 100644 (file)
@@ -69,8 +69,6 @@ def analyze_function : Separate<["-"], "analyze-function">,
 def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias<analyze_function>;
 def analyzer_eagerly_assume : Flag<["-"], "analyzer-eagerly-assume">,
   HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">;
-def analyzer_no_eagerly_trim_egraph : Flag<["-"], "analyzer-no-eagerly-trim-egraph">,
-  HelpText<"Don't eagerly remove uninteresting ExplodedNodes from the ExplodedGraph">;
 def trim_egraph : Flag<["-"], "trim-egraph">,
   HelpText<"Only show error-related paths in the analysis graph">;
 def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">,
index 4c11a675af716b3742cbe73422588610d2c717f1..ac30836561750bbe0cd406ee77043b1938c1ecaa 100644 (file)
@@ -149,7 +149,6 @@ public:
   unsigned visualizeExplodedGraphWithGraphViz : 1;
   unsigned visualizeExplodedGraphWithUbiGraph : 1;
   unsigned UnoptimizedCFG : 1;
-  unsigned eagerlyTrimExplodedGraph : 1;
   unsigned PrintStats : 1;
   
   /// \brief Do not re-analyze paths leading to exhausted nodes with a different
@@ -188,6 +187,9 @@ private:
   /// \sa shouldPruneNullReturnPaths
   llvm::Optional<bool> PruneNullReturnPaths;
 
+  /// \sa getGraphTrimInterval
+  llvm::Optional<unsigned> GraphTrimInterval;
+
   /// Interprets an option's string value as a boolean.
   ///
   /// Accepts the strings "true" and "false".
@@ -253,6 +255,13 @@ public:
   /// for well-known functions.
   bool shouldSynthesizeBodies();
 
+  /// Returns how often nodes in the ExplodedGraph should be recycled to save
+  /// memory.
+  ///
+  /// This is controlled by the 'graph-trim-interval' config option. To disable
+  /// node reclamation, set the option to "0".
+  unsigned getGraphTrimInterval();
+
 public:
   AnalyzerOptions() : CXXMemberInliningMode() {
     AnalysisStoreOpt = RegionStoreModel;
@@ -269,7 +278,6 @@ public:
     visualizeExplodedGraphWithGraphViz = 0;
     visualizeExplodedGraphWithUbiGraph = 0;
     UnoptimizedCFG = 0;
-    eagerlyTrimExplodedGraph = 0;
     PrintStats = 0;
     NoRetryExhausted = 0;
     // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
index 5ce219b4ed035ca0bc2d122cb4b967dbb6cae711..b112e66d30d383ad266559f3d06993cab77694d3 100644 (file)
@@ -282,11 +282,13 @@ protected:
   /// A list of nodes that can be reused.
   NodeVector FreeNodes;
   
-  /// A flag that indicates whether nodes should be recycled.
-  bool reclaimNodes;
+  /// Determines how often nodes are reclaimed.
+  ///
+  /// If this is 0, nodes will never be reclaimed.
+  unsigned ReclaimNodeInterval;
   
   /// Counter to determine when to reclaim nodes.
-  unsigned reclaimCounter;
+  unsigned ReclaimCounter;
 
 public:
 
@@ -374,7 +376,9 @@ public:
 
   /// Enable tracking of recently allocated nodes for potential reclamation
   /// when calling reclaimRecentlyAllocatedNodes().
-  void enableNodeReclamation() { reclaimNodes = true; }
+  void enableNodeReclamation(unsigned Interval) {
+    ReclaimCounter = ReclaimNodeInterval = Interval;
+  }
 
   /// Reclaim "uninteresting" nodes created since the last time this method
   /// was called.
index ae11805a0eea8db5de7461ebce06501b688082b5..aad63b6de3cfc675b069cbd1689b3d64988b67c9 100644 (file)
@@ -1138,7 +1138,6 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
   Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
   Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
   Opts.maxBlockVisitOnPath = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);
-  Opts.eagerlyTrimExplodedGraph = !Args.hasArg(OPT_analyzer_no_eagerly_trim_egraph);
   Opts.PrintStats = Args.hasArg(OPT_analyzer_stats);
   Opts.InlineMaxStackDepth =
     Args.getLastArgIntValue(OPT_analyzer_inline_max_stack_depth,
index e2b7cfc521f01fe349fbbf3f062a2a80d529f5a4..32073d726d941ab777707988c8c91f41dbec4a5a 100644 (file)
@@ -121,6 +121,12 @@ unsigned AnalyzerOptions::getAlwaysInlineSize() {
   return AlwaysInlineSize.getValue();
 }
 
+unsigned AnalyzerOptions::getGraphTrimInterval() {
+  if (!GraphTrimInterval.hasValue())
+    GraphTrimInterval = getOptionAsInteger("graph-trim-interval", 1000);
+  return GraphTrimInterval.getValue();
+}
+
 bool AnalyzerOptions::shouldSynthesizeBodies() {
   return getBooleanOption("faux-bodies", true);
 }
index 39440ccc0a4bb20d377f616c2186885fbc96b2a5..9b70d6861cccad333f2f1c7fe990fdab8e76a060 100644 (file)
@@ -47,10 +47,8 @@ void ExplodedNode::SetAuditor(ExplodedNode::Auditor* A) {
 // Cleanup.
 //===----------------------------------------------------------------------===//
 
-static const unsigned CounterTop = 1000;
-
 ExplodedGraph::ExplodedGraph()
-  : NumNodes(0), reclaimNodes(false), reclaimCounter(CounterTop) {}
+  : NumNodes(0), ReclaimNodeInterval(0) {}
 
 ExplodedGraph::~ExplodedGraph() {}
 
@@ -144,13 +142,13 @@ void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
   if (ChangedNodes.empty())
     return;
 
-  // Only periodically relcaim nodes so that we can build up a set of
+  // Only periodically reclaim nodes so that we can build up a set of
   // nodes that meet the reclamation criteria.  Freshly created nodes
   // by definition have no successor, and thus cannot be reclaimed (see below).
-  assert(reclaimCounter > 0);
-  if (--reclaimCounter != 0)
+  assert(ReclaimCounter > 0);
+  if (--ReclaimCounter != 0)
     return;
-  reclaimCounter = CounterTop;
+  ReclaimCounter = ReclaimNodeInterval;
 
   for (NodeVector::iterator it = ChangedNodes.begin(), et = ChangedNodes.end();
        it != et; ++it) {
@@ -284,7 +282,7 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
 
     new (V) NodeTy(L, State, IsSink);
 
-    if (reclaimNodes)
+    if (ReclaimNodeInterval)
       ChangedNodes.push_back(V);
 
     // Insert the node into the node set and return it.
index 213ab7ad5cc869cdcc40f7b18b4a4887029df31f..08f8405c4b2b097a10040eaa4aaf6c6cd9238d66 100644 (file)
@@ -72,10 +72,11 @@ ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
     ObjCGCEnabled(gcEnabled), BR(mgr, *this),
     VisitedCallees(VisitedCalleesIn)
 {
-    if (mgr.options.eagerlyTrimExplodedGraph) {
-      // Enable eager node reclaimation when constructing the ExplodedGraph.
-      G.enableNodeReclamation();
-    }
+  unsigned TrimInterval = mgr.options.getGraphTrimInterval();
+  if (TrimInterval != 0) {
+    // Enable eager node reclaimation when constructing the ExplodedGraph.
+    G.enableNodeReclamation(TrimInterval);
+  }
 }
 
 ExprEngine::~ExprEngine() {
index e9cfd0d3e65bdff1a5f7256d8c9acf285d694ffc..990f5784b42bed538613ef7e716d6deaa887a583 100644 (file)
@@ -7,6 +7,7 @@ void foo() { bar(); }
 // CHECK: [config]
 // CHECK-NEXT: cfg-temporary-dtors = false
 // CHECK-NEXT: faux-bodies = true
+// CHECK-NEXT: graph-trim-interval = 1000
 // CHECK-NEXT: ipa-always-inline-size = 3
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 3
+// CHECK-NEXT: num-entries = 4
index 414324e8bc364e8f97ca4ad8cd1bf2bc131e9f72..fb142669b428e05856877496f25d5b687b85c9b8 100644 (file)
@@ -16,6 +16,7 @@ public:
 // CHECK-NEXT: c++-template-inlining = true
 // CHECK-NEXT: cfg-temporary-dtors = false
 // CHECK-NEXT: faux-bodies = true
+// CHECK-NEXT: graph-trim-interval = 1000
 // CHECK-NEXT: ipa-always-inline-size = 3
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 6
+// CHECK-NEXT: num-entries = 7