mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
Add support for DenseMap/DenseSet count and find using const pointers
Summary: Similar to SmallPtrSet, this makes find and count work with both const referneces and const pointers. Reviewers: dblaikie Subscribers: llvm-commits, mzolotukhin Differential Revision: https://reviews.llvm.org/D30713 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297424 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
96acf92927
commit
5e2cfa2e2d
@ -53,6 +53,9 @@ class DenseMapIterator;
|
||||
template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
|
||||
typename BucketT>
|
||||
class DenseMapBase : public DebugEpochBase {
|
||||
template <typename T>
|
||||
using const_arg_type_t = typename const_pointer_or_const_ref<T>::type;
|
||||
|
||||
public:
|
||||
typedef unsigned size_type;
|
||||
typedef KeyT key_type;
|
||||
@ -119,18 +122,18 @@ public:
|
||||
}
|
||||
|
||||
/// Return 1 if the specified key is in the map, 0 otherwise.
|
||||
size_type count(const KeyT &Val) const {
|
||||
size_type count(const_arg_type_t<KeyT> Val) const {
|
||||
const BucketT *TheBucket;
|
||||
return LookupBucketFor(Val, TheBucket) ? 1 : 0;
|
||||
}
|
||||
|
||||
iterator find(const KeyT &Val) {
|
||||
iterator find(const_arg_type_t<KeyT> Val) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(Val, TheBucket))
|
||||
return iterator(TheBucket, getBucketsEnd(), *this, true);
|
||||
return end();
|
||||
}
|
||||
const_iterator find(const KeyT &Val) const {
|
||||
const_iterator find(const_arg_type_t<KeyT> Val) const {
|
||||
const BucketT *TheBucket;
|
||||
if (LookupBucketFor(Val, TheBucket))
|
||||
return const_iterator(TheBucket, getBucketsEnd(), *this, true);
|
||||
@ -159,7 +162,7 @@ public:
|
||||
|
||||
/// lookup - Return the entry for the specified key, or a default
|
||||
/// constructed value if no such entry exists.
|
||||
ValueT lookup(const KeyT &Val) const {
|
||||
ValueT lookup(const_arg_type_t<KeyT> Val) const {
|
||||
const BucketT *TheBucket;
|
||||
if (LookupBucketFor(Val, TheBucket))
|
||||
return TheBucket->getSecond();
|
||||
|
@ -48,6 +48,8 @@ class DenseSetImpl {
|
||||
static_assert(sizeof(typename MapTy::value_type) == sizeof(ValueT),
|
||||
"DenseMap buckets unexpectedly large!");
|
||||
MapTy TheMap;
|
||||
template <typename T>
|
||||
using const_arg_type_t = typename const_pointer_or_const_ref<T>::type;
|
||||
|
||||
public:
|
||||
typedef ValueT key_type;
|
||||
@ -78,7 +80,7 @@ public:
|
||||
}
|
||||
|
||||
/// Return 1 if the specified key is in the set, 0 otherwise.
|
||||
size_type count(const ValueT &V) const {
|
||||
size_type count(const_arg_type_t<ValueT> V) const {
|
||||
return TheMap.count(V);
|
||||
}
|
||||
|
||||
@ -154,8 +156,8 @@ public:
|
||||
const_iterator begin() const { return ConstIterator(TheMap.begin()); }
|
||||
const_iterator end() const { return ConstIterator(TheMap.end()); }
|
||||
|
||||
iterator find(const ValueT &V) { return Iterator(TheMap.find(V)); }
|
||||
const_iterator find(const ValueT &V) const {
|
||||
iterator find(const_arg_type_t<ValueT> V) { return Iterator(TheMap.find(V)); }
|
||||
const_iterator find(const_arg_type_t<ValueT> V) const {
|
||||
return ConstIterator(TheMap.find(V));
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,15 @@ struct add_const_past_pointer<
|
||||
typedef const typename std::remove_pointer<T>::type *type;
|
||||
};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct const_pointer_or_const_ref {
|
||||
using type = const T &;
|
||||
};
|
||||
template <typename T>
|
||||
struct const_pointer_or_const_ref<
|
||||
T, typename std::enable_if<std::is_pointer<T>::value>::type> {
|
||||
using type = typename add_const_past_pointer<T>::type;
|
||||
};
|
||||
}
|
||||
|
||||
// If the compiler supports detecting whether a class is final, define
|
||||
|
@ -3657,7 +3657,7 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi,
|
||||
|
||||
namespace {
|
||||
struct CSEDenseMapInfo {
|
||||
static bool canHandle(Instruction *I) {
|
||||
static bool canHandle(const Instruction *I) {
|
||||
return isa<InsertElementInst>(I) || isa<ExtractElementInst>(I) ||
|
||||
isa<ShuffleVectorInst>(I) || isa<GetElementPtrInst>(I);
|
||||
}
|
||||
@ -3667,12 +3667,12 @@ struct CSEDenseMapInfo {
|
||||
static inline Instruction *getTombstoneKey() {
|
||||
return DenseMapInfo<Instruction *>::getTombstoneKey();
|
||||
}
|
||||
static unsigned getHashValue(Instruction *I) {
|
||||
static unsigned getHashValue(const Instruction *I) {
|
||||
assert(canHandle(I) && "Unknown instruction!");
|
||||
return hash_combine(I->getOpcode(), hash_combine_range(I->value_op_begin(),
|
||||
I->value_op_end()));
|
||||
}
|
||||
static bool isEqual(Instruction *LHS, Instruction *RHS) {
|
||||
static bool isEqual(const Instruction *LHS, const Instruction *RHS) {
|
||||
if (LHS == getEmptyKey() || RHS == getEmptyKey() ||
|
||||
LHS == getTombstoneKey() || RHS == getTombstoneKey())
|
||||
return LHS == RHS;
|
||||
|
@ -580,4 +580,18 @@ TEST(DenseMapCustomTest, TryEmplaceTest) {
|
||||
EXPECT_EQ(Try1.first, Try2.first);
|
||||
EXPECT_NE(nullptr, P);
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, ConstTest) {
|
||||
// Test that const pointers work okay for count and find, even when the
|
||||
// underlying map is a non-const pointer.
|
||||
DenseMap<int *, int> Map;
|
||||
int A;
|
||||
int *B = &A;
|
||||
const int *C = &A;
|
||||
Map.insert({B, 0});
|
||||
EXPECT_EQ(Map.count(B), 1u);
|
||||
EXPECT_EQ(Map.count(C), 1u);
|
||||
EXPECT_NE(Map.find(B), Map.end());
|
||||
EXPECT_NE(Map.find(C), Map.end());
|
||||
}
|
||||
}
|
||||
|
@ -185,4 +185,17 @@ TEST(DenseSetCustomTest, ReserveTest) {
|
||||
EXPECT_EQ(0, CountCopyAndMove::Copy);
|
||||
}
|
||||
}
|
||||
TEST(DenseSetCustomTest, ConstTest) {
|
||||
// Test that const pointers work okay for count and find, even when the
|
||||
// underlying map is a non-const pointer.
|
||||
DenseSet<int *> Map;
|
||||
int A;
|
||||
int *B = &A;
|
||||
const int *C = &A;
|
||||
Map.insert(B);
|
||||
EXPECT_EQ(Map.count(B), 1u);
|
||||
EXPECT_EQ(Map.count(C), 1u);
|
||||
EXPECT_NE(Map.find(B), Map.end());
|
||||
EXPECT_NE(Map.find(C), Map.end());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user