166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===// 266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// The LLVM Compiler Infrastructure 466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This file is distributed under the University of Illinois Open Source 666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// License. See LICENSE.TXT for details. 766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===// 966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/ValueMap.h" 1166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Constants.h" 1266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Instructions.h" 1366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/LLVMContext.h" 1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/OwningPtr.h" 1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Config/config.h" 1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "gtest/gtest.h" 1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanusing namespace llvm; 2066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace { 2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Test fixture 2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantemplate<typename T> 2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanclass ValueMapTest : public testing::Test { 2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanprotected: 2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Constant *ConstantV; 2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<BitCastInst> BitcastV; 2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OwningPtr<BinaryOperator> AddV; 3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMapTest() : 3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)), 3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))), 3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) { 3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}; 3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 3866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Run everything on Value*, a subtype to make sure that casting works as 3966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// expected, and a const subtype to make sure we cast const correctly. 4066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantypedef ::testing::Types<Value, Instruction, const Instruction> KeyTypes; 4166b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST_CASE(ValueMapTest, KeyTypes); 4266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 4366b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, Null) { 4466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int> VM1; 4566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM1[NULL] = 7; 4666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, VM1.lookup(NULL)); 4766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 4866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 4966b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, FollowsValue) { 5066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int> VM; 5166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 7; 5266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, VM.lookup(this->BitcastV.get())); 5366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.count(this->AddV.get())); 5466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV->replaceAllUsesWith(this->AddV.get()); 5566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, VM.lookup(this->AddV.get())); 5666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.count(this->BitcastV.get())); 5766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->AddV.reset(); 5866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.count(this->AddV.get())); 5966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.count(this->BitcastV.get())); 6066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0U, VM.size()); 6166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 6266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 6366b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, OperationsWork) { 6466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int> VM; 6566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int> VM2(16); (void)VM2; 6666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typename ValueMapConfig<TypeParam*>::ExtraData Data; 6766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int> VM3(Data, 16); (void)VM3; 6866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_TRUE(VM.empty()); 6966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 7066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 7; 7166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 7266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Find: 7366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typename ValueMap<TypeParam*, int>::iterator I = 7466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM.find(this->BitcastV.get()); 7566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ASSERT_TRUE(I != VM.end()); 7666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->BitcastV.get(), I->first); 7766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, I->second); 7866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_TRUE(VM.find(this->AddV.get()) == VM.end()); 7966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Const find: 8166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const ValueMap<TypeParam*, int> &CVM = VM; 8266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typename ValueMap<TypeParam*, int>::const_iterator CI = 8366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman CVM.find(this->BitcastV.get()); 8466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ASSERT_TRUE(CI != CVM.end()); 8566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->BitcastV.get(), CI->first); 8666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, CI->second); 8766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_TRUE(CVM.find(this->AddV.get()) == CVM.end()); 8866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Insert: 9066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult1 = 9166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM.insert(std::make_pair(this->AddV.get(), 3)); 9266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->AddV.get(), InsertResult1.first->first); 9366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(3, InsertResult1.first->second); 9466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_TRUE(InsertResult1.second); 9566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(true, VM.count(this->AddV.get())); 9666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult2 = 9766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM.insert(std::make_pair(this->AddV.get(), 5)); 9866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->AddV.get(), InsertResult2.first->first); 9966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(3, InsertResult2.first->second); 10066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_FALSE(InsertResult2.second); 10166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 10266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Erase: 10366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM.erase(InsertResult2.first); 10466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0U, VM.count(this->AddV.get())); 10566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(1U, VM.count(this->BitcastV.get())); 10666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM.erase(this->BitcastV.get()); 10766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0U, VM.count(this->BitcastV.get())); 10866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0U, VM.size()); 10966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 11066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Range insert: 11166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman SmallVector<std::pair<Instruction*, int>, 2> Elems; 11266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Elems.push_back(std::make_pair(this->AddV.get(), 1)); 11366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Elems.push_back(std::make_pair(this->BitcastV.get(), 2)); 11466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM.insert(Elems.begin(), Elems.end()); 11566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(1, VM.lookup(this->AddV.get())); 11666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(2, VM.lookup(this->BitcastV.get())); 11766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 11866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 11966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantemplate<typename ExpectedType, typename VarType> 12066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid CompileAssertHasType(VarType) { 12166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typedef char assert[is_same<ExpectedType, VarType>::value ? 1 : -1]; 12266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 12366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 12466b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, Iteration) { 12566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int> VM; 12666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 2; 12766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->AddV.get()] = 3; 12866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman size_t size = 0; 12966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (typename ValueMap<TypeParam*, int>::iterator I = VM.begin(), E = VM.end(); 13066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman I != E; ++I) { 13166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ++size; 13266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::pair<TypeParam*, int> value = *I; (void)value; 13366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman CompileAssertHasType<TypeParam*>(I->first); 13466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (I->second == 2) { 13566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->BitcastV.get(), I->first); 13666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman I->second = 5; 13766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else if (I->second == 3) { 13866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->AddV.get(), I->first); 13966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman I->second = 6; 14066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else { 14166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ADD_FAILURE() << "Iterated through an extra value."; 14266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 14366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 14466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(2U, size); 14566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(5, VM[this->BitcastV.get()]); 14666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(6, VM[this->AddV.get()]); 14766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 14866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman size = 0; 14966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Cast to const ValueMap to avoid a bug in DenseMap's iterators. 15066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const ValueMap<TypeParam*, int>& CVM = VM; 15166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (typename ValueMap<TypeParam*, int>::const_iterator I = CVM.begin(), 15266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman E = CVM.end(); I != E; ++I) { 15366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ++size; 15466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::pair<TypeParam*, int> value = *I; (void)value; 15566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman CompileAssertHasType<TypeParam*>(I->first); 15666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (I->second == 5) { 15766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->BitcastV.get(), I->first); 15866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else if (I->second == 6) { 15966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(this->AddV.get(), I->first); 16066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else { 16166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ADD_FAILURE() << "Iterated through an extra value."; 16266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 16366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 16466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(2U, size); 16566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 16666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 16766b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, DefaultCollisionBehavior) { 16866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // By default, we overwrite the old value with the replaced value. 16966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int> VM; 17066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 7; 17166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->AddV.get()] = 9; 17266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV->replaceAllUsesWith(this->AddV.get()); 17366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.count(this->BitcastV.get())); 17466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(9, VM.lookup(this->AddV.get())); 17566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 17666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 17766b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, ConfiguredCollisionBehavior) { 17866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // TODO: Implement this when someone needs it. 17966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 18066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 18166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantemplate<typename KeyT> 18266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstruct LockMutex : ValueMapConfig<KeyT> { 18366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman struct ExtraData { 18466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Mutex *M; 18566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman bool *CalledRAUW; 18666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman bool *CalledDeleted; 18766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman }; 18866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) { 18966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman *Data.CalledRAUW = true; 19066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked."; 19166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 19266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static void onDelete(const ExtraData &Data, KeyT Old) { 19366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman *Data.CalledDeleted = true; 19466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked."; 19566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 19666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static sys::Mutex *getMutex(const ExtraData &Data) { return Data.M; } 19766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}; 19866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#if ENABLE_THREADS 19966b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, LocksMutex) { 20066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Mutex M(false); // Not recursive. 20166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman bool CalledRAUW = false, CalledDeleted = false; 20266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typename LockMutex<TypeParam*>::ExtraData Data = 20366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman {&M, &CalledRAUW, &CalledDeleted}; 20466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int, LockMutex<TypeParam*> > VM(Data); 20566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 7; 20666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV->replaceAllUsesWith(this->AddV.get()); 20766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->AddV.reset(); 20866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_TRUE(CalledRAUW); 20966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_TRUE(CalledDeleted); 21066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 21166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif 21266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 21366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantemplate<typename KeyT> 21466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstruct NoFollow : ValueMapConfig<KeyT> { 21566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman enum { FollowRAUW = false }; 21666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}; 21766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 21866b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, NoFollowRAUW) { 21966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM; 22066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 7; 22166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, VM.lookup(this->BitcastV.get())); 22266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.count(this->AddV.get())); 22366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV->replaceAllUsesWith(this->AddV.get()); 22466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, VM.lookup(this->BitcastV.get())); 22566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.lookup(this->AddV.get())); 22666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->AddV.reset(); 22766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(7, VM.lookup(this->BitcastV.get())); 22866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.lookup(this->AddV.get())); 22966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV.reset(); 23066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.lookup(this->BitcastV.get())); 23166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, VM.lookup(this->AddV.get())); 23266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0U, VM.size()); 23366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 23466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 23566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantemplate<typename KeyT> 23666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstruct CountOps : ValueMapConfig<KeyT> { 23766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman struct ExtraData { 23866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman int *Deletions; 23966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman int *RAUWs; 24066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman }; 24166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 24266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) { 24366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ++*Data.RAUWs; 24466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 24566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static void onDelete(const ExtraData &Data, KeyT Old) { 24666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ++*Data.Deletions; 24766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 24866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}; 24966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 25066b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, CallsConfig) { 25166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman int Deletions = 0, RAUWs = 0; 25266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typename CountOps<TypeParam*>::ExtraData Data = {&Deletions, &RAUWs}; 25366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int, CountOps<TypeParam*> > VM(Data); 25466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 7; 25566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV->replaceAllUsesWith(this->AddV.get()); 25666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(0, Deletions); 25766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(1, RAUWs); 25866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->AddV.reset(); 25966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(1, Deletions); 26066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(1, RAUWs); 26166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV.reset(); 26266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(1, Deletions); 26366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_EQ(1, RAUWs); 26466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 26566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 26666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantemplate<typename KeyT> 26766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstruct ModifyingConfig : ValueMapConfig<KeyT> { 26866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // We'll put a pointer here back to the ValueMap this key is in, so 26966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // that we can modify it (and clobber *this) before the ValueMap 27066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // tries to do the same modification. In previous versions of 27166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // ValueMap, that exploded. 27266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman typedef ValueMap<KeyT, int, ModifyingConfig<KeyT> > **ExtraData; 27366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 27466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static void onRAUW(ExtraData Map, KeyT Old, KeyT New) { 27566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman (*Map)->erase(Old); 27666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 27766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman static void onDelete(ExtraData Map, KeyT Old) { 27866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman (*Map)->erase(Old); 27966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 28066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}; 28166b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanTYPED_TEST(ValueMapTest, SurvivesModificationByConfig) { 28266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > *MapAddress; 28366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > VM(&MapAddress); 28466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman MapAddress = &VM; 28566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Now the ModifyingConfig can modify the Map inside a callback. 28666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->BitcastV.get()] = 7; 28766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->BitcastV->replaceAllUsesWith(this->AddV.get()); 28866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_FALSE(VM.count(this->BitcastV.get())); 28966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_FALSE(VM.count(this->AddV.get())); 29066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman VM[this->AddV.get()] = 7; 29166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman this->AddV.reset(); 29266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EXPECT_FALSE(VM.count(this->AddV.get())); 29366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 29466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 29566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 296