diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-08-09 22:55:37 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-09 22:55:37 +0000 |
commit | 824e07ac8f5c9efdddb4254de0203b9675b1ef0b (patch) | |
tree | 9bcd73d0adc05ae5c10794f8f08a0d5072cca983 /lib/StaticAnalyzer/Core/RegionStore.cpp | |
parent | bf74b568182bcfbe711b6a4f74293d007b8d5f00 (diff) |
[analyzer] Cache the "concrete offset base" for regions with symbolic offsets.
This makes it faster to access and invalidate bindings with symbolic offsets
by only computing this information once.
No intended functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161635 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 61 |
1 files changed, 26 insertions, 35 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index 90bd0f31a5..1ba46ea067 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -40,33 +40,42 @@ using llvm::Optional; namespace { class BindingKey { public: - enum Kind { Direct = 0x0, Default = 0x1 }; + enum Kind { Default = 0x0, Direct = 0x1 }; private: - enum { SYMBOLIC = UINT64_MAX }; + enum { Symbolic = 0x2 }; - llvm::PointerIntPair<const MemRegion *, 1, Kind> P; - uint64_t Offset; + llvm::PointerIntPair<const MemRegion *, 2> P; + uint64_t Data; - explicit BindingKey(const MemRegion *r, Kind k) - : P(r, k), Offset(SYMBOLIC) {} + explicit BindingKey(const MemRegion *r, const MemRegion *Base, Kind k) + : P(r, k | Symbolic), Data(reinterpret_cast<uintptr_t>(Base)) { + assert(r && Base && "Must have known regions."); + assert(getConcreteOffsetRegion() == Base && "Failed to store base region"); + } explicit BindingKey(const MemRegion *r, uint64_t offset, Kind k) - : P(r, k), Offset(offset) {} + : P(r, k), Data(offset) { + assert(r && "Must have known regions."); + assert(getOffset() == offset && "Failed to store offset"); + } public: - bool isDirect() const { return P.getInt() == Direct; } - bool hasSymbolicOffset() const { return Offset == SYMBOLIC; } + bool isDirect() const { return P.getInt() & Direct; } + bool hasSymbolicOffset() const { return P.getInt() & Symbolic; } const MemRegion *getRegion() const { return P.getPointer(); } uint64_t getOffset() const { assert(!hasSymbolicOffset()); - return Offset; + return Data; } - const MemRegion *getConcreteOffsetRegion() const; + const MemRegion *getConcreteOffsetRegion() const { + assert(hasSymbolicOffset()); + return reinterpret_cast<const MemRegion *>(static_cast<uintptr_t>(Data)); + } void Profile(llvm::FoldingSetNodeID& ID) const { ID.AddPointer(P.getOpaqueValue()); - ID.AddInteger(Offset); + ID.AddInteger(Data); } static BindingKey Make(const MemRegion *R, Kind k); @@ -76,12 +85,12 @@ public: return true; if (P.getOpaqueValue() > X.P.getOpaqueValue()) return false; - return Offset < X.Offset; + return Data < X.Data; } bool operator==(const BindingKey &X) const { return P.getOpaqueValue() == X.P.getOpaqueValue() && - Offset == X.Offset; + Data == X.Data; } bool isValid() const { @@ -92,27 +101,10 @@ public: BindingKey BindingKey::Make(const MemRegion *R, Kind k) { const RegionOffset &RO = R->getAsOffset(); - if (RO.isValid()) - return BindingKey(RO.getRegion(), RO.getOffset(), k); - - return BindingKey(R, k); -} - -const MemRegion *BindingKey::getConcreteOffsetRegion() const { - const MemRegion *R = getRegion(); - if (!hasSymbolicOffset()) - return R; - - RegionOffset RO; - do { - const SubRegion *SR = dyn_cast<SubRegion>(R); - if (!SR) - break; - R = SR->getSuperRegion(); - RO = R->getAsOffset(); - } while (!RO.isValid()); + if (RO.hasSymbolicOffset()) + return BindingKey(R, RO.getRegion(), k); - return R; + return BindingKey(RO.getRegion(), RO.getOffset(), k); } namespace llvm { @@ -561,7 +553,6 @@ RegionBindings RegionStoreManager::removeSubRegionBindings(RegionBindings B, // by changing the data structure used for RegionBindings. BindingKey SRKey = BindingKey::Make(R, BindingKey::Default); - assert(SRKey.isValid()); if (SRKey.hasSymbolicOffset()) { const SubRegion *Base = cast<SubRegion>(SRKey.getConcreteOffsetRegion()); B = removeSubRegionBindings(B, Base); |