mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
5a4700cb8f
Re-appply r333147, reverted in r333152 due to a pre-existing bug. As D47308 has been merged in r333206, the OSX issue should now be resolved. In many cases JIT users will know in which module a symbol resides. Avoiding to search other modules can be more efficient. It also allows to handle duplicate symbol names between modules. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D44889 llvm-svn: 333215
214 lines
6.0 KiB
C++
214 lines
6.0 KiB
C++
//===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "OrcTestCommon.h"
|
|
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
|
#include "llvm-c/Core.h"
|
|
#include "llvm-c/OrcBindings.h"
|
|
#include "llvm-c/Target.h"
|
|
#include "llvm-c/TargetMachine.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
namespace llvm {
|
|
|
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
|
|
|
class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
|
|
protected:
|
|
std::unique_ptr<Module> createTestModule(const Triple &TT) {
|
|
ModuleBuilder MB(Context, TT.str(), "");
|
|
Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
|
|
Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
|
|
|
|
Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
|
|
IRBuilder<> B(&Main->back());
|
|
Value* Result = B.CreateCall(TestFunc);
|
|
B.CreateRet(Result);
|
|
|
|
return MB.takeModule();
|
|
}
|
|
|
|
std::unique_ptr<MemoryBuffer> createTestObject() {
|
|
orc::SimpleCompiler IRCompiler(*TM);
|
|
auto M = createTestModule(TM->getTargetTriple());
|
|
M->setDataLayout(TM->createDataLayout());
|
|
return IRCompiler(*M);
|
|
}
|
|
|
|
typedef int (*MainFnTy)();
|
|
|
|
static int myTestFuncImpl() {
|
|
return 42;
|
|
}
|
|
|
|
static char *testFuncName;
|
|
|
|
static uint64_t myResolver(const char *Name, void *Ctx) {
|
|
if (!strncmp(Name, testFuncName, 8))
|
|
return (uint64_t)&myTestFuncImpl;
|
|
return 0;
|
|
}
|
|
|
|
struct CompileContext {
|
|
CompileContext() : Compiled(false) { }
|
|
|
|
OrcCAPIExecutionTest* APIExecTest;
|
|
std::unique_ptr<Module> M;
|
|
LLVMOrcModuleHandle H;
|
|
bool Compiled;
|
|
};
|
|
|
|
static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
|
|
void *Ctx) {
|
|
CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
|
|
auto *ET = CCtx->APIExecTest;
|
|
CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
|
|
LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, wrap(CCtx->M.release()),
|
|
myResolver, nullptr);
|
|
CCtx->Compiled = true;
|
|
LLVMOrcTargetAddress MainAddr;
|
|
LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main");
|
|
LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
|
|
return MainAddr;
|
|
}
|
|
};
|
|
|
|
char *OrcCAPIExecutionTest::testFuncName = nullptr;
|
|
|
|
TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
|
|
if (!SupportsJIT)
|
|
return;
|
|
|
|
LLVMOrcJITStackRef JIT =
|
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
|
|
|
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
|
|
|
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
|
|
|
LLVMOrcModuleHandle H;
|
|
LLVMOrcAddEagerlyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr);
|
|
|
|
// get symbol address searching the entire stack
|
|
{
|
|
LLVMOrcTargetAddress MainAddr;
|
|
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
|
|
MainFnTy MainFn = (MainFnTy)MainAddr;
|
|
int Result = MainFn();
|
|
EXPECT_EQ(Result, 42)
|
|
<< "Eagerly JIT'd code did not return expected result";
|
|
}
|
|
|
|
// and then just searching a single handle
|
|
{
|
|
LLVMOrcTargetAddress MainAddr;
|
|
LLVMOrcGetSymbolAddressIn(JIT, &MainAddr, H, "main");
|
|
MainFnTy MainFn = (MainFnTy)MainAddr;
|
|
int Result = MainFn();
|
|
EXPECT_EQ(Result, 42)
|
|
<< "Eagerly JIT'd code did not return expected result";
|
|
}
|
|
|
|
LLVMOrcRemoveModule(JIT, H);
|
|
|
|
LLVMOrcDisposeMangledSymbol(testFuncName);
|
|
LLVMOrcDisposeInstance(JIT);
|
|
}
|
|
|
|
TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
|
|
if (!SupportsIndirection)
|
|
return;
|
|
|
|
LLVMOrcJITStackRef JIT =
|
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
|
|
|
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
|
|
|
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
|
|
|
LLVMOrcModuleHandle H;
|
|
LLVMOrcAddLazilyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr);
|
|
LLVMOrcTargetAddress MainAddr;
|
|
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
|
|
MainFnTy MainFn = (MainFnTy)MainAddr;
|
|
int Result = MainFn();
|
|
EXPECT_EQ(Result, 42)
|
|
<< "Lazily JIT'd code did not return expected result";
|
|
|
|
LLVMOrcRemoveModule(JIT, H);
|
|
|
|
LLVMOrcDisposeMangledSymbol(testFuncName);
|
|
LLVMOrcDisposeInstance(JIT);
|
|
}
|
|
|
|
TEST_F(OrcCAPIExecutionTest, TestAddObjectFile) {
|
|
if (!SupportsJIT)
|
|
return;
|
|
|
|
auto ObjBuffer = createTestObject();
|
|
|
|
LLVMOrcJITStackRef JIT =
|
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
|
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
|
|
|
LLVMOrcModuleHandle H;
|
|
LLVMOrcAddObjectFile(JIT, &H, wrap(ObjBuffer.release()), myResolver, nullptr);
|
|
LLVMOrcTargetAddress MainAddr;
|
|
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
|
|
MainFnTy MainFn = (MainFnTy)MainAddr;
|
|
int Result = MainFn();
|
|
EXPECT_EQ(Result, 42)
|
|
<< "Lazily JIT'd code did not return expected result";
|
|
|
|
LLVMOrcRemoveModule(JIT, H);
|
|
|
|
LLVMOrcDisposeMangledSymbol(testFuncName);
|
|
LLVMOrcDisposeInstance(JIT);
|
|
}
|
|
|
|
TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
|
|
if (!SupportsIndirection)
|
|
return;
|
|
|
|
LLVMOrcJITStackRef JIT =
|
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
|
|
|
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
|
|
|
CompileContext C;
|
|
C.APIExecTest = this;
|
|
LLVMOrcTargetAddress CCAddr;
|
|
LLVMOrcCreateLazyCompileCallback(JIT, &CCAddr, myCompileCallback, &C);
|
|
LLVMOrcCreateIndirectStub(JIT, "foo", CCAddr);
|
|
LLVMOrcTargetAddress MainAddr;
|
|
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "foo");
|
|
MainFnTy FooFn = (MainFnTy)MainAddr;
|
|
int Result = FooFn();
|
|
EXPECT_TRUE(C.Compiled)
|
|
<< "Function wasn't lazily compiled";
|
|
EXPECT_EQ(Result, 42)
|
|
<< "Direct-callback JIT'd code did not return expected result";
|
|
|
|
C.Compiled = false;
|
|
FooFn();
|
|
EXPECT_FALSE(C.Compiled)
|
|
<< "Direct-callback JIT'd code was JIT'd twice";
|
|
|
|
LLVMOrcRemoveModule(JIT, C.H);
|
|
|
|
LLVMOrcDisposeMangledSymbol(testFuncName);
|
|
LLVMOrcDisposeInstance(JIT);
|
|
}
|
|
|
|
} // namespace llvm
|