diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-03-20 00:35:31 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-03-20 00:35:31 +0000 |
commit | f4cf6b10f863b9bc716a09b2b2a8c497dcc6aa9b (patch) | |
tree | 499340b68cb4458cca386ce23b06501d3a36d566 /lib/StaticAnalyzer/Core/ExplodedGraph.cpp | |
parent | 63a726870b486e0470c3a4b11cf62bab8be00b73 (diff) |
[analyzer] Break cycles (optionally) when trimming an ExplodedGraph.
Having a trimmed graph with no cycles (a DAG) is much more convenient for
trying to find shortest paths, which is exactly what BugReporter needs to do.
Part of the performance work for <rdar://problem/13433687>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177468 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExplodedGraph.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExplodedGraph.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index ca466d8907..f9d4345bae 100644 --- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -331,8 +331,22 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L, return V; } +static bool isDescendent(const ExplodedNode *Parent, const ExplodedNode *Child){ + SmallVector<const ExplodedNode *, 16> WL; + WL.push_back(Parent); + + while (!WL.empty()) { + const ExplodedNode *N = WL.pop_back_val(); + if (N == Child) + return true; + WL.append(N->succ_begin(), N->succ_end()); + } + + return false; +} + ExplodedGraph * -ExplodedGraph::trim(ArrayRef<const NodeTy *> Sinks, +ExplodedGraph::trim(ArrayRef<const NodeTy *> Sinks, bool BreakCycles, InterExplodedGraphMap *ForwardMap, InterExplodedGraphMap *InverseMap) const{ @@ -429,7 +443,8 @@ ExplodedGraph::trim(ArrayRef<const NodeTy *> Sinks, I != E; ++I) { Pass2Ty::iterator PI = Pass2.find(*I); if (PI != Pass2.end()) { - const_cast<ExplodedNode *>(PI->second)->addPredecessor(NewN, *G); + if (!BreakCycles || !isDescendent(PI->second, NewN)) + const_cast<ExplodedNode *>(PI->second)->addPredecessor(NewN, *G); continue; } |