blob: 326213c93681ef5cb0881607846c1af3257fb060 [file] [log] [blame]
Jeffrey Yasskin337b1242009-08-04 23:53:16 +00001//===- 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//===----------------------------------------------------------------------===//
9
Chandler Carruth130cec22012-12-04 10:23:08 +000010#include "llvm/ExecutionEngine/Interpreter.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000011#include "llvm/IR/DerivedTypes.h"
12#include "llvm/IR/GlobalVariable.h"
13#include "llvm/IR/LLVMContext.h"
14#include "llvm/IR/Module.h"
NAKAMURA Takumi4d723ba2014-09-23 13:49:51 +000015#include "llvm/Support/ManagedStatic.h"
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000016#include "gtest/gtest.h"
17
18using namespace llvm;
19
20namespace {
21
22class ExecutionEngineTest : public testing::Test {
NAKAMURA Takumidbf2c212014-09-23 14:41:02 +000023private:
24 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
25
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000026protected:
Rafael Espindola2a8a2792014-08-19 04:04:25 +000027 ExecutionEngineTest() {
28 auto Owner = make_unique<Module>("<main>", getGlobalContext());
29 M = Owner.get();
30 Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create());
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000031 }
32
33 virtual void SetUp() {
Craig Topper66f09ad2014-06-08 22:29:17 +000034 ASSERT_TRUE(Engine.get() != nullptr) << "EngineBuilder returned error: '"
Dylan Noblesmithf6f9f1d2011-12-02 20:53:53 +000035 << Error << "'";
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000036 }
37
Chris Lattner229907c2011-07-18 04:54:35 +000038 GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) {
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000039 return new GlobalVariable(*M, T, false, // Not constant.
Craig Topper66f09ad2014-06-08 22:29:17 +000040 GlobalValue::ExternalLinkage, nullptr, Name);
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000041 }
42
Dylan Noblesmithf6f9f1d2011-12-02 20:53:53 +000043 std::string Error;
Rafael Espindola2a8a2792014-08-19 04:04:25 +000044 Module *M; // Owned by ExecutionEngine.
45 std::unique_ptr<ExecutionEngine> Engine;
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000046};
47
48TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
Owen Anderson55f1c092009-08-13 21:58:54 +000049 GlobalVariable *G1 =
50 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000051 int32_t Mem1 = 3;
52 Engine->addGlobalMapping(G1, &Mem1);
53 EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1));
54 int32_t Mem2 = 4;
55 Engine->updateGlobalMapping(G1, &Mem2);
56 EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
Craig Topper66f09ad2014-06-08 22:29:17 +000057 Engine->updateGlobalMapping(G1, nullptr);
58 EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G1));
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000059 Engine->updateGlobalMapping(G1, &Mem2);
60 EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
61
Owen Anderson55f1c092009-08-13 21:58:54 +000062 GlobalVariable *G2 =
63 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
Craig Topper66f09ad2014-06-08 22:29:17 +000064 EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G2))
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000065 << "The NULL return shouldn't depend on having called"
66 << " updateGlobalMapping(..., NULL)";
67 // Check that update...() can be called before add...().
68 Engine->updateGlobalMapping(G2, &Mem1);
69 EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G2));
70 EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1))
71 << "A second mapping shouldn't affect the first.";
72}
73
74TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
Owen Anderson55f1c092009-08-13 21:58:54 +000075 GlobalVariable *G1 =
76 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000077
78 int32_t Mem1 = 3;
79 Engine->addGlobalMapping(G1, &Mem1);
80 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
81 int32_t Mem2 = 4;
82 Engine->updateGlobalMapping(G1, &Mem2);
Craig Topper66f09ad2014-06-08 22:29:17 +000083 EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000084 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
85
Owen Anderson55f1c092009-08-13 21:58:54 +000086 GlobalVariable *G2 =
87 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000088 Engine->updateGlobalMapping(G2, &Mem1);
89 EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
90 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
Craig Topper66f09ad2014-06-08 22:29:17 +000091 Engine->updateGlobalMapping(G1, nullptr);
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000092 EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1))
93 << "Removing one mapping doesn't affect a different one.";
Craig Topper66f09ad2014-06-08 22:29:17 +000094 EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem2));
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000095 Engine->updateGlobalMapping(G2, &Mem2);
Craig Topper66f09ad2014-06-08 22:29:17 +000096 EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
Jeffrey Yasskin337b1242009-08-04 23:53:16 +000097 EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2))
98 << "Once a mapping is removed, we can point another GV at the"
99 << " now-free address.";
100}
101
Jeffrey Yasskin307c0532009-10-09 22:10:27 +0000102TEST_F(ExecutionEngineTest, ClearModuleMappings) {
103 GlobalVariable *G1 =
104 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
105
106 int32_t Mem1 = 3;
107 Engine->addGlobalMapping(G1, &Mem1);
108 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
109
110 Engine->clearGlobalMappingsFromModule(M);
111
Craig Topper66f09ad2014-06-08 22:29:17 +0000112 EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
Jeffrey Yasskin307c0532009-10-09 22:10:27 +0000113
114 GlobalVariable *G2 =
115 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
116 // After clearing the module mappings, we can assign a new GV to the
117 // same address.
118 Engine->addGlobalMapping(G2, &Mem1);
119 EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
120}
121
Jeffrey Yasskinf98e9812009-10-13 17:42:08 +0000122TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
123 GlobalVariable *G1 =
124 NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
125 int32_t Mem1 = 3;
126 Engine->addGlobalMapping(G1, &Mem1);
127 // Make sure the reverse mapping is enabled.
128 EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
129 // When the GV goes away, the ExecutionEngine should remove any
130 // mappings that refer to it.
131 G1->eraseFromParent();
Craig Topper66f09ad2014-06-08 22:29:17 +0000132 EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
Jeffrey Yasskinf98e9812009-10-13 17:42:08 +0000133}
134
Jeffrey Yasskin337b1242009-08-04 23:53:16 +0000135}