diff options
author | Lang Hames <lhames@gmail.com> | 2015-07-10 22:56:47 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2015-07-10 22:56:47 +0000 |
commit | 11e086d275e2c246bd682a244361aa50a5f798f1 (patch) | |
tree | 752138d3f494012df7b8c457fd1c047dda86adb5 /llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp | |
parent | e463e470f8af0b854f07c33bf22882e6599a1779 (diff) | |
download | bcm5719-llvm-11e086d275e2c246bd682a244361aa50a5f798f1.tar.gz bcm5719-llvm-11e086d275e2c246bd682a244361aa50a5f798f1.zip |
[ExecutionEngine] Use std::function rather than a function pointer for the
LazyFunctionCreator.
Patch by Pierre-Andre Saulais. Thanks Pierre!
llvm-svn: 241962
Diffstat (limited to 'llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp')
-rw-r--r-- | llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp index f65ec96d944..7b9cb6cd57e 100644 --- a/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp +++ b/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp @@ -199,4 +199,69 @@ TEST_F(MCJITTest, multiple_decl_lookups) { EXPECT_EQ(A, B) << "Repeat calls to getPointerToFunction fail."; } +typedef void * (*FunctionHandlerPtr)(const std::string &str); + +TEST_F(MCJITTest, lazy_function_creator_pointer) { + SKIP_UNSUPPORTED_PLATFORM; + + Function *Foo = insertExternalReferenceToFunction<int32_t(void)>(M.get(), + "\1Foo"); + Function *Parent = startFunction<int32_t(void)>(M.get(), "Parent"); + CallInst *Call = Builder.CreateCall(Foo, {}); + Builder.CreateRet(Call); + + createJIT(std::move(M)); + + // Set up the lazy function creator that records the name of the last + // unresolved external function found in the module. Using a function pointer + // prevents us from capturing local variables, which is why this is static. + static std::string UnresolvedExternal; + FunctionHandlerPtr UnresolvedHandler = [] (const std::string &str) { + UnresolvedExternal = str; + return (void *)(uintptr_t)-1; + }; + TheJIT->InstallLazyFunctionCreator(UnresolvedHandler); + + // JIT the module. + TheJIT->finalizeObject(); + + // Verify that our handler was called. + EXPECT_EQ(UnresolvedExternal, "Foo"); +} + +TEST_F(MCJITTest, lazy_function_creator_lambda) { + SKIP_UNSUPPORTED_PLATFORM; + + Function *Foo1 = insertExternalReferenceToFunction<int32_t(void)>(M.get(), + "\1Foo1"); + Function *Foo2 = insertExternalReferenceToFunction<int32_t(void)>(M.get(), + "\1Foo2"); + Function *Parent = startFunction<int32_t(void)>(M.get(), "Parent"); + CallInst *Call1 = Builder.CreateCall(Foo1, {}); + CallInst *Call2 = Builder.CreateCall(Foo2, {}); + Value *Result = Builder.CreateAdd(Call1, Call2); + Builder.CreateRet(Result); + + createJIT(std::move(M)); + + // Set up the lazy function creator that records the name of unresolved + // external functions in the module. + std::vector<std::string> UnresolvedExternals; + auto UnresolvedHandler = [&UnresolvedExternals] (const std::string &str) { + llvm:dbgs() << "str is '" << str << "'\n"; + UnresolvedExternals.push_back(str); + return (void *)(uintptr_t)-1; + }; + TheJIT->InstallLazyFunctionCreator(UnresolvedHandler); + + // JIT the module. + TheJIT->finalizeObject(); + + // Verify that our handler was called for each unresolved function. + auto I = UnresolvedExternals.begin(), E = UnresolvedExternals.end(); + EXPECT_EQ(UnresolvedExternals.size(), 2); + EXPECT_FALSE(std::find(I, E, "Foo1") == E); + EXPECT_FALSE(std::find(I, E, "Foo2") == E); +} + } |