When removing a function from the function set and adding it to deferred, we
[llvm.git] / unittests / ExecutionEngine / ExecutionEngineTest.cpp
blob904ee2b6c49fb3fcf23fc08fca758d7d4ac43291
1 //===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
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"
18 using namespace llvm;
20 namespace {
22 class ExecutionEngineTest : public testing::Test {
23 protected:
24 ExecutionEngineTest()
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);
38 Module *const M;
39 const OwningPtr<ExecutionEngine> Engine;
42 TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
43 GlobalVariable *G1 =
44 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
45 int32_t Mem1 = 3;
46 Engine->addGlobalMapping(G1, &Mem1);
47 EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1));
48 int32_t Mem2 = 4;
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));
56 GlobalVariable *G2 =
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) {
69 GlobalVariable *G1 =
70 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
72 int32_t Mem1 = 3;
73 Engine->addGlobalMapping(G1, &Mem1);
74 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
75 int32_t Mem2 = 4;
76 Engine->updateGlobalMapping(G1, &Mem2);
77 EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
78 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
80 GlobalVariable *G2 =
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) {
97 GlobalVariable *G1 =
98 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
100 int32_t Mem1 = 3;
101 Engine->addGlobalMapping(G1, &Mem1);
102 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
104 Engine->clearGlobalMappingsFromModule(M);
106 EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
108 GlobalVariable *G2 =
109 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
110 // After clearing the module mappings, we can assign a new GV to the
111 // same address.
112 Engine->addGlobalMapping(G2, &Mem1);
113 EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
116 TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
117 GlobalVariable *G1 =
118 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
119 int32_t Mem1 = 3;
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));