]> granicus.if.org Git - clang/commitdiff
[analyzer] Make shallow mode more shallow.
authorAnna Zaks <ganna@apple.com>
Wed, 30 Jan 2013 19:12:39 +0000 (19:12 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 30 Jan 2013 19:12:39 +0000 (19:12 +0000)
Redefine the shallow mode to inline all functions for which we have a
definite definition (ipa=inlining). However, only inline functions that
are up to 4 basic blocks large and cut the max exploded nodes generated
per top level function in half.

This makes shallow faster and allows us to keep inlining small
functions. For example, we would keep inlining wrapper functions and
constructors/destructors.

With the new shallow, it takes 104s to analyze sqlite3, whereas
the deep mode is 658s and previous shallow is 209s.

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

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

index fa3e56fe754ec38690f2542291c07fe6afffa8ac..f84f177197eddf797c0ba4bf26622ff618d9f6e7 100644 (file)
@@ -88,8 +88,6 @@ def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<
 def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">,
   HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">;
   
-def analyzer_max_nodes : Separate<["-"], "analyzer-max-nodes">,
-  HelpText<"The maximum number of nodes the analyzer can generate (150000 default, 0 = no limit)">;
 def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">,
   HelpText<"The maximum number of times the analyzer will go through a loop">;
 def analyzer_stats : Flag<["-"], "analyzer-stats">,
index 9b9749df98951fc75386c4a74204df6fb6cbf7c1..e1fe0820497c887894ae059950e4589125407908 100644 (file)
@@ -132,9 +132,6 @@ public:
   
   std::string AnalyzeSpecificFunction;
   
-  /// \brief The maximum number of exploded nodes the analyzer will generate.
-  unsigned MaxNodes;
-  
   /// \brief The maximum number of times the analyzer visits a block.
   unsigned maxBlockVisitOnPath;
   
@@ -223,6 +220,9 @@ private:
   /// \sa getMaxTimesInlineLarge
   llvm::Optional<unsigned> MaxTimesInlineLarge;
 
+  /// \sa getMaxNodesPerTopLevelFunction
+  llvm::Optional<unsigned> MaxNodesPerTopLevelFunction;
+
   /// Interprets an option's string value as a boolean.
   ///
   /// Accepts the strings "true" and "false".
@@ -332,6 +332,13 @@ public:
   /// This is controlled by the 'max-times-inline-large' config option.
   unsigned getMaxTimesInlineLarge();
 
+  /// Returns the maximum number of nodes the analyzer can generate while
+  /// exploring a top level function (for each exploded graph).
+  /// 150000 is default; 0 means no limit.
+  ///
+  /// This is controlled by the 'max-nodes' config option.
+  unsigned getMaxNodesPerTopLevelFunction();
+
 public:
   AnalyzerOptions() :
     AnalysisStoreOpt(RegionStoreModel),
index ae240577d124b18a08a5444b8869125ff97269ca..a2b28bc53910329cf9e7efa985c14bbadee3dce8 100644 (file)
@@ -218,7 +218,6 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
   Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
   Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
   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.PrintStats = Args.hasArg(OPT_analyzer_stats);
   Opts.InlineMaxStackDepth =
index d90b48d998e0a6b5e9a0cfdb284de2dbf7e349ff..cb02e94d603e53f3fa16e08ee4823f03b2439702 100644 (file)
@@ -15,6 +15,7 @@
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -41,7 +42,7 @@ IPAKind AnalyzerOptions::getIPAMode() {
     const char *DefaultIPA = 0;
     UserModeKind HighLevelMode = getUserMode();
     if (HighLevelMode == UMK_Shallow)
-      DefaultIPA = "basic-inlining";
+      DefaultIPA = "inlining";
     else if (HighLevelMode == UMK_Deep)
       DefaultIPA = "dynamic-bifurcate";
     assert(DefaultIPA);
@@ -172,8 +173,23 @@ unsigned AnalyzerOptions::getAlwaysInlineSize() {
 }
 
 unsigned AnalyzerOptions::getMaxInlinableSize() {
-  if (!MaxInlinableSize.hasValue())
-    MaxInlinableSize = getOptionAsInteger("max-inlinable-size", 50);
+  if (!MaxInlinableSize.hasValue()) {
+
+    int DefaultValue = 0;
+    UserModeKind HighLevelMode = getUserMode();
+    switch (HighLevelMode) {
+      default:
+        llvm_unreachable("Invalid mode.");
+      case UMK_Shallow:
+        DefaultValue = 4;
+        break;
+      case UMK_Deep:
+        DefaultValue = 50;
+        break;
+    }
+
+    MaxInlinableSize = getOptionAsInteger("max-inlinable-size", DefaultValue);
+  }
   return MaxInlinableSize.getValue();
 }
 
@@ -189,6 +205,25 @@ unsigned AnalyzerOptions::getMaxTimesInlineLarge() {
   return MaxTimesInlineLarge.getValue();
 }
 
+unsigned AnalyzerOptions::getMaxNodesPerTopLevelFunction() {
+  if (!MaxNodesPerTopLevelFunction.hasValue()) {
+    int DefaultValue = 0;
+    UserModeKind HighLevelMode = getUserMode();
+    switch (HighLevelMode) {
+      default:
+        llvm_unreachable("Invalid mode.");
+      case UMK_Shallow:
+        DefaultValue = 75000;
+        break;
+      case UMK_Deep:
+        DefaultValue = 150000;
+        break;
+    }
+    MaxNodesPerTopLevelFunction = getOptionAsInteger("max-nodes", DefaultValue);
+  }
+  return MaxNodesPerTopLevelFunction.getValue();
+}
+
 bool AnalyzerOptions::shouldSynthesizeBodies() {
   return getBooleanOption("faux-bodies", true);
 }
index c2c5256d9ce1e06d512c20d365e97b36724b0509..a3195305525b53ea4c6eed032fe82fdbaafcdcf7 100644 (file)
@@ -616,7 +616,7 @@ void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
 
   // Execute the worklist algorithm.
   Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
-                      Mgr->options.MaxNodes);
+                      Mgr->options.getMaxNodesPerTopLevelFunction());
 
   // Release the auditor (if any) so that it doesn't monitor the graph
   // created BugReporter.
index 9d99b0a425dd572db90860a908a2f0e1689def41..7fa299b786e2216756b484bd5915aca325b2e9df 100644 (file)
@@ -11,7 +11,8 @@ void foo() { bar(); }
 // CHECK-NEXT: ipa = dynamic-bifurcate
 // CHECK-NEXT: ipa-always-inline-size = 3
 // CHECK-NEXT: max-inlinable-size = 50
+// CHECK-NEXT: max-nodes = 150000
 // CHECK-NEXT: max-times-inline-large = 32
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 8
+// CHECK-NEXT: num-entries = 9
index dafc86fe862a10904e59b3345b1fa048940eaa80..52700176b20499018e09c2dc8edfc742ecdc0d36 100644 (file)
@@ -20,7 +20,8 @@ public:
 // CHECK-NEXT: ipa = dynamic-bifurcate
 // CHECK-NEXT: ipa-always-inline-size = 3
 // CHECK-NEXT: max-inlinable-size = 50
+// CHECK-NEXT: max-nodes = 150000
 // CHECK-NEXT: max-times-inline-large = 32
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 11
+// CHECK-NEXT: num-entries = 12