mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-04 07:32:13 +00:00
0b8c9a80f2
into their new header subdirectory: include/llvm/IR. This matches the directory structure of lib, and begins to correct a long standing point of file layout clutter in LLVM. There are still more header files to move here, but I wanted to handle them in separate commits to make tracking what files make sense at each layer easier. The only really questionable files here are the target intrinsic tablegen files. But that's a battle I'd rather not fight today. I've updated both CMake and Makefile build systems (I think, and my tests think, but I may have missed something). I've also re-sorted the includes throughout the project. I'll be committing updates to Clang, DragonEgg, and Polly momentarily. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171366 91177308-0d34-0410-b5e6-96231b3b80d8
295 lines
9.4 KiB
C++
295 lines
9.4 KiB
C++
//===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/ValueMap.h"
|
|
#include "llvm/ADT/OwningPtr.h"
|
|
#include "llvm/Config/llvm-config.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
// Test fixture
|
|
template<typename T>
|
|
class ValueMapTest : public testing::Test {
|
|
protected:
|
|
Constant *ConstantV;
|
|
OwningPtr<BitCastInst> BitcastV;
|
|
OwningPtr<BinaryOperator> AddV;
|
|
|
|
ValueMapTest() :
|
|
ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
|
|
BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))),
|
|
AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) {
|
|
}
|
|
};
|
|
|
|
// Run everything on Value*, a subtype to make sure that casting works as
|
|
// expected, and a const subtype to make sure we cast const correctly.
|
|
typedef ::testing::Types<Value, Instruction, const Instruction> KeyTypes;
|
|
TYPED_TEST_CASE(ValueMapTest, KeyTypes);
|
|
|
|
TYPED_TEST(ValueMapTest, Null) {
|
|
ValueMap<TypeParam*, int> VM1;
|
|
VM1[NULL] = 7;
|
|
EXPECT_EQ(7, VM1.lookup(NULL));
|
|
}
|
|
|
|
TYPED_TEST(ValueMapTest, FollowsValue) {
|
|
ValueMap<TypeParam*, int> VM;
|
|
VM[this->BitcastV.get()] = 7;
|
|
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
|
|
EXPECT_EQ(0, VM.count(this->AddV.get()));
|
|
this->BitcastV->replaceAllUsesWith(this->AddV.get());
|
|
EXPECT_EQ(7, VM.lookup(this->AddV.get()));
|
|
EXPECT_EQ(0, VM.count(this->BitcastV.get()));
|
|
this->AddV.reset();
|
|
EXPECT_EQ(0, VM.count(this->AddV.get()));
|
|
EXPECT_EQ(0, VM.count(this->BitcastV.get()));
|
|
EXPECT_EQ(0U, VM.size());
|
|
}
|
|
|
|
TYPED_TEST(ValueMapTest, OperationsWork) {
|
|
ValueMap<TypeParam*, int> VM;
|
|
ValueMap<TypeParam*, int> VM2(16); (void)VM2;
|
|
typename ValueMapConfig<TypeParam*>::ExtraData Data;
|
|
ValueMap<TypeParam*, int> VM3(Data, 16); (void)VM3;
|
|
EXPECT_TRUE(VM.empty());
|
|
|
|
VM[this->BitcastV.get()] = 7;
|
|
|
|
// Find:
|
|
typename ValueMap<TypeParam*, int>::iterator I =
|
|
VM.find(this->BitcastV.get());
|
|
ASSERT_TRUE(I != VM.end());
|
|
EXPECT_EQ(this->BitcastV.get(), I->first);
|
|
EXPECT_EQ(7, I->second);
|
|
EXPECT_TRUE(VM.find(this->AddV.get()) == VM.end());
|
|
|
|
// Const find:
|
|
const ValueMap<TypeParam*, int> &CVM = VM;
|
|
typename ValueMap<TypeParam*, int>::const_iterator CI =
|
|
CVM.find(this->BitcastV.get());
|
|
ASSERT_TRUE(CI != CVM.end());
|
|
EXPECT_EQ(this->BitcastV.get(), CI->first);
|
|
EXPECT_EQ(7, CI->second);
|
|
EXPECT_TRUE(CVM.find(this->AddV.get()) == CVM.end());
|
|
|
|
// Insert:
|
|
std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult1 =
|
|
VM.insert(std::make_pair(this->AddV.get(), 3));
|
|
EXPECT_EQ(this->AddV.get(), InsertResult1.first->first);
|
|
EXPECT_EQ(3, InsertResult1.first->second);
|
|
EXPECT_TRUE(InsertResult1.second);
|
|
EXPECT_EQ(true, VM.count(this->AddV.get()));
|
|
std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult2 =
|
|
VM.insert(std::make_pair(this->AddV.get(), 5));
|
|
EXPECT_EQ(this->AddV.get(), InsertResult2.first->first);
|
|
EXPECT_EQ(3, InsertResult2.first->second);
|
|
EXPECT_FALSE(InsertResult2.second);
|
|
|
|
// Erase:
|
|
VM.erase(InsertResult2.first);
|
|
EXPECT_EQ(0U, VM.count(this->AddV.get()));
|
|
EXPECT_EQ(1U, VM.count(this->BitcastV.get()));
|
|
VM.erase(this->BitcastV.get());
|
|
EXPECT_EQ(0U, VM.count(this->BitcastV.get()));
|
|
EXPECT_EQ(0U, VM.size());
|
|
|
|
// Range insert:
|
|
SmallVector<std::pair<Instruction*, int>, 2> Elems;
|
|
Elems.push_back(std::make_pair(this->AddV.get(), 1));
|
|
Elems.push_back(std::make_pair(this->BitcastV.get(), 2));
|
|
VM.insert(Elems.begin(), Elems.end());
|
|
EXPECT_EQ(1, VM.lookup(this->AddV.get()));
|
|
EXPECT_EQ(2, VM.lookup(this->BitcastV.get()));
|
|
}
|
|
|
|
template<typename ExpectedType, typename VarType>
|
|
void CompileAssertHasType(VarType) {
|
|
typedef char assert[is_same<ExpectedType, VarType>::value ? 1 : -1];
|
|
}
|
|
|
|
TYPED_TEST(ValueMapTest, Iteration) {
|
|
ValueMap<TypeParam*, int> VM;
|
|
VM[this->BitcastV.get()] = 2;
|
|
VM[this->AddV.get()] = 3;
|
|
size_t size = 0;
|
|
for (typename ValueMap<TypeParam*, int>::iterator I = VM.begin(), E = VM.end();
|
|
I != E; ++I) {
|
|
++size;
|
|
std::pair<TypeParam*, int> value = *I; (void)value;
|
|
CompileAssertHasType<TypeParam*>(I->first);
|
|
if (I->second == 2) {
|
|
EXPECT_EQ(this->BitcastV.get(), I->first);
|
|
I->second = 5;
|
|
} else if (I->second == 3) {
|
|
EXPECT_EQ(this->AddV.get(), I->first);
|
|
I->second = 6;
|
|
} else {
|
|
ADD_FAILURE() << "Iterated through an extra value.";
|
|
}
|
|
}
|
|
EXPECT_EQ(2U, size);
|
|
EXPECT_EQ(5, VM[this->BitcastV.get()]);
|
|
EXPECT_EQ(6, VM[this->AddV.get()]);
|
|
|
|
size = 0;
|
|
// Cast to const ValueMap to avoid a bug in DenseMap's iterators.
|
|
const ValueMap<TypeParam*, int>& CVM = VM;
|
|
for (typename ValueMap<TypeParam*, int>::const_iterator I = CVM.begin(),
|
|
E = CVM.end(); I != E; ++I) {
|
|
++size;
|
|
std::pair<TypeParam*, int> value = *I; (void)value;
|
|
CompileAssertHasType<TypeParam*>(I->first);
|
|
if (I->second == 5) {
|
|
EXPECT_EQ(this->BitcastV.get(), I->first);
|
|
} else if (I->second == 6) {
|
|
EXPECT_EQ(this->AddV.get(), I->first);
|
|
} else {
|
|
ADD_FAILURE() << "Iterated through an extra value.";
|
|
}
|
|
}
|
|
EXPECT_EQ(2U, size);
|
|
}
|
|
|
|
TYPED_TEST(ValueMapTest, DefaultCollisionBehavior) {
|
|
// By default, we overwrite the old value with the replaced value.
|
|
ValueMap<TypeParam*, int> VM;
|
|
VM[this->BitcastV.get()] = 7;
|
|
VM[this->AddV.get()] = 9;
|
|
this->BitcastV->replaceAllUsesWith(this->AddV.get());
|
|
EXPECT_EQ(0, VM.count(this->BitcastV.get()));
|
|
EXPECT_EQ(9, VM.lookup(this->AddV.get()));
|
|
}
|
|
|
|
TYPED_TEST(ValueMapTest, ConfiguredCollisionBehavior) {
|
|
// TODO: Implement this when someone needs it.
|
|
}
|
|
|
|
template<typename KeyT>
|
|
struct LockMutex : ValueMapConfig<KeyT> {
|
|
struct ExtraData {
|
|
sys::Mutex *M;
|
|
bool *CalledRAUW;
|
|
bool *CalledDeleted;
|
|
};
|
|
static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
|
|
*Data.CalledRAUW = true;
|
|
EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked.";
|
|
}
|
|
static void onDelete(const ExtraData &Data, KeyT Old) {
|
|
*Data.CalledDeleted = true;
|
|
EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked.";
|
|
}
|
|
static sys::Mutex *getMutex(const ExtraData &Data) { return Data.M; }
|
|
};
|
|
#if LLVM_ENABLE_THREADS
|
|
TYPED_TEST(ValueMapTest, LocksMutex) {
|
|
sys::Mutex M(false); // Not recursive.
|
|
bool CalledRAUW = false, CalledDeleted = false;
|
|
typename LockMutex<TypeParam*>::ExtraData Data =
|
|
{&M, &CalledRAUW, &CalledDeleted};
|
|
ValueMap<TypeParam*, int, LockMutex<TypeParam*> > VM(Data);
|
|
VM[this->BitcastV.get()] = 7;
|
|
this->BitcastV->replaceAllUsesWith(this->AddV.get());
|
|
this->AddV.reset();
|
|
EXPECT_TRUE(CalledRAUW);
|
|
EXPECT_TRUE(CalledDeleted);
|
|
}
|
|
#endif
|
|
|
|
template<typename KeyT>
|
|
struct NoFollow : ValueMapConfig<KeyT> {
|
|
enum { FollowRAUW = false };
|
|
};
|
|
|
|
TYPED_TEST(ValueMapTest, NoFollowRAUW) {
|
|
ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM;
|
|
VM[this->BitcastV.get()] = 7;
|
|
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
|
|
EXPECT_EQ(0, VM.count(this->AddV.get()));
|
|
this->BitcastV->replaceAllUsesWith(this->AddV.get());
|
|
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
|
|
EXPECT_EQ(0, VM.lookup(this->AddV.get()));
|
|
this->AddV.reset();
|
|
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
|
|
EXPECT_EQ(0, VM.lookup(this->AddV.get()));
|
|
this->BitcastV.reset();
|
|
EXPECT_EQ(0, VM.lookup(this->BitcastV.get()));
|
|
EXPECT_EQ(0, VM.lookup(this->AddV.get()));
|
|
EXPECT_EQ(0U, VM.size());
|
|
}
|
|
|
|
template<typename KeyT>
|
|
struct CountOps : ValueMapConfig<KeyT> {
|
|
struct ExtraData {
|
|
int *Deletions;
|
|
int *RAUWs;
|
|
};
|
|
|
|
static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
|
|
++*Data.RAUWs;
|
|
}
|
|
static void onDelete(const ExtraData &Data, KeyT Old) {
|
|
++*Data.Deletions;
|
|
}
|
|
};
|
|
|
|
TYPED_TEST(ValueMapTest, CallsConfig) {
|
|
int Deletions = 0, RAUWs = 0;
|
|
typename CountOps<TypeParam*>::ExtraData Data = {&Deletions, &RAUWs};
|
|
ValueMap<TypeParam*, int, CountOps<TypeParam*> > VM(Data);
|
|
VM[this->BitcastV.get()] = 7;
|
|
this->BitcastV->replaceAllUsesWith(this->AddV.get());
|
|
EXPECT_EQ(0, Deletions);
|
|
EXPECT_EQ(1, RAUWs);
|
|
this->AddV.reset();
|
|
EXPECT_EQ(1, Deletions);
|
|
EXPECT_EQ(1, RAUWs);
|
|
this->BitcastV.reset();
|
|
EXPECT_EQ(1, Deletions);
|
|
EXPECT_EQ(1, RAUWs);
|
|
}
|
|
|
|
template<typename KeyT>
|
|
struct ModifyingConfig : ValueMapConfig<KeyT> {
|
|
// We'll put a pointer here back to the ValueMap this key is in, so
|
|
// that we can modify it (and clobber *this) before the ValueMap
|
|
// tries to do the same modification. In previous versions of
|
|
// ValueMap, that exploded.
|
|
typedef ValueMap<KeyT, int, ModifyingConfig<KeyT> > **ExtraData;
|
|
|
|
static void onRAUW(ExtraData Map, KeyT Old, KeyT New) {
|
|
(*Map)->erase(Old);
|
|
}
|
|
static void onDelete(ExtraData Map, KeyT Old) {
|
|
(*Map)->erase(Old);
|
|
}
|
|
};
|
|
TYPED_TEST(ValueMapTest, SurvivesModificationByConfig) {
|
|
ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > *MapAddress;
|
|
ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > VM(&MapAddress);
|
|
MapAddress = &VM;
|
|
// Now the ModifyingConfig can modify the Map inside a callback.
|
|
VM[this->BitcastV.get()] = 7;
|
|
this->BitcastV->replaceAllUsesWith(this->AddV.get());
|
|
EXPECT_FALSE(VM.count(this->BitcastV.get()));
|
|
EXPECT_FALSE(VM.count(this->AddV.get()));
|
|
VM[this->AddV.get()] = 7;
|
|
this->AddV.reset();
|
|
EXPECT_FALSE(VM.count(this->AddV.get()));
|
|
}
|
|
|
|
}
|