forked from OSchip/llvm-project
Rework ProgramPoint to bit-mangle the 'Kind' into both Data pointers and the LocationContext. After switching to PointerIntPair, it didn't look like a safe assumption to use the lower 3 bits of the LocationContext* field. Thanks to Jordy Rose and Benjamin Kramer for their feedback.
llvm-svn: 153933
This commit is contained in:
parent
cac9d9b3f6
commit
efcfbd71d1
clang/include/clang/Analysis
|
@ -19,6 +19,7 @@
|
||||||
#include "clang/Analysis/CFG.h"
|
#include "clang/Analysis/CFG.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/PointerIntPair.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
@ -55,39 +56,25 @@ public:
|
||||||
EpsilonKind};
|
EpsilonKind};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<uintptr_t, const void *> Data;
|
llvm::PointerIntPair<const void *, 2, unsigned> Data1;
|
||||||
|
llvm::PointerIntPair<const void *, 2, unsigned> Data2;
|
||||||
|
|
||||||
// The LocationContext could be NULL to allow ProgramPoint to be used in
|
// The LocationContext could be NULL to allow ProgramPoint to be used in
|
||||||
// context insensitive analysis.
|
// context insensitive analysis.
|
||||||
uintptr_t L;
|
llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
|
||||||
|
|
||||||
const ProgramPointTag *Tag;
|
const ProgramPointTag *Tag;
|
||||||
|
|
||||||
ProgramPoint();
|
ProgramPoint();
|
||||||
|
|
||||||
static uintptr_t mangleUpperKindBits(Kind K, const void *p) {
|
|
||||||
uintptr_t tmp = (uintptr_t) p;
|
|
||||||
uintptr_t k_int = (uintptr_t) K;
|
|
||||||
k_int >>= 3;
|
|
||||||
assert((k_int & 0x3) == k_int);
|
|
||||||
tmp |= k_int;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uintptr_t mangleLowerKindBits(Kind K, const void *p) {
|
|
||||||
uintptr_t tmp = (uintptr_t) p;
|
|
||||||
uintptr_t k_int = (uintptr_t) K;
|
|
||||||
k_int &= 0x7;
|
|
||||||
tmp |= k_int;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ProgramPoint(const void *P,
|
ProgramPoint(const void *P,
|
||||||
Kind k,
|
Kind k,
|
||||||
const LocationContext *l,
|
const LocationContext *l,
|
||||||
const ProgramPointTag *tag = 0)
|
const ProgramPointTag *tag = 0)
|
||||||
: Data(mangleUpperKindBits(k, P), static_cast<const void*>(NULL)),
|
: Data1(P, ((unsigned) k) & 0x3),
|
||||||
L(mangleLowerKindBits(k, l)),
|
Data2(0, (((unsigned) k) >> 2) & 0x3),
|
||||||
|
L(l, (((unsigned) k) >> 4) & 0x3),
|
||||||
Tag(tag) {
|
Tag(tag) {
|
||||||
assert(getKind() == k);
|
assert(getKind() == k);
|
||||||
assert(getLocationContext() == l);
|
assert(getLocationContext() == l);
|
||||||
|
@ -99,34 +86,37 @@ protected:
|
||||||
Kind k,
|
Kind k,
|
||||||
const LocationContext *l,
|
const LocationContext *l,
|
||||||
const ProgramPointTag *tag = 0)
|
const ProgramPointTag *tag = 0)
|
||||||
: Data(mangleUpperKindBits(k, P1), P2),
|
: Data1(P1, ((unsigned) k) & 0x3),
|
||||||
L(mangleLowerKindBits(k, l)),
|
Data2(P2, (((unsigned) k) >> 2) & 0x3),
|
||||||
|
L(l, (((unsigned) k) >> 4) & 0x3),
|
||||||
Tag(tag) {}
|
Tag(tag) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const void *getData1() const {
|
const void *getData1() const { return Data1.getPointer(); }
|
||||||
return (void*) (Data.first & ~((uintptr_t) 0x3));
|
const void *getData2() const { return Data2.getPointer(); }
|
||||||
}
|
void setData2(const void *d) { Data2.setPointer(d); }
|
||||||
|
|
||||||
const void *getData2() const { return Data.second; }
|
|
||||||
void setData2(const void *d) { Data.second = d; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Create a new ProgramPoint object that is the same as the original
|
/// Create a new ProgramPoint object that is the same as the original
|
||||||
/// except for using the specified tag value.
|
/// except for using the specified tag value.
|
||||||
ProgramPoint withTag(const ProgramPointTag *tag) const {
|
ProgramPoint withTag(const ProgramPointTag *tag) const {
|
||||||
return ProgramPoint(getData1(), Data.second, getKind(),
|
return ProgramPoint(getData1(), getData2(), getKind(),
|
||||||
getLocationContext(), tag);
|
getLocationContext(), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
Kind getKind() const {
|
Kind getKind() const {
|
||||||
return (Kind) (((Data.first & 0x3) << 3) | (L & 0x7));
|
unsigned x = L.getInt();
|
||||||
|
x <<= 2;
|
||||||
|
x |= Data2.getInt();
|
||||||
|
x <<= 2;
|
||||||
|
x |= Data1.getInt();
|
||||||
|
return (Kind) x;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgramPointTag *getTag() const { return Tag; }
|
const ProgramPointTag *getTag() const { return Tag; }
|
||||||
|
|
||||||
const LocationContext *getLocationContext() const {
|
const LocationContext *getLocationContext() const {
|
||||||
return (LocationContext*) (L & ~((uintptr_t) 0x7));
|
return L.getPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use with DenseMap. This hash is probably slow.
|
// For use with DenseMap. This hash is probably slow.
|
||||||
|
@ -139,17 +129,23 @@ public:
|
||||||
static bool classof(const ProgramPoint*) { return true; }
|
static bool classof(const ProgramPoint*) { return true; }
|
||||||
|
|
||||||
bool operator==(const ProgramPoint & RHS) const {
|
bool operator==(const ProgramPoint & RHS) const {
|
||||||
return Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
|
return Data1 == Data1 &&
|
||||||
|
Data2 == RHS.Data2 &&
|
||||||
|
L == RHS.L &&
|
||||||
|
Tag == RHS.Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ProgramPoint &RHS) const {
|
bool operator!=(const ProgramPoint &RHS) const {
|
||||||
return Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
|
return Data1 != RHS.Data1 ||
|
||||||
|
Data2 != RHS.Data2 ||
|
||||||
|
L != RHS.L ||
|
||||||
|
Tag != RHS.Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Profile(llvm::FoldingSetNodeID& ID) const {
|
void Profile(llvm::FoldingSetNodeID& ID) const {
|
||||||
ID.AddInteger((unsigned) getKind());
|
ID.AddInteger((unsigned) getKind());
|
||||||
ID.AddPointer(getData1());
|
ID.AddPointer(getData1());
|
||||||
ID.AddPointer(Data.second);
|
ID.AddPointer(getData2());
|
||||||
ID.AddPointer(getLocationContext());
|
ID.AddPointer(getLocationContext());
|
||||||
ID.AddPointer(Tag);
|
ID.AddPointer(Tag);
|
||||||
}
|
}
|
||||||
|
@ -157,7 +153,6 @@ public:
|
||||||
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
|
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
|
||||||
const LocationContext *LC,
|
const LocationContext *LC,
|
||||||
const ProgramPointTag *tag);
|
const ProgramPointTag *tag);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockEntrance : public ProgramPoint {
|
class BlockEntrance : public ProgramPoint {
|
||||||
|
|
Loading…
Reference in New Issue