aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-09 22:55:37 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-09 22:55:37 +0000
commit824e07ac8f5c9efdddb4254de0203b9675b1ef0b (patch)
tree9bcd73d0adc05ae5c10794f8f08a0d5072cca983 /lib/StaticAnalyzer/Core/RegionStore.cpp
parentbf74b568182bcfbe711b6a4f74293d007b8d5f00 (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.cpp61
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);