Remove isPod() from DenseMapInfo, splitting it out to its own

isPodLike type trait.  This is a generally useful type trait for
more than just DenseMap, and we really care about whether something
acts like a pod, not whether it really is a pod.

llvm-svn: 91421
This commit is contained in:
Chris Lattner 2009-12-15 07:26:43 +00:00
parent 7743ee06be
commit 587962c667
21 changed files with 118 additions and 82 deletions

View File

@ -217,7 +217,8 @@ public:
private:
void CopyFrom(const DenseMap& other) {
if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) {
if (NumBuckets != 0 &&
(!isPodLike<KeyInfoT>::value || !isPodLike<ValueInfoT>::value)) {
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
@ -239,7 +240,7 @@ private:
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) *
other.NumBuckets));
if (KeyInfoT::isPod() && ValueInfoT::isPod())
if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value)
memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
else
for (size_t i = 0; i < other.NumBuckets; ++i) {

View File

@ -15,7 +15,7 @@
#define LLVM_ADT_DENSEMAPINFO_H
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <utility>
#include "llvm/Support/type_traits.h"
namespace llvm {
@ -25,7 +25,6 @@ struct DenseMapInfo {
//static inline T getTombstoneKey();
//static unsigned getHashValue(const T &Val);
//static bool isEqual(const T &LHS, const T &RHS);
//static bool isPod()
};
// Provide DenseMapInfo for all pointers.
@ -46,7 +45,6 @@ struct DenseMapInfo<T*> {
(unsigned((uintptr_t)PtrVal) >> 9);
}
static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
// Provide DenseMapInfo for chars.
@ -54,7 +52,6 @@ template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; }
static unsigned getHashValue(const char& Val) { return Val * 37; }
static bool isPod() { return true; }
static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS;
}
@ -65,7 +62,6 @@ template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37; }
static bool isPod() { return true; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS;
}
@ -78,7 +74,6 @@ template<> struct DenseMapInfo<unsigned long> {
static unsigned getHashValue(const unsigned long& Val) {
return (unsigned)(Val * 37UL);
}
static bool isPod() { return true; }
static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
return LHS == RHS;
}
@ -91,7 +86,6 @@ template<> struct DenseMapInfo<unsigned long long> {
static unsigned getHashValue(const unsigned long long& Val) {
return (unsigned)(Val * 37ULL);
}
static bool isPod() { return true; }
static bool isEqual(const unsigned long long& LHS,
const unsigned long long& RHS) {
return LHS == RHS;
@ -127,7 +121,6 @@ struct DenseMapInfo<std::pair<T, U> > {
return (unsigned)key;
}
static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; }
static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); }
};
} // end namespace llvm

View File

@ -211,9 +211,12 @@ template<typename T> struct DenseMapInfo<ImmutableList<T> > {
static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) {
return X1 == X2;
}
static bool isPod() { return true; }
};
template <typename T> struct isPodLike;
template <typename T>
struct isPodLike<ImmutableList<T> > { static const bool value = true; };
} // end llvm namespace
#endif

View File

@ -106,6 +106,12 @@ public:
bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
};
template <typename T> struct isPodLike;
template<typename PointerTy, unsigned IntBits, typename IntType>
struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
static const bool value = true;
};
// Provide specialization of DenseMapInfo for PointerIntPair.
template<typename PointerTy, unsigned IntBits, typename IntType>
struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
@ -125,7 +131,6 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
return unsigned(IV) ^ unsigned(IV >> 9);
}
static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
// Teach SmallPtrSet that PointerIntPair is "basically a pointer".

View File

@ -250,6 +250,12 @@ public:
}
};
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
struct isPodLike<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
static const bool value = true;
};
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH;
@ -267,7 +273,6 @@ struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
static bool isEqual(const VH &LHS, const VH &RHS) {
return LHS == RHS;
}
static bool isPod() { return false; }
};

View File

@ -259,11 +259,9 @@ class AliasSetTracker {
ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
ASTCallbackVH &operator=(Value *V);
};
/// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that ASTCallbackVH
/// is not a POD (it needs its destructor called).
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {
static bool isPod() { return false; }
};
/// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to
/// compare and hash the value handle.
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
AliasAnalysis &AA;
ilist<AliasSet> AliasSets;

