summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ADT/DenseMap.h11
-rw-r--r--llvm/include/llvm/ADT/DenseSet.h8
-rw-r--r--llvm/include/llvm/Support/type_traits.h9
-rw-r--r--llvm/lib/Transforms/Vectorize/LoopVectorize.cpp6
-rw-r--r--llvm/unittests/ADT/DenseMapTest.cpp14
-rw-r--r--llvm/unittests/ADT/DenseSetTest.cpp13
6 files changed, 51 insertions, 10 deletions
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index a689bcbf151..fd8d3bf368a 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -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();
diff --git a/llvm/include/llvm/ADT/DenseSet.h b/llvm/include/llvm/ADT/DenseSet.h
index b1345f7da73..fcf304c3ecc 100644
--- a/llvm/include/llvm/ADT/DenseSet.h
+++ b/llvm/include/llvm/ADT/DenseSet.h
@@ -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));
}
diff --git a/llvm/include/llvm/Support/type_traits.h b/llvm/include/llvm/Support/type_traits.h
index 7706ff52719..ce4bbf8cb2c 100644
--- a/llvm/include/llvm/Support/type_traits.h
+++ b/llvm/include/llvm/Support/type_traits.h
@@ -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
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 080f265b258..223986cde64 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -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;
diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
index 80f0462bc8f..273f4da021c 100644
--- a/llvm/unittests/ADT/DenseMapTest.cpp
+++ b/llvm/unittests/ADT/DenseMapTest.cpp
@@ -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());
+}
}
diff --git a/llvm/unittests/ADT/DenseSetTest.cpp b/llvm/unittests/ADT/DenseSetTest.cpp
index 19feb415a9d..a09537a3e99 100644
--- a/llvm/unittests/ADT/DenseSetTest.cpp
+++ b/llvm/unittests/ADT/DenseSetTest.cpp
@@ -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());
+}
}
OpenPOWER on IntegriCloud