diff options
| author | Devin Coughlin <dcoughlin@apple.com> | 2015-09-11 20:14:05 +0000 |
|---|---|---|
| committer | Devin Coughlin <dcoughlin@apple.com> | 2015-09-11 20:14:05 +0000 |
| commit | 0123af994ec5f46bd705c11b17fc14a2fefc4726 (patch) | |
| tree | 65317fb1e9458c81c1edbea44d8db625b39d5b8a | |
| parent | 822e2887b956a1aa4c72a5920c7d060d1472c88b (diff) | |
| download | bcm5719-llvm-0123af994ec5f46bd705c11b17fc14a2fefc4726.tar.gz bcm5719-llvm-0123af994ec5f46bd705c11b17fc14a2fefc4726.zip | |
[analyzer] Add -analyzer-config option for function size the inliner considers as large
Add an option (-analyzer-config min-blocks-for-inline-large=14) to control the function
size the inliner considers as large, in relation to "max-times-inline-large". The option
defaults to the original hard coded behaviour, which I believe should be adjustable with
the other inlining settings.
The analyzer-config test has been modified so that the analyzer will reach the
getMinBlocksForInlineLarge() method and store the result in the ConfigTable, to ensure it
is dumped by the debug checker.
A patch by Sean Eveson!
Differential Revision: http://reviews.llvm.org/D12406
llvm-svn: 247463
| -rw-r--r-- | clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h | 10 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 3 | ||||
| -rw-r--r-- | clang/test/Analysis/analyzer-config.c | 14 | ||||
| -rw-r--r-- | clang/test/Analysis/analyzer-config.cpp | 14 |
5 files changed, 41 insertions, 7 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index be212336a69..a6e56107150 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -253,6 +253,9 @@ private: /// \sa getMaxTimesInlineLarge Optional<unsigned> MaxTimesInlineLarge; + /// \sa getMinCFGSizeTreatFunctionsAsLarge + Optional<unsigned> MinCFGSizeTreatFunctionsAsLarge; + /// \sa getMaxNodesPerTopLevelFunction Optional<unsigned> MaxNodesPerTopLevelFunction; @@ -505,6 +508,13 @@ public: /// This is controlled by the 'max-times-inline-large' config option. unsigned getMaxTimesInlineLarge(); + /// Returns the number of basic blocks a function needs to have to be + /// considered large for the 'max-times-inline-large' config option. + /// + /// This is controlled by the 'min-cfg-size-treat-functions-as-large' config + /// option. + unsigned getMinCFGSizeTreatFunctionsAsLarge(); + /// 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. diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 93133ef4c4b..8b31a0db531 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -295,6 +295,13 @@ unsigned AnalyzerOptions::getMaxTimesInlineLarge() { return MaxTimesInlineLarge.getValue(); } +unsigned AnalyzerOptions::getMinCFGSizeTreatFunctionsAsLarge() { + if (!MinCFGSizeTreatFunctionsAsLarge.hasValue()) + MinCFGSizeTreatFunctionsAsLarge = getOptionAsInteger( + "min-cfg-size-treat-functions-as-large", 14); + return MinCFGSizeTreatFunctionsAsLarge.getValue(); +} + unsigned AnalyzerOptions::getMaxNodesPerTopLevelFunction() { if (!MaxNodesPerTopLevelFunction.hasValue()) { int DefaultValue = 0; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 5b6ce7ad95e..25c0cf29bcb 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -870,7 +870,8 @@ bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D, // Do not inline large functions too many times. if ((Engine.FunctionSummaries->getNumTimesInlined(D) > Opts.getMaxTimesInlineLarge()) && - CalleeCFG->getNumBlockIDs() > 13) { + CalleeCFG->getNumBlockIDs() >= + Opts.getMinCFGSizeTreatFunctionsAsLarge()) { NumReachedInlineCountMax++; return false; } diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c index 55b1df9ca8a..5fe53249d77 100644 --- a/clang/test/Analysis/analyzer-config.c +++ b/clang/test/Analysis/analyzer-config.c @@ -1,22 +1,30 @@ -// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1 +// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper -Xclang -analyzer-max-loop -Xclang 34 > %t 2>&1 // RUN: FileCheck --input-file=%t %s void bar() {} -void foo() { bar(); } +void foo() { + // Call bar 33 times so max-times-inline-large is met and + // min-blocks-for-inline-large is checked + for (int i = 0; i < 34; ++i) { + bar(); + } +} // CHECK: [config] // CHECK-NEXT: cfg-conditional-static-initializers = true // CHECK-NEXT: cfg-temporary-dtors = false // CHECK-NEXT: faux-bodies = true // CHECK-NEXT: graph-trim-interval = 1000 +// CHECK-NEXT: inline-lambdas = true // CHECK-NEXT: ipa = dynamic-bifurcate // CHECK-NEXT: ipa-always-inline-size = 3 // CHECK-NEXT: leak-diagnostics-reference-allocation = false // CHECK-NEXT: max-inlinable-size = 50 // CHECK-NEXT: max-nodes = 150000 // CHECK-NEXT: max-times-inline-large = 32 +// CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep // CHECK-NEXT: region-store-small-struct-limit = 2 // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 12 +// CHECK-NEXT: num-entries = 14 diff --git a/clang/test/Analysis/analyzer-config.cpp b/clang/test/Analysis/analyzer-config.cpp index 521344a5119..57913321f42 100644 --- a/clang/test/Analysis/analyzer-config.cpp +++ b/clang/test/Analysis/analyzer-config.cpp @@ -1,8 +1,14 @@ -// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper > %t 2>&1 +// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper -Xclang -analyzer-max-loop -Xclang 34 > %t 2>&1 // RUN: FileCheck --input-file=%t %s void bar() {} -void foo() { bar(); } +void foo() { + // Call bar 33 times so max-times-inline-large is met and + // min-blocks-for-inline-large is checked + for (int i = 0; i < 34; ++i) { + bar(); + } +} class Foo { public: @@ -20,13 +26,15 @@ public: // CHECK-NEXT: cfg-temporary-dtors = false // CHECK-NEXT: faux-bodies = true // CHECK-NEXT: graph-trim-interval = 1000 +// CHECK-NEXT: inline-lambdas = true // CHECK-NEXT: ipa = dynamic-bifurcate // CHECK-NEXT: ipa-always-inline-size = 3 // CHECK-NEXT: leak-diagnostics-reference-allocation = false // CHECK-NEXT: max-inlinable-size = 50 // CHECK-NEXT: max-nodes = 150000 // CHECK-NEXT: max-times-inline-large = 32 +// CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep // CHECK-NEXT: region-store-small-struct-limit = 2 // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 17 +// CHECK-NEXT: num-entries = 19 |