View File

@ -25,53 +25,52 @@
namespace llvm {
struct BPNode {
BPNode* Next;
uintptr_t& PtrRef;
BPNode(BPNode* n, uintptr_t& pref)
: Next(n), PtrRef(pref) {
PtrRef = 0;
}
};
struct BPEntry {
union { BPNode* Head; void* Ptr; };
BPEntry() : Head(NULL) {}
void SetPtr(BPNode*& FreeList, void* P);
};
class BPKey {
unsigned Raw;
public:
BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); }
BPKey(unsigned code, unsigned) : Raw(code) {}
void MarkFinal() { Raw |= 0x1; }
bool hasFinalPtr() const { return Raw & 0x1 ? true : false; }
SerializedPtrID getID() const { return Raw >> 1; }
static inline BPKey getEmptyKey() { return BPKey(0,0); }
static inline BPKey getTombstoneKey() { return BPKey(1,0); }
static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; }
static bool isEqual(const BPKey& K1, const BPKey& K2) {
return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true;
}
};
template <>
struct isPodLike<BPKey> { static const bool value = true; };
template <>
struct isPodLike<BPEntry> { static const bool value = true; };
class Deserializer {
//===----------------------------------------------------------===//
// Internal type definitions.
//===----------------------------------------------------------===//
struct BPNode {
BPNode* Next;
uintptr_t& PtrRef;
BPNode(BPNode* n, uintptr_t& pref)
: Next(n), PtrRef(pref) {
PtrRef = 0;
}
};
struct BPEntry {
union { BPNode* Head; void* Ptr; };
BPEntry() : Head(NULL) {}
static inline bool isPod() { return true; }
void SetPtr(BPNode*& FreeList, void* P);
};
class BPKey {
unsigned Raw;
public:
BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); }
BPKey(unsigned code, unsigned) : Raw(code) {}
void MarkFinal() { Raw |= 0x1; }
bool hasFinalPtr() const { return Raw & 0x1 ? true : false; }
SerializedPtrID getID() const { return Raw >> 1; }
static inline BPKey getEmptyKey() { return BPKey(0,0); }
static inline BPKey getTombstoneKey() { return BPKey(1,0); }
static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; }
static bool isEqual(const BPKey& K1, const BPKey& K2) {
return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true;
}
static bool isPod() { return true; }
};
typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy;

View File

