From: Ted Kremenek Date: Thu, 10 Nov 2011 23:26:10 +0000 (+0000) Subject: [static analyzer]: only call RemoveDeadBindings() when analyzing non-Expr stmts,... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce117a7d289f57f792e5cc3294280cfe070433de;p=clang [static analyzer]: only call RemoveDeadBindings() when analyzing non-Expr stmts, entering a basic block, or analyzing non-consumed expressions. This sigificantly speeds up analysis time, and reduces analysis time down to 27% less than before we linearized the CFG. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144332 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 32cfa847e9..eeb3451384 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -220,6 +220,29 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, currentBuilderContext = 0; } +static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, + const CFGStmt S, + const ExplodedNode *Pred, + const LocationContext *LC) { + + // Are we never purging state values? + if (AMgr.getPurgeMode() == PurgeNone) + return false; + + // Is this the beginning of a basic block? + if (!isa(Pred->getLocation())) + return true; + + // Is this on a non-expression? + if (!isa(S.getStmt())) + return true; + + // Is this an expression that is consumed by another expression? If so, + // postpone cleaning out the state. + ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap(); + return !PM.isConsumedExpr(cast(S.getStmt())); +} + void ExprEngine::ProcessStmt(const CFGStmt S, ExplodedNode *Pred) { // TODO: Use RAII to remove the unnecessary, tagged nodes. @@ -244,7 +267,7 @@ void ExprEngine::ProcessStmt(const CFGStmt S, const LocationContext *LC = EntryNode->getLocationContext(); SymbolReaper SymReaper(LC, currentStmt, SymMgr, getStoreManager()); - if (AMgr.getPurgeMode() != PurgeNone) { + if (shouldRemoveDeadBindings(AMgr, S, Pred, LC)) { getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper); const StackFrameContext *SFC = LC->getCurrentStackFrame();