1
//===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===//
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/DerivedTypes.h"
11
#include "llvm/GlobalVariable.h"
12
#include "llvm/LLVMContext.h"
13
#include "llvm/Module.h"
14
#include "llvm/ADT/OwningPtr.h"
15
#include "llvm/ExecutionEngine/Interpreter.h"
16
#include "gtest/gtest.h"
22
class ExecutionEngineTest : public testing::Test {
25
: M(new Module("<main>", getGlobalContext())),
26
Engine(EngineBuilder(M).create()) {
29
virtual void SetUp() {
30
ASSERT_TRUE(Engine.get() != NULL);
33
GlobalVariable *NewExtGlobal(const Type *T, const Twine &Name) {
34
return new GlobalVariable(*M, T, false, // Not constant.
35
GlobalValue::ExternalLinkage, NULL, Name);
39
const OwningPtr<ExecutionEngine> Engine;
42
TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
44
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
46
Engine->addGlobalMapping(G1, &Mem1);
47
EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1));
49
Engine->updateGlobalMapping(G1, &Mem2);
50
EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
51
Engine->updateGlobalMapping(G1, NULL);
52
EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G1));
53
Engine->updateGlobalMapping(G1, &Mem2);
54
EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
57
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
58
EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G2))
59
<< "The NULL return shouldn't depend on having called"
60
<< " updateGlobalMapping(..., NULL)";
61
// Check that update...() can be called before add...().
62
Engine->updateGlobalMapping(G2, &Mem1);
63
EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G2));
64
EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1))
65
<< "A second mapping shouldn't affect the first.";
68
TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
70
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
73
Engine->addGlobalMapping(G1, &Mem1);
74
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
76
Engine->updateGlobalMapping(G1, &Mem2);
77
EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
78
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
81
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
82
Engine->updateGlobalMapping(G2, &Mem1);
83
EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
84
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
85
Engine->updateGlobalMapping(G1, NULL);
86
EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1))
87
<< "Removing one mapping doesn't affect a different one.";
88
EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem2));
89
Engine->updateGlobalMapping(G2, &Mem2);
90
EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
91
EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2))
92
<< "Once a mapping is removed, we can point another GV at the"
93
<< " now-free address.";
96
TEST_F(ExecutionEngineTest, ClearModuleMappings) {
98
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
101
Engine->addGlobalMapping(G1, &Mem1);
102
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
104
Engine->clearGlobalMappingsFromModule(M);
106
EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
109
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
110
// After clearing the module mappings, we can assign a new GV to the
112
Engine->addGlobalMapping(G2, &Mem1);
113
EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
116
TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
118
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
120
Engine->addGlobalMapping(G1, &Mem1);
121
// Make sure the reverse mapping is enabled.
122
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
123
// When the GV goes away, the ExecutionEngine should remove any
124
// mappings that refer to it.
125
G1->eraseFromParent();
126
EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));