[cfe-commits] r152440 - in /cfe/trunk: include/clang/Frontend/AnalyzerOptions.h include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h lib/Frontend/CompilerInvocation.cpp lib/StaticAnalyzer/Core/CoreEngine.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Anna Zaks
ganna at apple.com
Fri Mar 9 13:14:02 PST 2012
Author: zaks
Date: Fri Mar 9 15:14:01 2012
New Revision: 152440
URL: http://llvm.org/viewvc/llvm-project?rev=152440&view=rev
Log:
[analyzer] Add support for NoRedundancy inlining mode.
We do not reanalyze a function, which has already been analyzed as an
inlined callee. As per PRELIMINARY testing, this gives over
50% run time reduction on some benchmarks without decreasing of the
number of bugs found.
Turning the mode on by default.
Modified:
cfe/trunk/include/clang/Frontend/AnalyzerOptions.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Modified: cfe/trunk/include/clang/Frontend/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/AnalyzerOptions.h?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/AnalyzerOptions.h Fri Mar 9 15:14:01 2012
@@ -126,7 +126,7 @@
// Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
InlineMaxStackDepth = 5;
InlineMaxFunctionSize = 200;
- InliningMode = All;
+ InliningMode = NoRedundancy;
}
};
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h Fri Mar 9 15:14:01 2012
@@ -30,6 +30,8 @@
namespace ento {
class CheckerManager;
+typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls;
+
class AnalysisManager : public BugReporterData {
virtual void anchor();
AnalysisDeclContextManager AnaCtxMgr;
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Fri Mar 9 15:14:01 2012
@@ -78,6 +78,10 @@
/// usually because it could not reason about something.
BlocksAborted blocksAborted;
+ /// The functions which have been analyzed through inlining. This is owned by
+ /// AnalysisConsumer. It can be null.
+ SetOfDecls *AnalyzedCallees;
+
void generateNode(const ProgramPoint &Loc,
ProgramStateRef State,
ExplodedNode *Pred);
@@ -102,17 +106,11 @@
public:
/// Construct a CoreEngine object to analyze the provided CFG using
/// a DFS exploration of the exploded graph.
- CoreEngine(SubEngine& subengine)
+ CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees)
: SubEng(subengine), G(new ExplodedGraph()),
WList(WorkList::makeBFS()),
- BCounterFactory(G->getAllocator()) {}
-
- /// Construct a CoreEngine object to analyze the provided CFG and to
- /// use the provided worklist object to execute the worklist algorithm.
- /// The CoreEngine object assumes ownership of 'wlist'.
- CoreEngine(WorkList* wlist, SubEngine& subengine)
- : SubEng(subengine), G(new ExplodedGraph()), WList(wlist),
- BCounterFactory(G->getAllocator()) {}
+ BCounterFactory(G->getAllocator()),
+ AnalyzedCallees(VisitedCallees) {}
~CoreEngine() {
delete WList;
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Fri Mar 9 15:14:01 2012
@@ -89,7 +89,7 @@
GRBugReporter BR;
public:
- ExprEngine(AnalysisManager &mgr, bool gcEnabled);
+ ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfDecls *VisitedCallees);
~ExprEngine();
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Mar 9 15:14:01 2012
@@ -138,7 +138,7 @@
Res.push_back("-analyzer-ipa");
Res.push_back(getAnalysisIPAModeName(Opts.IPAMode));
}
- if (Opts.InliningMode != All) {
+ if (Opts.InliningMode != NoRedundancy) {
Res.push_back("-analyzer-inlining-mode");
Res.push_back(getAnalysisInliningModeName(Opts.InliningMode));
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Fri Mar 9 15:14:01 2012
@@ -214,9 +214,16 @@
assert (false && "BlockExit location never occur in forward analysis.");
break;
- case ProgramPoint::CallEnterKind:
- SubEng.processCallEnter(cast<CallEnter>(Node->getLocation()), Node);
+ case ProgramPoint::CallEnterKind: {
+ CallEnter CEnter = cast<CallEnter>(Node->getLocation());
+ if (AnalyzedCallees)
+ if (const CallExpr* CE =
+ dyn_cast_or_null<CallExpr>(CEnter.getCallExpr()))
+ if (const Decl *CD = CE->getCalleeDecl())
+ AnalyzedCallees->insert(CD);
+ SubEng.processCallEnter(CEnter, Node);
break;
+ }
case ProgramPoint::CallExitKind:
SubEng.processCallExit(Node);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Mar 9 15:14:01 2012
@@ -57,10 +57,11 @@
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
-ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled)
+ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
+ SetOfDecls *VisitedCallees)
: AMgr(mgr),
AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
- Engine(*this),
+ Engine(*this, VisitedCallees),
G(Engine.getGraph()),
StateMgr(getContext(), mgr.getStoreManagerCreator(),
mgr.getConstraintManagerCreator(), G.getAllocator(),
Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=152440&r1=152439&r2=152440&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Fri Mar 9 15:14:01 2012
@@ -48,6 +48,7 @@
static ExplodedNode::Auditor* CreateUbiViz();
+STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
STATISTIC(NumFunctionsAnalyzed, "The # of functions analysed (as top level).");
//===----------------------------------------------------------------------===//
@@ -189,7 +190,9 @@
void HandleDeclContextDecl(ASTContext &C, Decl *D);
void HandleDeclContextDeclFunction(ASTContext &C, Decl *D);
- void HandleCode(Decl *D);
+ void HandleCode(Decl *D, SetOfDecls *VisitedCallees = 0);
+ void RunPathSensitiveChecks(Decl *D, SetOfDecls *VisitedCallees);
+ void ActionExprEngine(Decl *D, bool ObjCGCEnabled, SetOfDecls *VisitedCallees);
};
} // end anonymous namespace
@@ -219,15 +222,18 @@
// Find the top level nodes - children of root + the unreachable (parentless)
// nodes.
- llvm::SmallVector<CallGraphNode*, 24> TopLevelFunctions;
+ llvm::SmallVector<CallGraphNode*, 24> TopLevelFunctions;
CallGraphNode *Entry = CG.getRoot();
for (CallGraphNode::iterator I = Entry->begin(),
- E = Entry->end(); I != E; ++I)
+ E = Entry->end(); I != E; ++I) {
TopLevelFunctions.push_back(*I);
-
+ NumFunctionTopLevel++;
+ }
for (CallGraph::nodes_iterator TI = CG.parentless_begin(),
- TE = CG.parentless_end(); TI != TE; ++TI)
+ TE = CG.parentless_end(); TI != TE; ++TI) {
TopLevelFunctions.push_back(*TI);
+ NumFunctionTopLevel++;
+ }
// TODO: Sort TopLevelFunctions.
@@ -241,12 +247,20 @@
DFI = llvm::df_ext_begin(*TI, Visited),
E = llvm::df_ext_end(*TI, Visited);
DFI != E; ++DFI) {
+ SetOfDecls VisitedCallees;
Decl *D = (*DFI)->getDecl();
assert(D);
- HandleCode(D);
+ HandleCode(D, (Mgr->InliningMode == All ? 0 : &VisitedCallees));
+
+ // Add the visited callees to the global visited set.
+ for (SetOfDecls::const_iterator I = VisitedCallees.begin(),
+ E = VisitedCallees.end(); I != E; ++I) {
+ CallGraphNode *VN = CG.getNode(*I);
+ if (VN)
+ Visited.insert(VN);
+ }
}
}
-
}
void AnalysisConsumer::HandleDeclContextDecl(ASTContext &C, Decl *D) {
@@ -284,6 +298,9 @@
case Decl::CXXMethod:
case Decl::Function: {
FunctionDecl *FD = cast<FunctionDecl>(D);
+ IdentifierInfo *II = FD->getIdentifier();
+ if (II && II->getName().startswith("__inline"))
+ break;
// We skip function template definitions, as their semantics is
// only determined when they are instantiated.
if (FD->isThisDeclarationADefinition() &&
@@ -350,9 +367,6 @@
FindBlocks(DC, WL);
}
-static void RunPathSensitiveChecks(AnalysisConsumer &C, AnalysisManager &mgr,
- Decl *D);
-
static std::string getFunctionName(const Decl *D) {
if (const ObjCMethodDecl *ID = dyn_cast<ObjCMethodDecl>(D)) {
return ID->getSelector().getAsString();
@@ -365,7 +379,7 @@
return "";
}
-void AnalysisConsumer::HandleCode(Decl *D) {
+void AnalysisConsumer::HandleCode(Decl *D, SetOfDecls *VisitedCallees) {
if (!Opts.AnalyzeSpecificFunction.empty() &&
getFunctionName(D) != Opts.AnalyzeSpecificFunction)
return;
@@ -400,7 +414,7 @@
if ((*WI)->hasBody()) {
checkerMgr->runCheckersOnASTBody(*WI, *Mgr, BR);
if (checkerMgr->hasPathSensitiveCheckers())
- RunPathSensitiveChecks(*this, *Mgr, *WI);
+ RunPathSensitiveChecks(*WI, VisitedCallees);
}
NumFunctionsAnalyzed++;
}
@@ -409,52 +423,52 @@
// Path-sensitive checking.
//===----------------------------------------------------------------------===//
-static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager &mgr,
- Decl *D, bool ObjCGCEnabled) {
+void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
+ SetOfDecls *VisitedCallees) {
// Construct the analysis engine. First check if the CFG is valid.
// FIXME: Inter-procedural analysis will need to handle invalid CFGs.
- if (!mgr.getCFG(D))
+ if (!Mgr->getCFG(D))
return;
- ExprEngine Eng(mgr, ObjCGCEnabled);
+
+ ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees);
// Set the graph auditor.
OwningPtr<ExplodedNode::Auditor> Auditor;
- if (mgr.shouldVisualizeUbigraph()) {
+ if (Mgr->shouldVisualizeUbigraph()) {
Auditor.reset(CreateUbiViz());
ExplodedNode::SetAuditor(Auditor.get());
}
// Execute the worklist algorithm.
- Eng.ExecuteWorkList(mgr.getAnalysisDeclContextManager().getStackFrame(D, 0),
- mgr.getMaxNodes());
+ Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D, 0),
+ Mgr->getMaxNodes());
// Release the auditor (if any) so that it doesn't monitor the graph
// created BugReporter.
ExplodedNode::SetAuditor(0);
// Visualize the exploded graph.
- if (mgr.shouldVisualizeGraphviz())
- Eng.ViewGraph(mgr.shouldTrimGraph());
+ if (Mgr->shouldVisualizeGraphviz())
+ Eng.ViewGraph(Mgr->shouldTrimGraph());
// Display warnings.
Eng.getBugReporter().FlushReports();
}
-static void RunPathSensitiveChecks(AnalysisConsumer &C, AnalysisManager &mgr,
- Decl *D) {
+void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, SetOfDecls *Visited) {
- switch (mgr.getLangOptions().getGC()) {
+ switch (Mgr->getLangOptions().getGC()) {
case LangOptions::NonGC:
- ActionExprEngine(C, mgr, D, false);
+ ActionExprEngine(D, false, Visited);
break;
case LangOptions::GCOnly:
- ActionExprEngine(C, mgr, D, true);
+ ActionExprEngine(D, true, Visited);
break;
case LangOptions::HybridGC:
- ActionExprEngine(C, mgr, D, false);
- ActionExprEngine(C, mgr, D, true);
+ ActionExprEngine(D, false, Visited);
+ ActionExprEngine(D, true, Visited);
break;
}
}
More information about the cfe-commits
mailing list