ExecutionEngineTest.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. //===----------------------------------------------------------------------===//
  9. #include "llvm/ExecutionEngine/Interpreter.h"
  10. #include "llvm/IR/DerivedTypes.h"
  11. #include "llvm/IR/GlobalVariable.h"
  12. #include "llvm/IR/LLVMContext.h"
  13. #include "llvm/IR/Module.h"
  14. #include "gtest/gtest.h"
  15. using namespace llvm;
  16. namespace {
  17. class ExecutionEngineTest : public testing::Test {
  18. protected:
  19. ExecutionEngineTest() {
  20. auto Owner = make_unique<Module>("<main>", getGlobalContext());
  21. M = Owner.get();
  22. Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create());
  23. }
  24. virtual void SetUp() {
  25. ASSERT_TRUE(Engine.get() != nullptr) << "EngineBuilder returned error: '"
  26. << Error << "'";
  27. }
  28. GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) {
  29. return new GlobalVariable(*M, T, false, // Not constant.
  30. GlobalValue::ExternalLinkage, nullptr, Name);
  31. }
  32. std::string Error;
  33. Module *M; // Owned by ExecutionEngine.
  34. std::unique_ptr<ExecutionEngine> Engine;
  35. };
  36. TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
  37. GlobalVariable *G1 =
  38. NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
  39. int32_t Mem1 = 3;
  40. Engine->addGlobalMapping(G1, &Mem1);
  41. EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1));
  42. int32_t Mem2 = 4;
  43. Engine->updateGlobalMapping(G1, &Mem2);
  44. EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
  45. Engine->updateGlobalMapping(G1, nullptr);
  46. EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G1));
  47. Engine->updateGlobalMapping(G1, &Mem2);
  48. EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
  49. GlobalVariable *G2 =
  50. NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
  51. EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G2))
  52. << "The NULL return shouldn't depend on having called"
  53. << " updateGlobalMapping(..., NULL)";
  54. // Check that update...() can be called before add...().
  55. Engine->updateGlobalMapping(G2, &Mem1);
  56. EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G2));
  57. EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1))
  58. << "A second mapping shouldn't affect the first.";
  59. }
  60. TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
  61. GlobalVariable *G1 =
  62. NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
  63. int32_t Mem1 = 3;
  64. Engine->addGlobalMapping(G1, &Mem1);
  65. EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
  66. int32_t Mem2 = 4;
  67. Engine->updateGlobalMapping(G1, &Mem2);
  68. EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
  69. EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
  70. GlobalVariable *G2 =
  71. NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
  72. Engine->updateGlobalMapping(G2, &Mem1);
  73. EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
  74. EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
  75. Engine->updateGlobalMapping(G1, nullptr);
  76. EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1))
  77. << "Removing one mapping doesn't affect a different one.";
  78. EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem2));
  79. Engine->updateGlobalMapping(G2, &Mem2);
  80. EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
  81. EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2))
  82. << "Once a mapping is removed, we can point another GV at the"
  83. << " now-free address.";
  84. }
  85. TEST_F(ExecutionEngineTest, ClearModuleMappings) {
  86. GlobalVariable *G1 =
  87. NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
  88. int32_t Mem1 = 3;
  89. Engine->addGlobalMapping(G1, &Mem1);
  90. EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
  91. Engine->clearGlobalMappingsFromModule(M);
  92. EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
  93. GlobalVariable *G2 =
  94. NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
  95. // After clearing the module mappings, we can assign a new GV to the
  96. // same address.
  97. Engine->addGlobalMapping(G2, &Mem1);
  98. EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
  99. }
  100. TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
  101. GlobalVariable *G1 =
  102. NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
  103. int32_t Mem1 = 3;
  104. Engine->addGlobalMapping(G1, &Mem1);
  105. // Make sure the reverse mapping is enabled.
  106. EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
  107. // When the GV goes away, the ExecutionEngine should remove any
  108. // mappings that refer to it.
  109. G1->eraseFromParent();
  110. EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
  111. }
  112. }