diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-09-25 19:03:01 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-09-25 19:03:01 +0000 |
commit | 6e3bf21f20d4d744fdf5acd719e9f442f4a144fc (patch) | |
tree | 65eba656004eb866ae99bacf7fb069318f2af9c2 | |
parent | 156f0f0c0d733f668a43526d62b8149c068cb3a0 (diff) |
[analyzer] Calculate liveness for symbolic exprs as well as atomic symbols.
No tests, but this allows the optimization of removing dead constraints.
We can then add tests that we don't do this prematurely.
<rdar://problem/12333297>
Note: the added FIXME to investigate SymbolRegionValue liveness is
tracked by <rdar://problem/12368183>. This patch does not change the
existing behavior.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164621 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Core/SymbolManager.cpp | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp index c21df4c318..87b4ba315e 100644 --- a/lib/StaticAnalyzer/Core/SymbolManager.cpp +++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -466,37 +466,49 @@ bool SymbolReaper::isLive(SymbolRef sym) { markDependentsLive(sym); return true; } - - if (const SymbolDerived *derived = dyn_cast<SymbolDerived>(sym)) { - if (isLive(derived->getParentSymbol())) { - markLive(sym); - return true; - } - return false; - } - - if (const SymbolExtent *extent = dyn_cast<SymbolExtent>(sym)) { - if (isLiveRegion(extent->getRegion())) { - markLive(sym); - return true; - } - return false; + + bool KnownLive; + + switch (sym->getKind()) { + case SymExpr::RegionValueKind: + // FIXME: We should be able to use isLiveRegion here (this behavior + // predates isLiveRegion), but doing so causes test failures. Investigate. + KnownLive = true; + break; + case SymExpr::ConjuredKind: + KnownLive = false; + break; + case SymExpr::DerivedKind: + KnownLive = isLive(cast<SymbolDerived>(sym)->getParentSymbol()); + break; + case SymExpr::ExtentKind: + KnownLive = isLiveRegion(cast<SymbolExtent>(sym)->getRegion()); + break; + case SymExpr::MetadataKind: + KnownLive = MetadataInUse.count(sym) && + isLiveRegion(cast<SymbolMetadata>(sym)->getRegion()); + if (KnownLive) + MetadataInUse.erase(sym); + break; + case SymExpr::SymIntKind: + KnownLive = isLive(cast<SymIntExpr>(sym)->getLHS()); + break; + case SymExpr::IntSymKind: + KnownLive = isLive(cast<IntSymExpr>(sym)->getRHS()); + break; + case SymExpr::SymSymKind: + KnownLive = isLive(cast<SymSymExpr>(sym)->getLHS()) && + isLive(cast<SymSymExpr>(sym)->getRHS()); + break; + case SymExpr::CastSymbolKind: + KnownLive = isLive(cast<SymbolCast>(sym)->getOperand()); + break; } - if (const SymbolMetadata *metadata = dyn_cast<SymbolMetadata>(sym)) { - if (MetadataInUse.count(sym)) { - if (isLiveRegion(metadata->getRegion())) { - markLive(sym); - MetadataInUse.erase(sym); - return true; - } - } - return false; - } + if (KnownLive) + markLive(sym); - // Interogate the symbol. It may derive from an input value to - // the analyzed function/method. - return isa<SymbolRegionValue>(sym); + return KnownLive; } bool |