1
//===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
#include "llvm/IR/ValueMap.h"
11
#include "llvm/Config/llvm-config.h"
12
#include "llvm/IR/Constants.h"
13
#include "llvm/IR/Instructions.h"
14
#include "llvm/IR/LLVMContext.h"
15
#include "gtest/gtest.h"
23
class ValueMapTest : public testing::Test {
26
std::unique_ptr<BitCastInst> BitcastV;
27
std::unique_ptr<BinaryOperator> AddV;
30
ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
31
BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))),
32
AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) {
36
// Run everything on Value*, a subtype to make sure that casting works as
37
// expected, and a const subtype to make sure we cast const correctly.
38
typedef ::testing::Types<Value, Instruction, const Instruction> KeyTypes;
39
TYPED_TEST_CASE(ValueMapTest, KeyTypes);
41
TYPED_TEST(ValueMapTest, Null) {
42
ValueMap<TypeParam*, int> VM1;
44
EXPECT_EQ(7, VM1.lookup(nullptr));
47
TYPED_TEST(ValueMapTest, FollowsValue) {
48
ValueMap<TypeParam*, int> VM;
49
VM[this->BitcastV.get()] = 7;
50
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
51
EXPECT_EQ(0u, VM.count(this->AddV.get()));
52
this->BitcastV->replaceAllUsesWith(this->AddV.get());
53
EXPECT_EQ(7, VM.lookup(this->AddV.get()));
54
EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
56
EXPECT_EQ(0u, VM.count(this->AddV.get()));
57
EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
58
EXPECT_EQ(0U, VM.size());
61
TYPED_TEST(ValueMapTest, OperationsWork) {
62
ValueMap<TypeParam*, int> VM;
63
ValueMap<TypeParam*, int> VM2(16); (void)VM2;
64
typename ValueMapConfig<TypeParam*>::ExtraData Data;
65
ValueMap<TypeParam*, int> VM3(Data, 16); (void)VM3;
66
EXPECT_TRUE(VM.empty());
68
VM[this->BitcastV.get()] = 7;
71
typename ValueMap<TypeParam*, int>::iterator I =
72
VM.find(this->BitcastV.get());
73
ASSERT_TRUE(I != VM.end());
74
EXPECT_EQ(this->BitcastV.get(), I->first);
75
EXPECT_EQ(7, I->second);
76
EXPECT_TRUE(VM.find(this->AddV.get()) == VM.end());
79
const ValueMap<TypeParam*, int> &CVM = VM;
80
typename ValueMap<TypeParam*, int>::const_iterator CI =
81
CVM.find(this->BitcastV.get());
82
ASSERT_TRUE(CI != CVM.end());
83
EXPECT_EQ(this->BitcastV.get(), CI->first);
84
EXPECT_EQ(7, CI->second);
85
EXPECT_TRUE(CVM.find(this->AddV.get()) == CVM.end());
88
std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult1 =
89
VM.insert(std::make_pair(this->AddV.get(), 3));
90
EXPECT_EQ(this->AddV.get(), InsertResult1.first->first);
91
EXPECT_EQ(3, InsertResult1.first->second);
92
EXPECT_TRUE(InsertResult1.second);
93
EXPECT_EQ(1u, VM.count(this->AddV.get()));
94
std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult2 =
95
VM.insert(std::make_pair(this->AddV.get(), 5));
96
EXPECT_EQ(this->AddV.get(), InsertResult2.first->first);
97
EXPECT_EQ(3, InsertResult2.first->second);
98
EXPECT_FALSE(InsertResult2.second);
101
VM.erase(InsertResult2.first);
102
EXPECT_EQ(0U, VM.count(this->AddV.get()));
103
EXPECT_EQ(1U, VM.count(this->BitcastV.get()));
104
VM.erase(this->BitcastV.get());
105
EXPECT_EQ(0U, VM.count(this->BitcastV.get()));
106
EXPECT_EQ(0U, VM.size());
109
SmallVector<std::pair<Instruction*, int>, 2> Elems;
110
Elems.push_back(std::make_pair(this->AddV.get(), 1));
111
Elems.push_back(std::make_pair(this->BitcastV.get(), 2));
112
VM.insert(Elems.begin(), Elems.end());
113
EXPECT_EQ(1, VM.lookup(this->AddV.get()));
114
EXPECT_EQ(2, VM.lookup(this->BitcastV.get()));
117
template<typename ExpectedType, typename VarType>
118
void CompileAssertHasType(VarType) {
119
static_assert(std::is_same<ExpectedType, VarType>::value,
120
"Not the same type");
123
TYPED_TEST(ValueMapTest, Iteration) {
124
ValueMap<TypeParam*, int> VM;
125
VM[this->BitcastV.get()] = 2;
126
VM[this->AddV.get()] = 3;
128
for (typename ValueMap<TypeParam*, int>::iterator I = VM.begin(), E = VM.end();
131
std::pair<TypeParam*, int> value = *I; (void)value;
132
CompileAssertHasType<TypeParam*>(I->first);
133
if (I->second == 2) {
134
EXPECT_EQ(this->BitcastV.get(), I->first);
136
} else if (I->second == 3) {
137
EXPECT_EQ(this->AddV.get(), I->first);
140
ADD_FAILURE() << "Iterated through an extra value.";
144
EXPECT_EQ(5, VM[this->BitcastV.get()]);
145
EXPECT_EQ(6, VM[this->AddV.get()]);
148
// Cast to const ValueMap to avoid a bug in DenseMap's iterators.
149
const ValueMap<TypeParam*, int>& CVM = VM;
150
for (typename ValueMap<TypeParam*, int>::const_iterator I = CVM.begin(),
151
E = CVM.end(); I != E; ++I) {
153
std::pair<TypeParam*, int> value = *I; (void)value;
154
CompileAssertHasType<TypeParam*>(I->first);
155
if (I->second == 5) {
156
EXPECT_EQ(this->BitcastV.get(), I->first);
157
} else if (I->second == 6) {
158
EXPECT_EQ(this->AddV.get(), I->first);
160
ADD_FAILURE() << "Iterated through an extra value.";
166
TYPED_TEST(ValueMapTest, DefaultCollisionBehavior) {
167
// By default, we overwrite the old value with the replaced value.
168
ValueMap<TypeParam*, int> VM;
169
VM[this->BitcastV.get()] = 7;
170
VM[this->AddV.get()] = 9;
171
this->BitcastV->replaceAllUsesWith(this->AddV.get());
172
EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
173
EXPECT_EQ(9, VM.lookup(this->AddV.get()));
176
TYPED_TEST(ValueMapTest, ConfiguredCollisionBehavior) {
177
// TODO: Implement this when someone needs it.
180
template<typename KeyT, typename MutexT>
181
struct LockMutex : ValueMapConfig<KeyT, MutexT> {
187
static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
188
*Data.CalledRAUW = true;
189
EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
191
static void onDelete(const ExtraData &Data, KeyT Old) {
192
*Data.CalledDeleted = true;
193
EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
195
static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
197
// FIXME: These tests started failing on Windows.
198
#if LLVM_ENABLE_THREADS && !defined(LLVM_ON_WIN32)
199
TYPED_TEST(ValueMapTest, LocksMutex) {
200
sys::Mutex M(false); // Not recursive.
201
bool CalledRAUW = false, CalledDeleted = false;
202
typedef LockMutex<TypeParam*, sys::Mutex> ConfigType;
203
typename ConfigType::ExtraData Data = {&M, &CalledRAUW, &CalledDeleted};
204
ValueMap<TypeParam*, int, ConfigType> VM(Data);
205
VM[this->BitcastV.get()] = 7;
206
this->BitcastV->replaceAllUsesWith(this->AddV.get());
208
EXPECT_TRUE(CalledRAUW);
209
EXPECT_TRUE(CalledDeleted);
213
template<typename KeyT>
214
struct NoFollow : ValueMapConfig<KeyT> {
215
enum { FollowRAUW = false };
218
TYPED_TEST(ValueMapTest, NoFollowRAUW) {
219
ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM;
220
VM[this->BitcastV.get()] = 7;
221
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
222
EXPECT_EQ(0u, VM.count(this->AddV.get()));
223
this->BitcastV->replaceAllUsesWith(this->AddV.get());
224
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
225
EXPECT_EQ(0, VM.lookup(this->AddV.get()));
227
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
228
EXPECT_EQ(0, VM.lookup(this->AddV.get()));
229
this->BitcastV.reset();
230
EXPECT_EQ(0, VM.lookup(this->BitcastV.get()));
231
EXPECT_EQ(0, VM.lookup(this->AddV.get()));
232
EXPECT_EQ(0U, VM.size());
235
template<typename KeyT>
236
struct CountOps : ValueMapConfig<KeyT> {
242
static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
245
static void onDelete(const ExtraData &Data, KeyT Old) {
250
TYPED_TEST(ValueMapTest, CallsConfig) {
251
int Deletions = 0, RAUWs = 0;
252
typename CountOps<TypeParam*>::ExtraData Data = {&Deletions, &RAUWs};
253
ValueMap<TypeParam*, int, CountOps<TypeParam*> > VM(Data);
254
VM[this->BitcastV.get()] = 7;
255
this->BitcastV->replaceAllUsesWith(this->AddV.get());
256
EXPECT_EQ(0, Deletions);
259
EXPECT_EQ(1, Deletions);
261
this->BitcastV.reset();
262
EXPECT_EQ(1, Deletions);
266
template<typename KeyT>
267
struct ModifyingConfig : ValueMapConfig<KeyT> {
268
// We'll put a pointer here back to the ValueMap this key is in, so
269
// that we can modify it (and clobber *this) before the ValueMap
270
// tries to do the same modification. In previous versions of
271
// ValueMap, that exploded.
272
typedef ValueMap<KeyT, int, ModifyingConfig<KeyT> > **ExtraData;
274
static void onRAUW(ExtraData Map, KeyT Old, KeyT New) {
277
static void onDelete(ExtraData Map, KeyT Old) {
281
TYPED_TEST(ValueMapTest, SurvivesModificationByConfig) {
282
ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > *MapAddress;
283
ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > VM(&MapAddress);
285
// Now the ModifyingConfig can modify the Map inside a callback.
286
VM[this->BitcastV.get()] = 7;
287
this->BitcastV->replaceAllUsesWith(this->AddV.get());
288
EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
289
EXPECT_EQ(0u, VM.count(this->AddV.get()));
290
VM[this->AddV.get()] = 7;
292
EXPECT_EQ(0u, VM.count(this->AddV.get()));