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; 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines VM1[nullptr] = 7; 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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())); 51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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())); 54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(0u, VM.count(this->BitcastV.get())); 5571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->AddV.reset(); 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(0u, VM.count(this->AddV.get())); 57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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); 93cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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()); 172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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 180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate<typename KeyT, typename MutexT> 181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstruct LockMutex : ValueMapConfig<KeyT, MutexT> { 18271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin struct ExtraData { 183cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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; 18971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked."; 19071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin } 1914ab74cdc124af6b4f57c2d2d09548e01d64a1f34Jeffrey Yasskin static void onDelete(const ExtraData &Data, KeyT Old) { 19271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin *Data.CalledDeleted = true; 19371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked."; 19471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin } 195cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static MutexT *getMutex(const ExtraData &Data) { return Data.M; } 19671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}; 1979f756cf4e293e5ac75db4636f7ea45ee85123f25Dylan Noblesmith#if LLVM_ENABLE_THREADS 19871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, LocksMutex) { 19971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin sys::Mutex M(false); // Not recursive. 20071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin bool CalledRAUW = false, CalledDeleted = false; 201cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines typedef LockMutex<TypeParam*, sys::Mutex> ConfigType; 202cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines typename ConfigType::ExtraData Data = {&M, &CalledRAUW, &CalledDeleted}; 203cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ValueMap<TypeParam*, int, ConfigType> VM(Data); 20471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin VM[this->BitcastV.get()] = 7; 20571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->BitcastV->replaceAllUsesWith(this->AddV.get()); 20671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->AddV.reset(); 20771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_TRUE(CalledRAUW); 20871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_TRUE(CalledDeleted); 20971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin} 210b83012a180dbd8d55672fd946ac9c6256cb00bceDuncan Sands#endif 21171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 21271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename KeyT> 21371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinstruct NoFollow : ValueMapConfig<KeyT> { 21471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin enum { FollowRAUW = false }; 21571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}; 21671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 21771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, NoFollowRAUW) { 21871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM; 21971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin VM[this->BitcastV.get()] = 7; 22071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(7, VM.lookup(this->BitcastV.get())); 221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(0u, VM.count(this->AddV.get())); 22271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->BitcastV->replaceAllUsesWith(this->AddV.get()); 22371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(7, VM.lookup(this->BitcastV.get())); 22471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(0, VM.lookup(this->AddV.get())); 22571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->AddV.reset(); 22671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(7, VM.lookup(this->BitcastV.get())); 22771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(0, VM.lookup(this->AddV.get())); 22871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->BitcastV.reset(); 22971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(0, VM.lookup(this->BitcastV.get())); 23071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(0, VM.lookup(this->AddV.get())); 23171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(0U, VM.size()); 23271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin} 23371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 23471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename KeyT> 23571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinstruct CountOps : ValueMapConfig<KeyT> { 23671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin struct ExtraData { 23771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin int *Deletions; 23871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin int *RAUWs; 23971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin }; 24071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 24171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) { 24271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin ++*Data.RAUWs; 24371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin } 2444ab74cdc124af6b4f57c2d2d09548e01d64a1f34Jeffrey Yasskin static void onDelete(const ExtraData &Data, KeyT Old) { 24571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin ++*Data.Deletions; 24671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin } 24771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}; 24871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 24971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, CallsConfig) { 25071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin int Deletions = 0, RAUWs = 0; 25171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin typename CountOps<TypeParam*>::ExtraData Data = {&Deletions, &RAUWs}; 25271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin ValueMap<TypeParam*, int, CountOps<TypeParam*> > VM(Data); 25371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin VM[this->BitcastV.get()] = 7; 25471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->BitcastV->replaceAllUsesWith(this->AddV.get()); 25571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(0, Deletions); 25671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(1, RAUWs); 25771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->AddV.reset(); 25871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(1, Deletions); 25971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(1, RAUWs); 26071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->BitcastV.reset(); 26171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(1, Deletions); 26271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin EXPECT_EQ(1, RAUWs); 26371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin} 26471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 26571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskintemplate<typename KeyT> 26671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskinstruct ModifyingConfig : ValueMapConfig<KeyT> { 26771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin // We'll put a pointer here back to the ValueMap this key is in, so 26871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin // that we can modify it (and clobber *this) before the ValueMap 26971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin // tries to do the same modification. In previous versions of 27071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin // ValueMap, that exploded. 27171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin typedef ValueMap<KeyT, int, ModifyingConfig<KeyT> > **ExtraData; 27271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 27371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin static void onRAUW(ExtraData Map, KeyT Old, KeyT New) { 27471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin (*Map)->erase(Old); 27571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin } 2764ab74cdc124af6b4f57c2d2d09548e01d64a1f34Jeffrey Yasskin static void onDelete(ExtraData Map, KeyT Old) { 27771a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin (*Map)->erase(Old); 27871a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin } 27971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin}; 28071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey YasskinTYPED_TEST(ValueMapTest, SurvivesModificationByConfig) { 28171a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > *MapAddress; 28271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > VM(&MapAddress); 28371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin MapAddress = &VM; 28471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin // Now the ModifyingConfig can modify the Map inside a callback. 28571a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin VM[this->BitcastV.get()] = 7; 28671a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->BitcastV->replaceAllUsesWith(this->AddV.get()); 287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(0u, VM.count(this->BitcastV.get())); 288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(0u, VM.count(this->AddV.get())); 28971a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin VM[this->AddV.get()] = 7; 29071a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin this->AddV.reset(); 291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(0u, VM.count(this->AddV.get())); 29271a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin} 29371a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin 29471a5c22c2b635ea903c3ae7d2695ca649b38726fJeffrey Yasskin} 295