]> granicus.if.org Git - clang/commitdiff
[Analyzer] Don't cache report generation ExplodedNodes
authorBen Craig <ben.craig@codeaurora.org>
Thu, 23 Jun 2016 15:47:12 +0000 (15:47 +0000)
committerBen Craig <ben.craig@codeaurora.org>
Thu, 23 Jun 2016 15:47:12 +0000 (15:47 +0000)
During the core analysis, ExplodedNodes are added to the
ExplodedGraph, and those nodes are cached for deduplication purposes.

After core analysis, reports are generated. Here, trimmed copies of
the ExplodedGraph are made. Since the ExplodedGraph has already been
deduplicated, there is no need to deduplicate again.

This change makes it possible to add ExplodedNodes to an
ExplodedGraph without the overhead of deduplication. "Uncached" nodes
also cannot be iterated over, but none of the report generation code
attempts to iterate over all nodes. This change reduces the analysis
time of a large .C file from 3m43.941s to 3m40.256s (~1.6% speedup).
It should slightly reduce memory consumption. Gains should be roughly
proportional to the number (and path length) of static analysis
warnings.

This patch enables future work that should remove the need for an
InterExplodedGraphMap inverse map. I plan on using the (now unused)
ExplodedNode link to connect new nodes to the original nodes.

http://reviews.llvm.org/D21229

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273572 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
lib/StaticAnalyzer/Core/BugReporter.cpp
lib/StaticAnalyzer/Core/ExplodedGraph.cpp

index b14a1cc5f62fa418f8ca3c478c5378f8abc62937..bacb42dd176fd74046c1a6e00d3a3f3ed0542396 100644 (file)
@@ -295,6 +295,14 @@ public:
                         bool IsSink = false,
                         bool* IsNew = nullptr);
 
+  /// \brief Create a node for a (Location, State) pair,
+  ///  but don't store it for deduplication later.  This
+  ///  is useful when copying an already completed
+  ///  ExplodedGraph for further processing.
+  ExplodedNode *createUncachedNode(const ProgramPoint &L,
+    ProgramStateRef State,
+    bool IsSink = false);
+
   std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const {
     return llvm::make_unique<ExplodedGraph>();
   }
index f546a6636d3a7b94d64e60ab55d63915791ff46a..488126b0088a1ececbcef9b651fddd0710339596 100644 (file)
@@ -2922,7 +2922,7 @@ bool TrimmedGraph::popNextReportGraph(ReportGraph &GraphWrapper) {
   while (true) {
     // Create the equivalent node in the new graph with the same state
     // and location.
-    ExplodedNode *NewN = GNew->getNode(OrigN->getLocation(), OrigN->getState(),
+    ExplodedNode *NewN = GNew->createUncachedNode(OrigN->getLocation(), OrigN->getState(),
                                        OrigN->isSink());
 
     // Store the mapping to the original node.
index 8a09720b2a19655c02ddd545cf3b23c78aa84129..02d382cc4885ebd6588a7d5b001a8104b58c1d0d 100644 (file)
@@ -336,6 +336,14 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
   return V;
 }
 
+ExplodedNode *ExplodedGraph::createUncachedNode(const ProgramPoint &L,
+                                                ProgramStateRef State,
+                                                bool IsSink) {
+  NodeTy *V = (NodeTy *) getAllocator().Allocate<NodeTy>();
+  new (V) NodeTy(L, State, IsSink);
+  return V;
+}
+
 std::unique_ptr<ExplodedGraph>
 ExplodedGraph::trim(ArrayRef<const NodeTy *> Sinks,
                     InterExplodedGraphMap *ForwardMap,
@@ -395,8 +403,7 @@ ExplodedGraph::trim(ArrayRef<const NodeTy *> Sinks,
 
     // Create the corresponding node in the new graph and record the mapping
     // from the old node to the new node.
-    ExplodedNode *NewN = G->getNode(N->getLocation(), N->State, N->isSink(),
-                                    nullptr);
+    ExplodedNode *NewN = G->createUncachedNode(N->getLocation(), N->State, N->isSink());
     Pass2[N] = NewN;
 
     // Also record the reverse mapping from the new node to the old node.