171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin//===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===//
271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin//
371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin//                     The LLVM Compiler Infrastructure
471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin//
571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// This file is distributed under the University of Illinois Open Source
671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// License. See LICENSE.TXT for details.
771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin//
871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin//===----------------------------------------------------------------------===//
971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/ValueMap.h"
115a88dda4be791426ab4d20a6a6c9c65d66614a27Chandler Carruth#include "llvm/Config/llvm-config.h"
120b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
130b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h"
140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
1571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin#include "gtest/gtest.h"
1671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
1771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinusing namespace llvm;
1871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
1971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinnamespace {
2071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
2171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// Test fixture
2271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename T>
2371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinclass ValueMapTest : public testing::Test {
2471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinprotected:
2571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  Constant *ConstantV;
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<BitCastInst> BitcastV;
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<BinaryOperator> AddV;
2871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
2971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMapTest() :
3071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
3171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))),
3271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) {
3371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
3471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin};
3571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
3671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// Run everything on Value*, a subtype to make sure that casting works as
3771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin// expected, and a const subtype to make sure we cast const correctly.
3871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintypedef ::testing::Types<Value, Instruction, const Instruction> KeyTypes;
3971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST_CASE(ValueMapTest, KeyTypes);
4071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
4171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, Null) {
4271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int> VM1;
43c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  VM1[nullptr] = 7;
44c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(7, VM1.lookup(nullptr));
4571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
4671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
4771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, FollowsValue) {
4871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int> VM;
4971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 7;
5071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
51c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->AddV.get()));
5271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV->replaceAllUsesWith(this->AddV.get());
5371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(7, VM.lookup(this->AddV.get()));
54c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
5571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->AddV.reset();
56c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->AddV.get()));
57c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
5871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0U, VM.size());
5971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
6071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
6171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, OperationsWork) {
6271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int> VM;
63a07cd90a2a13f86f7491d1fd58e71521936b086dChris Lattner  ValueMap<TypeParam*, int> VM2(16);  (void)VM2;
6471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  typename ValueMapConfig<TypeParam*>::ExtraData Data;
65a07cd90a2a13f86f7491d1fd58e71521936b086dChris Lattner  ValueMap<TypeParam*, int> VM3(Data, 16);  (void)VM3;
6671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_TRUE(VM.empty());
6771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
6871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 7;
6971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
7071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // Find:
7171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  typename ValueMap<TypeParam*, int>::iterator I =
7271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    VM.find(this->BitcastV.get());
7371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ASSERT_TRUE(I != VM.end());
74e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach  EXPECT_EQ(this->BitcastV.get(), I->first);
7571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(7, I->second);
76e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach  EXPECT_TRUE(VM.find(this->AddV.get()) == VM.end());
7771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
7871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // Const find:
7971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  const ValueMap<TypeParam*, int> &CVM = VM;
8071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  typename ValueMap<TypeParam*, int>::const_iterator CI =
8171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    CVM.find(this->BitcastV.get());
8271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ASSERT_TRUE(CI != CVM.end());
83e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach  EXPECT_EQ(this->BitcastV.get(), CI->first);
8471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(7, CI->second);
8571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_TRUE(CVM.find(this->AddV.get()) == CVM.end());
8671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
8771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // Insert:
8871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult1 =
8971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    VM.insert(std::make_pair(this->AddV.get(), 3));
90e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach  EXPECT_EQ(this->AddV.get(), InsertResult1.first->first);
9171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(3, InsertResult1.first->second);
9271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_TRUE(InsertResult1.second);
93c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(1u, VM.count(this->AddV.get()));
9471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult2 =
9571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    VM.insert(std::make_pair(this->AddV.get(), 5));
96e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach  EXPECT_EQ(this->AddV.get(), InsertResult2.first->first);
9771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(3, InsertResult2.first->second);
9871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_FALSE(InsertResult2.second);
9971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
10071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // Erase:
10171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM.erase(InsertResult2.first);
1023732396fe1513c4d20661e65c538ce368f153557Bill Wendling  EXPECT_EQ(0U, VM.count(this->AddV.get()));
1033732396fe1513c4d20661e65c538ce368f153557Bill Wendling  EXPECT_EQ(1U, VM.count(this->BitcastV.get()));
10471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM.erase(this->BitcastV.get());
1053732396fe1513c4d20661e65c538ce368f153557Bill Wendling  EXPECT_EQ(0U, VM.count(this->BitcastV.get()));
10671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0U, VM.size());
10771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
10871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // Range insert:
10971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  SmallVector<std::pair<Instruction*, int>, 2> Elems;
11071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  Elems.push_back(std::make_pair(this->AddV.get(), 1));
11171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  Elems.push_back(std::make_pair(this->BitcastV.get(), 2));
11271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM.insert(Elems.begin(), Elems.end());
11371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(1, VM.lookup(this->AddV.get()));
11471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(2, VM.lookup(this->BitcastV.get()));
11571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
11671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
11771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename ExpectedType, typename VarType>
11871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinvoid CompileAssertHasType(VarType) {
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static_assert(std::is_same<ExpectedType, VarType>::value,
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                "Not the same type");
12171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
12271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
12371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, Iteration) {
12471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int> VM;
12571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 2;
12671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->AddV.get()] = 3;
12771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  size_t size = 0;
12871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  for (typename ValueMap<TypeParam*, int>::iterator I = VM.begin(), E = VM.end();
12971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin       I != E; ++I) {
13071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    ++size;
131a07cd90a2a13f86f7491d1fd58e71521936b086dChris Lattner    std::pair<TypeParam*, int> value = *I; (void)value;
13271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    CompileAssertHasType<TypeParam*>(I->first);
13371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    if (I->second == 2) {
134e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach      EXPECT_EQ(this->BitcastV.get(), I->first);
13571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin      I->second = 5;
13671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    } else if (I->second == 3) {
137e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach      EXPECT_EQ(this->AddV.get(), I->first);
13871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin      I->second = 6;
13971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    } else {
14071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin      ADD_FAILURE() << "Iterated through an extra value.";
14171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    }
14271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
14371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(2U, size);
14471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(5, VM[this->BitcastV.get()]);
14571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(6, VM[this->AddV.get()]);
14671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
14771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  size = 0;
14871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // Cast to const ValueMap to avoid a bug in DenseMap's iterators.
14971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  const ValueMap<TypeParam*, int>& CVM = VM;
15071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  for (typename ValueMap<TypeParam*, int>::const_iterator I = CVM.begin(),
15171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin         E = CVM.end(); I != E; ++I) {
15271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    ++size;
153a07cd90a2a13f86f7491d1fd58e71521936b086dChris Lattner    std::pair<TypeParam*, int> value = *I;  (void)value;
15471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    CompileAssertHasType<TypeParam*>(I->first);
15571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    if (I->second == 5) {
156e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach      EXPECT_EQ(this->BitcastV.get(), I->first);
15771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    } else if (I->second == 6) {
158e541528e351668fb5b6eebbd168aed73d7ff563bJim Grosbach      EXPECT_EQ(this->AddV.get(), I->first);
15971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    } else {
16071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin      ADD_FAILURE() << "Iterated through an extra value.";
16171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    }
16271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
16371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(2U, size);
16471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
16571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
16671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, DefaultCollisionBehavior) {
16771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // By default, we overwrite the old value with the replaced value.
16871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int> VM;
16971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 7;
17071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->AddV.get()] = 9;
17171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV->replaceAllUsesWith(this->AddV.get());
172c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
17371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(9, VM.lookup(this->AddV.get()));
17471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
17571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
17671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, ConfiguredCollisionBehavior) {
17771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // TODO: Implement this when someone needs it.
17871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
17971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate<typename KeyT, typename MutexT>
181c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstruct LockMutex : ValueMapConfig<KeyT, MutexT> {
18271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  struct ExtraData {
183c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    MutexT *M;
18471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    bool *CalledRAUW;
18571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    bool *CalledDeleted;
18671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  };
18771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
18871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    *Data.CalledRAUW = true;
18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
19071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
1914ab74cdc124af6b4f57c2d2d09548e01d64a1f34Jeffrey Yasskin  static void onDelete(const ExtraData &Data, KeyT Old) {
19271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    *Data.CalledDeleted = true;
19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
19471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
195c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
19671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin};
1972c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar// FIXME: These tests started failing on Windows.
1982c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar#if LLVM_ENABLE_THREADS && !defined(LLVM_ON_WIN32)
19971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, LocksMutex) {
20071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  sys::Mutex M(false);  // Not recursive.
20171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  bool CalledRAUW = false, CalledDeleted = false;
202c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typedef LockMutex<TypeParam*, sys::Mutex> ConfigType;
203c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typename ConfigType::ExtraData Data = {&M, &CalledRAUW, &CalledDeleted};
204c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ValueMap<TypeParam*, int, ConfigType> VM(Data);
20571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 7;
20671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV->replaceAllUsesWith(this->AddV.get());
20771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->AddV.reset();
20871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_TRUE(CalledRAUW);
20971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_TRUE(CalledDeleted);
21071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
211b83012a180dbd8d55672fd946ac9c6256cb00bceDuncan Sands#endif
21271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
21371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename KeyT>
21471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinstruct NoFollow : ValueMapConfig<KeyT> {
21571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  enum { FollowRAUW = false };
21671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin};
21771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
21871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, NoFollowRAUW) {
21971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM;
22071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 7;
22171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
222c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->AddV.get()));
22371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV->replaceAllUsesWith(this->AddV.get());
22471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
22571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0, VM.lookup(this->AddV.get()));
22671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->AddV.reset();
22771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
22871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0, VM.lookup(this->AddV.get()));
22971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV.reset();
23071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0, VM.lookup(this->BitcastV.get()));
23171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0, VM.lookup(this->AddV.get()));
23271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0U, VM.size());
23371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
23471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
23571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename KeyT>
23671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinstruct CountOps : ValueMapConfig<KeyT> {
23771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  struct ExtraData {
23871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    int *Deletions;
23971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    int *RAUWs;
24071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  };
24171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
24271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
24371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    ++*Data.RAUWs;
24471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
2454ab74cdc124af6b4f57c2d2d09548e01d64a1f34Jeffrey Yasskin  static void onDelete(const ExtraData &Data, KeyT Old) {
24671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    ++*Data.Deletions;
24771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
24871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin};
24971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
25071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, CallsConfig) {
25171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  int Deletions = 0, RAUWs = 0;
25271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  typename CountOps<TypeParam*>::ExtraData Data = {&Deletions, &RAUWs};
25371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int, CountOps<TypeParam*> > VM(Data);
25471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 7;
25571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV->replaceAllUsesWith(this->AddV.get());
25671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(0, Deletions);
25771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(1, RAUWs);
25871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->AddV.reset();
25971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(1, Deletions);
26071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(1, RAUWs);
26171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV.reset();
26271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(1, Deletions);
26371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  EXPECT_EQ(1, RAUWs);
26471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
26571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
26671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename KeyT>
26771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinstruct ModifyingConfig : ValueMapConfig<KeyT> {
26871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // We'll put a pointer here back to the ValueMap this key is in, so
26971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // that we can modify it (and clobber *this) before the ValueMap
27071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // tries to do the same modification.  In previous versions of
27171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // ValueMap, that exploded.
27271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  typedef ValueMap<KeyT, int, ModifyingConfig<KeyT> > **ExtraData;
27371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
27471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  static void onRAUW(ExtraData Map, KeyT Old, KeyT New) {
27571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    (*Map)->erase(Old);
27671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
2774ab74cdc124af6b4f57c2d2d09548e01d64a1f34Jeffrey Yasskin  static void onDelete(ExtraData Map, KeyT Old) {
27871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin    (*Map)->erase(Old);
27971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  }
28071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin};
28171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, SurvivesModificationByConfig) {
28271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > *MapAddress;
28371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > VM(&MapAddress);
28471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  MapAddress = &VM;
28571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  // Now the ModifyingConfig can modify the Map inside a callback.
28671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->BitcastV.get()] = 7;
28771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->BitcastV->replaceAllUsesWith(this->AddV.get());
288c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
289c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->AddV.get()));
29071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  VM[this->AddV.get()] = 7;
29171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin  this->AddV.reset();
292c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EXPECT_EQ(0u, VM.count(this->AddV.get()));
29371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
29471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin
29571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}
296