@ -891,8 +891,9 @@ template<> struct DenseMapInfo<SDValue> {
static bool isEqual(const SDValue &LHS, const SDValue &RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
template <> struct isPodLike<SDValue> { static const bool value = true; };
/// simplify_type specializations - Allow casting operators to work directly on
/// SDValues as if they were SDNode*'s.

View File

@ -329,6 +329,7 @@ namespace llvm {
};
/// DenseMapInfo specialization for SlotIndex.
/// TODO: Not a POD?
template <>
struct DenseMapInfo<SlotIndex> {
static inline SlotIndex getEmptyKey() {
@ -343,7 +344,6 @@ namespace llvm {
static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) {
return (LHS == RHS);
}
static inline bool isPod() { return false; }
};
inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {

View File

@ -66,7 +66,7 @@ namespace llvm {
};
// Specialize DenseMapInfo for DebugLocTuple.
template<> struct DenseMapInfo<DebugLocTuple> {
template<> struct DenseMapInfo<DebugLocTuple> {
static inline DebugLocTuple getEmptyKey() {
return DebugLocTuple(0, 0, ~0U, ~0U);
}
@ -85,9 +85,9 @@ namespace llvm {
LHS.Line == RHS.Line &&
LHS.Col == RHS.Col;
}
static bool isPod() { return true; }
};
template <> struct isPodLike<DebugLocTuple> {static const bool value = true;};
/// DebugLocTracker - This class tracks debug location information.
///

View File

@ -254,14 +254,17 @@ struct DenseMapInfo<AssertingVH<T> > {
static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
return LHS == RHS;
}
static bool isPod() {
#ifdef NDEBUG
return true;
#else
return false;
#endif
}
};
template <typename T>
struct isPodLike<AssertingVH<T> > {
#ifdef NDEBUG
static const bool value = true;
#else
static const bool value = false;
#endif
};
/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
/// even across RAUW operations.

View File

@ -17,6 +17,8 @@
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
#define LLVM_SUPPORT_TYPE_TRAITS_H
#include <utility>
// This is actually the conforming implementation which works with abstract
// classes. However, enough compilers have trouble with it that most will use
// the one in boost/type_traits/object_traits.hpp. This implementation actually
@ -24,6 +26,33 @@
namespace llvm {
/// isPodLike - This is a type trait that is used to determine whether a given
/// type can be copied around with memcpy instead of running ctors etc.
template <typename T>
struct isPodLike {
static const bool value = false;
};
// pointers are all pod-like.
template <typename T>
struct isPodLike<T*> { static const bool value = true; };
// builtin types are pod-like as well.
// There is probably a much better way to do this.
template <> struct isPodLike<char> { static const bool value = true; };
template <> struct isPodLike<unsigned> { static const bool value = true; };
template <> struct isPodLike<unsigned long> { static const bool value = true; };
template <> struct isPodLike<unsigned long long> {
static const bool value = true;
};
// pairs are pod-like if their elements are.
template<typename T, typename U>
struct isPodLike<std::pair<T, U> > {
static const bool value = isPodLike<T>::value & isPodLike<U>::value;
};
namespace dont_use
{
// These two functions should never be used. They are helpers to

View File

@ -121,8 +121,6 @@ namespace {
return *LHS == *RHS;
}
static bool isPod() { return true; }
};
class Andersens : public ModulePass, public AliasAnalysis,

View File

@ -413,7 +413,7 @@ uintptr_t Deserializer::ReadInternalRefPtr() {
return GetFinalPtr(E);
}
void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) {
void BPEntry::SetPtr(BPNode*& FreeList, void* P) {
BPNode* Last = NULL;
for (BPNode* N = Head; N != NULL; N=N->Next) {

View File

@ -119,7 +119,6 @@ class DwarfException : public Dwarf {
static inline unsigned getTombstoneKey() { return -2U; }
static unsigned getHashValue(const unsigned &Key) { return Key; }
static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
/// PadRange - Structure holding a try-range and the associated landing pad.

View File

@ -175,7 +175,6 @@ struct KeyInfo {
static inline unsigned getTombstoneKey() { return -2U; }
static unsigned getHashValue(const unsigned &Key) { return Key; }
static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
/// ActionEntry - Structure describing an entry in the actions table.

View File

@ -190,8 +190,11 @@ template <> struct DenseMapInfo<Expression> {
static bool isEqual(const Expression &LHS, const Expression &RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
template <>
struct isPodLike<Expression> { static const bool value = true; };
}
//===----------------------------------------------------------------------===//

View File

@ -11200,8 +11200,9 @@ namespace llvm {
return LHS.PN == RHS.PN && LHS.Shift == RHS.Shift &&
LHS.Width == RHS.Width;
}
static bool isPod() { return true; }
};
template <>
struct isPodLike<LoweredPHIRecord> { static const bool value = true; };
}

View File

@ -154,8 +154,10 @@ template <> struct DenseMapInfo<Expression> {
static bool isEqual(const Expression &LHS, const Expression &RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
template <>
struct isPodLike<Expression> { static const bool value = true; };
}
//===----------------------------------------------------------------------===//

View File

@ -55,7 +55,6 @@ struct DenseMapInfo<std::pair<BasicBlock*, unsigned> > {
static bool isEqual(const EltTy &LHS, const EltTy &RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
}

View File

@ -62,7 +62,6 @@ struct DenseMapAPIntKeyInfo {
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
return LHS == RHS;
}
static bool isPod() { return false; }
};
struct DenseMapAPFloatKeyInfo {
@ -89,7 +88,6 @@ struct DenseMapAPFloatKeyInfo {
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
return LHS == RHS;
}
static bool isPod() { return false; }
};
class LLVMContextImpl {