diff options
Diffstat (limited to 'unittests/ExecutionEngine')
-rw-r--r-- | unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp | 3 | ||||
-rw-r--r-- | unittests/ExecutionEngine/JIT/JITTest.cpp | 179 | ||||
-rw-r--r-- | unittests/ExecutionEngine/JIT/MultiJITTest.cpp | 8 | ||||
-rw-r--r-- | unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp | 169 | ||||
-rw-r--r-- | unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp | 6 | ||||
-rw-r--r-- | unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp | 5 | ||||
-rw-r--r-- | unittests/ExecutionEngine/MCJIT/MCJITTest.cpp | 23 | ||||
-rw-r--r-- | unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h | 20 | ||||
-rw-r--r-- | unittests/ExecutionEngine/MCJIT/MCJITTestBase.h | 13 |
9 files changed, 210 insertions, 216 deletions
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp index 6ba8bc4..87f4824 100644 --- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp @@ -74,6 +74,8 @@ class JITEventListenerTest : public testing::Test { const OwningPtr<ExecutionEngine> EE; }; +// Tests on SystemZ disabled as we're running the old JIT +#if !defined(__s390__) Function *buildFunction(Module *M) { Function *Result = Function::Create( TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()), @@ -224,6 +226,7 @@ TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) { EXPECT_EQ(1U, Listener.FreedEvents[0].Index); EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code); } +#endif class JITEnvironment : public testing::Environment { virtual void SetUp() { diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index 30dadc9..3b94d76 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -33,8 +33,27 @@ using namespace llvm; +// This variable is intentionally defined differently in the statically-compiled +// program from the IR input to the JIT to assert that the JIT doesn't use its +// definition. Note that this variable must be defined even on platforms where +// JIT tests are disabled as it is referenced from the .def file. +extern "C" int32_t JITTest_AvailableExternallyGlobal; +int32_t JITTest_AvailableExternallyGlobal LLVM_ATTRIBUTE_USED = 42; + +// This function is intentionally defined differently in the statically-compiled +// program from the IR input to the JIT to assert that the JIT doesn't use its +// definition. Note that this function must be defined even on platforms where +// JIT tests are disabled as it is referenced from the .def file. +extern "C" int32_t JITTest_AvailableExternallyFunction() LLVM_ATTRIBUTE_USED; +extern "C" int32_t JITTest_AvailableExternallyFunction() { + return 42; +} + namespace { +// Tests on ARM, PowerPC and SystemZ disabled as we're running the old jit +#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) + Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) { std::vector<Type*> params; FunctionType *FTy = FunctionType::get(G->getType()->getElementType(), @@ -124,7 +143,7 @@ public: unsigned SectionID) { return Base->allocateCodeSection(Size, Alignment, SectionID); } - virtual bool applyPermissions(std::string *ErrMsg) { return false; } + virtual bool finalizeMemory(std::string *ErrMsg) { return false; } virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { return Base->allocateSpace(Size, Alignment); } @@ -140,54 +159,6 @@ public: deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body)); Base->deallocateFunctionBody(Body); } - struct DeallocateExceptionTableCall { - DeallocateExceptionTableCall(const void *ET) : ET(ET) {} - const void *ET; - }; - std::vector<DeallocateExceptionTableCall> deallocateExceptionTableCalls; - virtual void deallocateExceptionTable(void *ET) { - deallocateExceptionTableCalls.push_back(DeallocateExceptionTableCall(ET)); - Base->deallocateExceptionTable(ET); - } - struct StartExceptionTableCall { - StartExceptionTableCall(uint8_t *Result, const Function *F, - uintptr_t ActualSize, uintptr_t ActualSizeResult) - : Result(Result), F(F), F_dump(DumpFunction(F)), - ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {} - uint8_t *Result; - const Function *F; - std::string F_dump; - uintptr_t ActualSize; - uintptr_t ActualSizeResult; - }; - std::vector<StartExceptionTableCall> startExceptionTableCalls; - virtual uint8_t *startExceptionTable(const Function *F, - uintptr_t &ActualSize) { - uintptr_t InitialActualSize = ActualSize; - uint8_t *Result = Base->startExceptionTable(F, ActualSize); - startExceptionTableCalls.push_back( - StartExceptionTableCall(Result, F, InitialActualSize, ActualSize)); - return Result; - } - struct EndExceptionTableCall { - EndExceptionTableCall(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) - : F(F), F_dump(DumpFunction(F)), - TableStart(TableStart), TableEnd(TableEnd), - FrameRegister(FrameRegister) {} - const Function *F; - std::string F_dump; - uint8_t *TableStart; - uint8_t *TableEnd; - uint8_t *FrameRegister; - }; - std::vector<EndExceptionTableCall> endExceptionTableCalls; - virtual void endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) { - endExceptionTableCalls.push_back( - EndExceptionTableCall(F, TableStart, TableEnd, FrameRegister)); - return Base->endExceptionTable(F, TableStart, TableEnd, FrameRegister); - } }; bool LoadAssemblyInto(Module *M, const char *assembly) { @@ -213,7 +184,6 @@ class JITTest : public testing::Test { RJMM->setPoisonMemory(true); std::string Error; TargetOptions Options; - Options.JITExceptionHandling = true; TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT) .setJITMemoryManager(RJMM) .setErrorStr(&Error) @@ -231,9 +201,6 @@ class JITTest : public testing::Test { OwningPtr<ExecutionEngine> TheJIT; }; -// Tests on ARM and PowerPC disabled as we're running the old jit -#if !defined(__arm__) && !defined(__powerpc__) - // Regression test for a bug. The JIT used to allocate globals inside the same // memory block used for the function, and when the function code was freed, // the global was left in the same place. This test allocates a function @@ -302,54 +269,10 @@ TEST(JIT, GlobalInFunction) { EXPECT_EQ(3, *GPtr); } -#endif // !defined(__arm__) && !defined(__powerpc__) - -// Regression test for a bug. The JITEmitter wasn't checking to verify that -// it hadn't run out of space while generating the DWARF exception information -// for an emitted function. - -class ExceptionMemoryManagerMock : public RecordingJITMemoryManager { - public: - virtual uint8_t *startExceptionTable(const Function *F, - uintptr_t &ActualSize) { - // force an insufficient size the first time through. - bool ChangeActualSize = false; - if (ActualSize == 0) - ChangeActualSize = true;; - uint8_t *result = - RecordingJITMemoryManager::startExceptionTable(F, ActualSize); - if (ChangeActualSize) - ActualSize = 1; - return result; - } -}; - -class JITExceptionMemoryTest : public JITTest { - protected: - virtual RecordingJITMemoryManager *createMemoryManager() { - return new ExceptionMemoryManagerMock; - } -}; - -TEST_F(JITExceptionMemoryTest, ExceptionTableOverflow) { - Function *F = Function::Create(TypeBuilder<void(void), false>::get(Context), - Function::ExternalLinkage, - "func1", M); - BasicBlock *Block = BasicBlock::Create(Context, "block", F); - IRBuilder<> Builder(Block); - Builder.CreateRetVoid(); - TheJIT->getPointerToFunction(F); - ASSERT_TRUE(RJMM->startExceptionTableCalls.size() == 2); - ASSERT_TRUE(RJMM->deallocateExceptionTableCalls.size() == 1); - ASSERT_TRUE(RJMM->endExceptionTableCalls.size() == 1); -} - int PlusOne(int arg) { return arg + 1; } -// ARM and PowerPC tests disabled pending fix for PR10783. -#if !defined(__arm__) && !defined(__powerpc__) TEST_F(JITTest, FarCallToKnownFunction) { // x86-64 can only make direct calls to functions within 32 bits of // the current PC. To call anything farther away, we have to load @@ -505,29 +428,7 @@ TEST_F(JITTest, ModuleDeletion) { } EXPECT_EQ(RJMM->startFunctionBodyCalls.size(), RJMM->deallocateFunctionBodyCalls.size()); - - SmallPtrSet<const void*, 2> ExceptionTablesDeallocated; - unsigned NumTablesDeallocated = 0; - for (unsigned i = 0, e = RJMM->deallocateExceptionTableCalls.size(); - i != e; ++i) { - ExceptionTablesDeallocated.insert( - RJMM->deallocateExceptionTableCalls[i].ET); - if (RJMM->deallocateExceptionTableCalls[i].ET != NULL) { - // If JITEmitDebugInfo is off, we'll "deallocate" NULL, which doesn't - // appear in startExceptionTableCalls. - NumTablesDeallocated++; - } - } - for (unsigned i = 0, e = RJMM->startExceptionTableCalls.size(); i != e; ++i) { - EXPECT_TRUE(ExceptionTablesDeallocated.count( - RJMM->startExceptionTableCalls[i].Result)) - << "Function's exception table leaked: \n" - << RJMM->startExceptionTableCalls[i].F_dump; - } - EXPECT_EQ(RJMM->startExceptionTableCalls.size(), - NumTablesDeallocated); } -#endif // !defined(__arm__) && !defined(__powerpc__) // ARM, MIPS and PPC still emit stubs for calls since the target may be // too far away to call directly. This #if can probably be removed when @@ -573,9 +474,6 @@ TEST_F(JITTest, NoStubs) { } #endif // !ARM && !PPC -// Tests on ARM and PowerPC disabled as we're running the old jit -#if !defined(__arm__) && !defined(__powerpc__) - TEST_F(JITTest, FunctionPointersOutliveTheirCreator) { TheJIT->DisableLazyCompilation(true); LoadAssembly("define i8()* @get_foo_addr() { " @@ -610,13 +508,9 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) { #endif } -#endif //!defined(__arm__) && !defined(__powerpc__) - -// Tests on ARM and PowerPC disabled as we're running the old jit -// In addition, ARM does not have an implementation -// of replaceMachineCodeForFunction(), so recompileAndRelinkFunction -// doesn't work. -#if !defined(__arm__) && !defined(__powerpc__) +// ARM does not have an implementation of replaceMachineCodeForFunction(), +// so recompileAndRelinkFunction doesn't work. +#if !defined(__arm__) TEST_F(JITTest, FunctionIsRecompiledAndRelinked) { Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context), GlobalValue::ExternalLinkage, "test", M); @@ -647,18 +541,7 @@ TEST_F(JITTest, FunctionIsRecompiledAndRelinked) { EXPECT_EQ(2, OrigFPtr()) << "The old pointer's target should now jump to the new version"; } -#endif // !defined(__arm__) && !defined(__powerpc__) - -} // anonymous namespace -// This variable is intentionally defined differently in the statically-compiled -// program from the IR input to the JIT to assert that the JIT doesn't use its -// definition. -extern "C" int32_t JITTest_AvailableExternallyGlobal; -int32_t JITTest_AvailableExternallyGlobal LLVM_ATTRIBUTE_USED = 42; -namespace { - -// Tests on ARM and PowerPC disabled as we're running the old jit -#if !defined(__arm__) && !defined(__powerpc__) +#endif // !defined(__arm__) TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { TheJIT->DisableLazyCompilation(true); @@ -676,19 +559,7 @@ TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) { EXPECT_EQ(42, loader()) << "func should return 42 from the external global," << " not 7 from the IR version."; } -#endif //!defined(__arm__) && !defined(__powerpc__) -} // anonymous namespace -// This function is intentionally defined differently in the statically-compiled -// program from the IR input to the JIT to assert that the JIT doesn't use its -// definition. -extern "C" int32_t JITTest_AvailableExternallyFunction() LLVM_ATTRIBUTE_USED; -extern "C" int32_t JITTest_AvailableExternallyFunction() { - return 42; -} -namespace { -// ARM and PowerPC tests disabled pending fix for PR10783. -#if !defined(__arm__) && !defined(__powerpc__) TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) { TheJIT->DisableLazyCompilation(true); LoadAssembly("define available_externally i32 " @@ -844,7 +715,7 @@ TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) { (intptr_t)TheJIT->getPointerToFunction(recur1IR)); EXPECT_EQ(3, recur1(4)); } -#endif // !defined(__arm__) && !defined(__powerpc__) +#endif // !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) // This code is copied from JITEventListenerTest, but it only runs once for all // the tests in this directory. Everything seems fine, but that's strange diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp index 5301467..4018cd5 100644 --- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp +++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp @@ -20,6 +20,9 @@ using namespace llvm; namespace { +// ARM, PowerPC and SystemZ tests disabled pending fix for PR10783. +#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) + bool LoadAssemblyInto(Module *M, const char *assembly) { SMDiagnostic Error; bool success = @@ -65,9 +68,6 @@ void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) { FooF2 = M2->getFunction("foo2"); } -// ARM and PowerPC tests disabled pending fix for PR10783. -#if !defined(__arm__) && !defined(__powerpc__) - TEST(MultiJitTest, EagerMode) { LLVMContext Context1; Module *M1 = 0; @@ -176,6 +176,6 @@ TEST(MultiJitTest, JitPool) { #endif EXPECT_TRUE(sa == fa); } -#endif // !defined(__arm__) && !defined(__powerpc__) +#endif // !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) } // anonymous namespace diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp index d8cf6c5..c434a7c 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp +++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp @@ -17,79 +17,176 @@ #include "llvm-c/ExecutionEngine.h" #include "llvm-c/Target.h" #include "llvm-c/Transforms/Scalar.h" +#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/Support/Host.h" #include "MCJITTestAPICommon.h" #include "gtest/gtest.h" using namespace llvm; +static bool didCallAllocateCodeSection; + +static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size, + unsigned alignment, + unsigned sectionID) { + didCallAllocateCodeSection = true; + return static_cast<SectionMemoryManager*>(object)->allocateCodeSection( + size, alignment, sectionID); +} + +static uint8_t *roundTripAllocateDataSection(void *object, uintptr_t size, + unsigned alignment, + unsigned sectionID, + LLVMBool isReadOnly) { + return static_cast<SectionMemoryManager*>(object)->allocateDataSection( + size, alignment, sectionID, isReadOnly); +} + +static LLVMBool roundTripFinalizeMemory(void *object, char **errMsg) { + std::string errMsgString; + bool result = + static_cast<SectionMemoryManager*>(object)->finalizeMemory(&errMsgString); + if (result) { + *errMsg = LLVMCreateMessage(errMsgString.c_str()); + return 1; + } + return 0; +} + +static void roundTripDestroy(void *object) { + delete static_cast<SectionMemoryManager*>(object); +} + class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon { protected: MCJITCAPITest() { // The architectures below are known to be compatible with MCJIT as they // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be // kept in sync. + SupportedArchs.push_back(Triple::aarch64); SupportedArchs.push_back(Triple::arm); SupportedArchs.push_back(Triple::mips); SupportedArchs.push_back(Triple::x86); SupportedArchs.push_back(Triple::x86_64); + // Some architectures have sub-architectures in which tests will fail, like + // ARM. These two vectors will define if they do have sub-archs (to avoid + // extra work for those who don't), and if so, if they are listed to work + HasSubArchs.push_back(Triple::arm); + SupportedSubArchs.push_back("armv6"); + SupportedSubArchs.push_back("armv7"); + // The operating systems below are known to be sufficiently incompatible // that they will fail the MCJIT C API tests. UnsupportedOSs.push_back(Triple::Cygwin); } -}; - -TEST_F(MCJITCAPITest, simple_function) { - SKIP_UNSUPPORTED_PLATFORM; - char *error = 0; + virtual void SetUp() { + didCallAllocateCodeSection = false; + Module = 0; + Function = 0; + Engine = 0; + Error = 0; + } - // Creates a function that returns 42, compiles it, and runs it. + virtual void TearDown() { + if (Engine) + LLVMDisposeExecutionEngine(Engine); + else if (Module) + LLVMDisposeModule(Module); + } - LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); + void buildSimpleFunction() { + Module = LLVMModuleCreateWithName("simple_module"); + + LLVMSetTarget(Module, HostTriple.c_str()); + + Function = LLVMAddFunction( + Module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0)); + LLVMSetFunctionCallConv(Function, LLVMCCallConv); + + LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry"); + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMPositionBuilderAtEnd(builder, entry); + LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0)); + + LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error); + LLVMDisposeMessage(Error); + + LLVMDisposeBuilder(builder); + } - LLVMValueRef function = LLVMAddFunction( - module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0)); - LLVMSetFunctionCallConv(function, LLVMCCallConv); + void buildMCJITOptions() { + LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options)); + Options.OptLevel = 2; + + // Just ensure that this field still exists. + Options.NoFramePointerElim = false; + } - LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry"); - LLVMBuilderRef builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(builder, entry); - LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0)); + void useRoundTripSectionMemoryManager() { + Options.MCJMM = LLVMCreateSimpleMCJITMemoryManager( + new SectionMemoryManager(), + roundTripAllocateCodeSection, + roundTripAllocateDataSection, + roundTripFinalizeMemory, + roundTripDestroy); + } - LLVMVerifyModule(module, LLVMAbortProcessAction, &error); - LLVMDisposeMessage(error); + void buildMCJITEngine() { + ASSERT_EQ( + 0, LLVMCreateMCJITCompilerForModule(&Engine, Module, &Options, + sizeof(Options), &Error)); + } - LLVMDisposeBuilder(builder); + void buildAndRunPasses() { + LLVMPassManagerRef pass = LLVMCreatePassManager(); + LLVMAddTargetData(LLVMGetExecutionEngineTargetData(Engine), pass); + LLVMAddConstantPropagationPass(pass); + LLVMAddInstructionCombiningPass(pass); + LLVMRunPassManager(pass, Module); + LLVMDisposePassManager(pass); + } - LLVMMCJITCompilerOptions options; - LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); - options.OptLevel = 2; + LLVMModuleRef Module; + LLVMValueRef Function; + LLVMMCJITCompilerOptions Options; + LLVMExecutionEngineRef Engine; + char *Error; +}; + +TEST_F(MCJITCAPITest, simple_function) { + SKIP_UNSUPPORTED_PLATFORM; - // Just ensure that this field still exists. - options.NoFramePointerElim = false; + buildSimpleFunction(); + buildMCJITOptions(); + buildMCJITEngine(); + buildAndRunPasses(); + + union { + void *raw; + int (*usable)(); + } functionPointer; + functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function); - LLVMExecutionEngineRef engine; - ASSERT_EQ( - 0, LLVMCreateMCJITCompilerForModule(&engine, module, &options, - sizeof(options), &error)); + EXPECT_EQ(42, functionPointer.usable()); +} + +TEST_F(MCJITCAPITest, custom_memory_manager) { + SKIP_UNSUPPORTED_PLATFORM; - LLVMPassManagerRef pass = LLVMCreatePassManager(); - LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); - LLVMAddConstantPropagationPass(pass); - LLVMAddInstructionCombiningPass(pass); - LLVMRunPassManager(pass, module); - LLVMDisposePassManager(pass); + buildSimpleFunction(); + buildMCJITOptions(); + useRoundTripSectionMemoryManager(); + buildMCJITEngine(); + buildAndRunPasses(); union { void *raw; int (*usable)(); } functionPointer; - functionPointer.raw = LLVMGetPointerToGlobal(engine, function); + functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function); EXPECT_EQ(42, functionPointer.usable()); - - LLVMDisposeExecutionEngine(engine); + EXPECT_TRUE(didCallAllocateCodeSection); } - diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp index ab09aca..9e0b353 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp +++ b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp @@ -46,7 +46,7 @@ TEST(MCJITMemoryManagerTest, BasicAllocations) { }
std::string Error;
- EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+ EXPECT_FALSE(MemMgr->finalizeMemory(&Error));
}
TEST(MCJITMemoryManagerTest, LargeAllocations) {
@@ -79,7 +79,7 @@ TEST(MCJITMemoryManagerTest, LargeAllocations) { }
std::string Error;
- EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+ EXPECT_FALSE(MemMgr->finalizeMemory(&Error));
}
TEST(MCJITMemoryManagerTest, ManyAllocations) {
@@ -114,7 +114,7 @@ TEST(MCJITMemoryManagerTest, ManyAllocations) { }
std::string Error;
- EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+ EXPECT_FALSE(MemMgr->finalizeMemory(&Error));
}
TEST(MCJITMemoryManagerTest, ManyVariedAllocations) {
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp index 0061e30..32fc292 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp +++ b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp @@ -98,14 +98,13 @@ protected: void compileAndRun(int ExpectedRC = OriginalRC) { // This function shouldn't be called until after SetUp. - ASSERT_TRUE(0 != TheJIT); + ASSERT_TRUE(TheJIT.isValid()); ASSERT_TRUE(0 != Main); + // We may be using a null cache, so ensure compilation is valid. TheJIT->finalizeObject(); void *vPtr = TheJIT->getPointerToFunction(Main); - static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); - EXPECT_TRUE(0 != vPtr) << "Unable to get pointer to main() from JIT"; diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp index e9cf904..43a8298 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp +++ b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp @@ -34,6 +34,7 @@ namespace { /* TEST_F(MCJITTest, empty_module) { createJIT(M.take()); + TheJIT->finalizeObject(); //EXPECT_NE(0, TheJIT->getObjectImage()) // << "Unable to generate executable loaded object image"; } @@ -46,8 +47,7 @@ TEST_F(MCJITTest, global_variable) { GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue); createJIT(M.take()); void *globalPtr = TheJIT->getPointerToGlobal(Global); - MM->applyPermissions(); - static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); + TheJIT->finalizeObject(); EXPECT_TRUE(0 != globalPtr) << "Unable to get pointer to global value from JIT"; @@ -61,8 +61,7 @@ TEST_F(MCJITTest, add_function) { Function *F = insertAddFunction(M.get()); createJIT(M.take()); void *addPtr = TheJIT->getPointerToFunction(F); - MM->applyPermissions(); - static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); + TheJIT->finalizeObject(); EXPECT_TRUE(0 != addPtr) << "Unable to get pointer to function from JIT"; @@ -79,8 +78,7 @@ TEST_F(MCJITTest, run_main) { Function *Main = insertMainFunction(M.get(), 6); createJIT(M.take()); void *vPtr = TheJIT->getPointerToFunction(Main); - MM->applyPermissions(); - static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); + TheJIT->finalizeObject(); EXPECT_TRUE(0 != vPtr) << "Unable to get pointer to main() from JIT"; @@ -102,8 +100,7 @@ TEST_F(MCJITTest, return_global) { createJIT(M.take()); void *rgvPtr = TheJIT->getPointerToFunction(ReturnGlobal); - MM->applyPermissions(); - static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); + TheJIT->finalizeObject(); EXPECT_TRUE(0 != rgvPtr); int32_t(*FuncPtr)(void) = (int32_t(*)(void))(intptr_t)rgvPtr; @@ -134,6 +131,7 @@ TEST_F(MCJITTest, increment_global) { createJIT(M.take()); void *gvPtr = TheJIT->getPointerToGlobal(GV); + TheJIT->finalizeObject(); EXPECT_EQ(initialNum, *(int32_t*)gvPtr); void *vPtr = TheJIT->getPointerToFunction(IncrementGlobal); @@ -150,6 +148,9 @@ TEST_F(MCJITTest, increment_global) { } */ +// PR16013: XFAIL this test on ARM, which currently can't handle multiple relocations. +#if !defined(__arm__) + TEST_F(MCJITTest, multiple_functions) { SKIP_UNSUPPORTED_PLATFORM; @@ -172,8 +173,7 @@ TEST_F(MCJITTest, multiple_functions) { createJIT(M.take()); void *vPtr = TheJIT->getPointerToFunction(Outer); - MM->applyPermissions(); - static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); + TheJIT->finalizeObject(); EXPECT_TRUE(0 != vPtr) << "Unable to get pointer to outer function from JIT"; @@ -182,6 +182,8 @@ TEST_F(MCJITTest, multiple_functions) { << "Incorrect result returned from function"; } +#endif /*!defined(__arm__)*/ + // FIXME: ExecutionEngine has no support empty modules /* TEST_F(MCJITTest, multiple_empty_modules) { @@ -219,6 +221,7 @@ TEST_F(MCJITTest, multiple_modules) { // get a function pointer in a module that was not used in EE construction void *vPtr = TheJIT->getPointerToFunction(Caller); + TheJIT->finalizeObject(); EXPECT_NE(0, vPtr) << "Unable to get pointer to caller function from JIT"; diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h index 8160a18..7b6e39f 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h +++ b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h @@ -49,11 +49,23 @@ protected: /// Returns true if the host architecture is known to support MCJIT bool ArchSupportsMCJIT() { Triple Host(HostTriple); + // If ARCH is not supported, bail if (std::find(SupportedArchs.begin(), SupportedArchs.end(), Host.getArch()) - == SupportedArchs.end()) { + == SupportedArchs.end()) return false; - } - return true; + + // If ARCH is supported and has no specific sub-arch support + if (std::find(HasSubArchs.begin(), HasSubArchs.end(), Host.getArch()) + == HasSubArchs.end()) + return true; + + // If ARCH has sub-arch support, find it + SmallVectorImpl<std::string>::const_iterator I = SupportedSubArchs.begin(); + for(; I != SupportedSubArchs.end(); ++I) + if (Host.getArchName().startswith(I->c_str())) + return true; + + return false; } /// Returns true if the host OS is known to support MCJIT @@ -68,6 +80,8 @@ protected: std::string HostTriple; SmallVector<Triple::ArchType, 4> SupportedArchs; + SmallVector<Triple::ArchType, 1> HasSubArchs; + SmallVector<std::string, 2> SupportedSubArchs; // We need to own the memory SmallVector<Triple::OSType, 4> UnsupportedOSs; }; diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h index b0e98a8..95a5c8b 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h +++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h @@ -44,11 +44,19 @@ protected: // The architectures below are known to be compatible with MCJIT as they // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be // kept in sync. + SupportedArchs.push_back(Triple::aarch64); SupportedArchs.push_back(Triple::arm); SupportedArchs.push_back(Triple::mips); SupportedArchs.push_back(Triple::x86); SupportedArchs.push_back(Triple::x86_64); + // Some architectures have sub-architectures in which tests will fail, like + // ARM. These two vectors will define if they do have sub-archs (to avoid + // extra work for those who don't), and if so, if they are listed to work + HasSubArchs.push_back(Triple::arm); + SupportedSubArchs.push_back("armv6"); + SupportedSubArchs.push_back("armv7"); + // The operating systems below are known to be incompatible with MCJIT as // they are copied from the test/ExecutionEngine/MCJIT/lit.local.cfg and // should be kept in sync. @@ -165,7 +173,7 @@ protected: std::string Error; TheJIT.reset(EB.setEngineKind(EngineKind::JIT) .setUseMCJIT(true) /* can this be folded into the EngineKind enum? */ - .setJITMemoryManager(MM) + .setMCJITMemoryManager(MM) .setErrorStr(&Error) .setOptLevel(CodeGenOpt::None) .setAllocateGVsWithCode(false) /*does this do anything?*/ @@ -185,10 +193,9 @@ protected: CodeModel::Model CodeModel; StringRef MArch; SmallVector<std::string, 1> MAttrs; - OwningPtr<TargetMachine> TM; OwningPtr<ExecutionEngine> TheJIT; IRBuilder<> Builder; - JITMemoryManager *MM; + RTDyldMemoryManager *MM; OwningPtr<Module> M; }; |