diff options
author | Anna Zaks <ganna@apple.com> | 2012-09-10 22:37:19 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-09-10 22:37:19 +0000 |
commit | 14ce52492f4002c743e27dca48d02e7e9bfcf61c (patch) | |
tree | fd58a8a4e5ba34482f59bf39d4f7521f4910b701 /clang/lib/StaticAnalyzer | |
parent | 41ff85d7541960a7b5bec74c15835d48881a9a3a (diff) | |
download | bcm5719-llvm-14ce52492f4002c743e27dca48d02e7e9bfcf61c.tar.gz bcm5719-llvm-14ce52492f4002c743e27dca48d02e7e9bfcf61c.zip |
[analyzer] Add ipa-always-inline-size option (with 3 as the default).
The option allows to always inline very small functions, whose size (in
number of basic blocks) is set using -analyzer-config
ipa-always-inline-size option.
llvm-svn: 163558
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 24 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 22 |
2 files changed, 39 insertions, 7 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 29e27834763..5cbbb8d4628 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/StringSwitch.h" using namespace clang; +using namespace llvm; bool AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const { @@ -80,3 +81,26 @@ bool AnalyzerOptions::mayInlineTemplateFunctions() const { return *InlineTemplateFunctions; } + +int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) const { + std::string OptStr = Config.lookup(Name); + if (OptStr.empty()) + return DefaultVal; + + int Res = DefaultVal; + assert(StringRef(OptStr).getAsInteger(10, Res) == false && + "analyzer-config option should be numeric."); + + return Res; +} + +unsigned AnalyzerOptions::getAlwaysInlineSize() const { + if (!AlwaysInlineSize.hasValue()) { + unsigned DefaultSize = 3; + Optional<unsigned> &MutableOption = + const_cast<Optional<unsigned> &>(AlwaysInlineSize); + MutableOption = getOptionAsInteger("ipa-always-inline-size", DefaultSize); + } + + return AlwaysInlineSize.getValue(); +} diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 9bf63c5b961..a4e1eb2f4cc 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -247,14 +247,18 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { } } -static unsigned getNumberStackFrames(const LocationContext *LCtx) { - unsigned count = 0; +static void examineStackFrames(const Decl *D, const LocationContext *LCtx, + bool &IsRecursive, unsigned &StackDepth) { + IsRecursive = false; + StackDepth = 0; while (LCtx) { - if (isa<StackFrameContext>(LCtx)) - ++count; + if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LCtx)) { + ++StackDepth; + if (SFC->getDecl() == D) + IsRecursive = true; + } LCtx = LCtx->getParent(); } - return count; } static bool IsInStdNamespace(const FunctionDecl *FD) { @@ -282,8 +286,12 @@ bool ExprEngine::shouldInlineDecl(const Decl *D, ExplodedNode *Pred) { if (!CalleeCFG) return false; - if (getNumberStackFrames(Pred->getLocationContext()) - == AMgr.options.InlineMaxStackDepth) + bool IsRecursive = false; + unsigned StackDepth = 0; + examineStackFrames(D, Pred->getLocationContext(), IsRecursive, StackDepth); + if ((StackDepth >= AMgr.options.InlineMaxStackDepth) && + ((CalleeCFG->getNumBlockIDs() > AMgr.options.getAlwaysInlineSize()) + || IsRecursive)) return false; if (Engine.FunctionSummaries->hasReachedMaxBlockCount(D)) |