[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