Home | History | Annotate | Download | only in ExecutionEngine
      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 
     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"
     17 
     18 using namespace llvm;
     19 
     20 namespace {
     21 
     22 class ExecutionEngineTest : public testing::Test {
     23 protected:
     24   ExecutionEngineTest()
     25     : M(new Module("<main>", getGlobalContext())),
     26       Engine(EngineBuilder(M).create()) {
     27   }
     28 
     29   virtual void SetUp() {
     30     ASSERT_TRUE(Engine.get() != NULL);
     31   }
     32 
     33   GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) {
     34     return new GlobalVariable(*M, T, false,  // Not constant.
     35                               GlobalValue::ExternalLinkage, NULL, Name);
     36   }
     37 
     38   Module *const M;
     39   const OwningPtr<ExecutionEngine> Engine;
     40 };
     41 
     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));
     55 
     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.";
     66 }
     67 
     68 TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
     69   GlobalVariable *G1 =
     70       NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
     71 
     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));
     79 
     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.";
     94 }
     95 
     96 TEST_F(ExecutionEngineTest, ClearModuleMappings) {
     97   GlobalVariable *G1 =
     98       NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
     99 
    100   int32_t Mem1 = 3;
    101   Engine->addGlobalMapping(G1, &Mem1);
    102   EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
    103 
    104   Engine->clearGlobalMappingsFromModule(M);
    105 
    106   EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
    107 
    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));
    114 }
    115 
    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));
    127 }
    128 
    129 }
    130