mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-19 03:24:09 +00:00
Make it explicit that ExecutionEngine takes ownership of the modules.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215967 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -125,13 +125,13 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
//Read the BrainF program
|
//Read the BrainF program
|
||||||
BrainF bf;
|
BrainF bf;
|
||||||
Module *mod = bf.parse(in, 65536, cf, Context); //64 KiB
|
std::unique_ptr<Module> Mod(bf.parse(in, 65536, cf, Context)); // 64 KiB
|
||||||
if (in != &std::cin)
|
if (in != &std::cin)
|
||||||
delete in;
|
delete in;
|
||||||
addMainFunction(mod);
|
addMainFunction(Mod.get());
|
||||||
|
|
||||||
//Verify generated code
|
//Verify generated code
|
||||||
if (verifyModule(*mod)) {
|
if (verifyModule(*Mod)) {
|
||||||
errs() << "Error: module failed verification. This shouldn't happen.\n";
|
errs() << "Error: module failed verification. This shouldn't happen.\n";
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@ -141,18 +141,18 @@ int main(int argc, char **argv) {
|
|||||||
InitializeNativeTarget();
|
InitializeNativeTarget();
|
||||||
|
|
||||||
outs() << "------- Running JIT -------\n";
|
outs() << "------- Running JIT -------\n";
|
||||||
ExecutionEngine *ee = EngineBuilder(mod).create();
|
Module &M = *Mod;
|
||||||
|
ExecutionEngine *ee = EngineBuilder(std::move(Mod)).create();
|
||||||
std::vector<GenericValue> args;
|
std::vector<GenericValue> args;
|
||||||
Function *brainf_func = mod->getFunction("brainf");
|
Function *brainf_func = M.getFunction("brainf");
|
||||||
GenericValue gv = ee->runFunction(brainf_func, args);
|
GenericValue gv = ee->runFunction(brainf_func, args);
|
||||||
} else {
|
} else {
|
||||||
WriteBitcodeToFile(mod, *out);
|
WriteBitcodeToFile(Mod.get(), *out);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clean up
|
//Clean up
|
||||||
if (out != &outs())
|
if (out != &outs())
|
||||||
delete out;
|
delete out;
|
||||||
delete mod;
|
|
||||||
|
|
||||||
llvm_shutdown();
|
llvm_shutdown();
|
||||||
|
|
||||||
|
@ -1957,12 +1957,14 @@ int main(int argc, char *argv[]) {
|
|||||||
llvm::IRBuilder<> theBuilder(context);
|
llvm::IRBuilder<> theBuilder(context);
|
||||||
|
|
||||||
// Make the module, which holds all the code.
|
// Make the module, which holds all the code.
|
||||||
llvm::Module *module = new llvm::Module("my cool jit", context);
|
std::unique_ptr<llvm::Module> Owner =
|
||||||
|
llvm::make_unique<llvm::Module>("my cool jit", context);
|
||||||
|
llvm::Module *module = Owner.get();
|
||||||
|
|
||||||
llvm::RTDyldMemoryManager *MemMgr = new llvm::SectionMemoryManager();
|
llvm::RTDyldMemoryManager *MemMgr = new llvm::SectionMemoryManager();
|
||||||
|
|
||||||
// Build engine with JIT
|
// Build engine with JIT
|
||||||
llvm::EngineBuilder factory(module);
|
llvm::EngineBuilder factory(std::move(Owner));
|
||||||
factory.setEngineKind(llvm::EngineKind::JIT);
|
factory.setEngineKind(llvm::EngineKind::JIT);
|
||||||
factory.setAllocateGVsWithCode(false);
|
factory.setAllocateGVsWithCode(false);
|
||||||
factory.setTargetOptions(Opts);
|
factory.setTargetOptions(Opts);
|
||||||
|
@ -96,15 +96,16 @@ int main(int argc, char **argv) {
|
|||||||
LLVMContext Context;
|
LLVMContext Context;
|
||||||
|
|
||||||
// Create some module to put our function into it.
|
// Create some module to put our function into it.
|
||||||
std::unique_ptr<Module> M(new Module("test", Context));
|
std::unique_ptr<Module> Owner(new Module("test", Context));
|
||||||
|
Module *M = Owner.get();
|
||||||
|
|
||||||
// We are about to create the "fib" function:
|
// We are about to create the "fib" function:
|
||||||
Function *FibF = CreateFibFunction(M.get(), Context);
|
Function *FibF = CreateFibFunction(M, Context);
|
||||||
|
|
||||||
// Now we going to create JIT
|
// Now we going to create JIT
|
||||||
std::string errStr;
|
std::string errStr;
|
||||||
ExecutionEngine *EE =
|
ExecutionEngine *EE =
|
||||||
EngineBuilder(M.get())
|
EngineBuilder(std::move(Owner))
|
||||||
.setErrorStr(&errStr)
|
.setErrorStr(&errStr)
|
||||||
.setEngineKind(EngineKind::JIT)
|
.setEngineKind(EngineKind::JIT)
|
||||||
.create();
|
.create();
|
||||||
|
@ -56,7 +56,8 @@ int main() {
|
|||||||
LLVMContext Context;
|
LLVMContext Context;
|
||||||
|
|
||||||
// Create some module to put our function into it.
|
// Create some module to put our function into it.
|
||||||
Module *M = new Module("test", Context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("test", Context);
|
||||||
|
Module *M = Owner.get();
|
||||||
|
|
||||||
// Create the add1 function entry and insert this entry into module M. The
|
// Create the add1 function entry and insert this entry into module M. The
|
||||||
// function will have a return type of "int" and take an argument of "int".
|
// function will have a return type of "int" and take an argument of "int".
|
||||||
@ -114,7 +115,7 @@ int main() {
|
|||||||
builder.CreateRet(Add1CallRes);
|
builder.CreateRet(Add1CallRes);
|
||||||
|
|
||||||
// Now we create the JIT.
|
// Now we create the JIT.
|
||||||
ExecutionEngine* EE = EngineBuilder(M).create();
|
ExecutionEngine* EE = EngineBuilder(std::move(Owner)).create();
|
||||||
|
|
||||||
outs() << "We just constructed this LLVM module:\n\n" << *M;
|
outs() << "We just constructed this LLVM module:\n\n" << *M;
|
||||||
outs() << "\n\nRunning foo: ";
|
outs() << "\n\nRunning foo: ";
|
||||||
|
@ -572,11 +572,13 @@ int main() {
|
|||||||
getNextToken();
|
getNextToken();
|
||||||
|
|
||||||
// Make the module, which holds all the code.
|
// Make the module, which holds all the code.
|
||||||
TheModule = new Module("my cool jit", Context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context);
|
||||||
|
TheModule = Owner.get();
|
||||||
|
|
||||||
// Create the JIT. This takes ownership of the module.
|
// Create the JIT. This takes ownership of the module.
|
||||||
std::string ErrStr;
|
std::string ErrStr;
|
||||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
TheExecutionEngine =
|
||||||
|
EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
|
||||||
if (!TheExecutionEngine) {
|
if (!TheExecutionEngine) {
|
||||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -817,11 +817,13 @@ int main() {
|
|||||||
getNextToken();
|
getNextToken();
|
||||||
|
|
||||||
// Make the module, which holds all the code.
|
// Make the module, which holds all the code.
|
||||||
TheModule = new Module("my cool jit", Context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context);
|
||||||
|
TheModule = Owner.get();
|
||||||
|
|
||||||
// Create the JIT. This takes ownership of the module.
|
// Create the JIT. This takes ownership of the module.
|
||||||
std::string ErrStr;
|
std::string ErrStr;
|
||||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
TheExecutionEngine =
|
||||||
|
EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
|
||||||
if (!TheExecutionEngine) {
|
if (!TheExecutionEngine) {
|
||||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -935,11 +935,13 @@ int main() {
|
|||||||
getNextToken();
|
getNextToken();
|
||||||
|
|
||||||
// Make the module, which holds all the code.
|
// Make the module, which holds all the code.
|
||||||
TheModule = new Module("my cool jit", Context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context);
|
||||||
|
TheModule = Owner.get();
|
||||||
|
|
||||||
// Create the JIT. This takes ownership of the module.
|
// Create the JIT. This takes ownership of the module.
|
||||||
std::string ErrStr;
|
std::string ErrStr;
|
||||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
TheExecutionEngine =
|
||||||
|
EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
|
||||||
if (!TheExecutionEngine) {
|
if (!TheExecutionEngine) {
|
||||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -1099,11 +1099,13 @@ int main() {
|
|||||||
getNextToken();
|
getNextToken();
|
||||||
|
|
||||||
// Make the module, which holds all the code.
|
// Make the module, which holds all the code.
|
||||||
TheModule = new Module("my cool jit", Context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context);
|
||||||
|
TheModule = Owner.get();
|
||||||
|
|
||||||
// Create the JIT. This takes ownership of the module.
|
// Create the JIT. This takes ownership of the module.
|
||||||
std::string ErrStr;
|
std::string ErrStr;
|
||||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
TheExecutionEngine =
|
||||||
|
EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
|
||||||
if (!TheExecutionEngine) {
|
if (!TheExecutionEngine) {
|
||||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -243,13 +243,14 @@ int main() {
|
|||||||
LLVMContext Context;
|
LLVMContext Context;
|
||||||
|
|
||||||
// Create some module to put our function into it.
|
// Create some module to put our function into it.
|
||||||
Module *M = new Module("test", Context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("test", Context);
|
||||||
|
Module *M = Owner.get();
|
||||||
|
|
||||||
Function* add1F = createAdd1( M );
|
Function* add1F = createAdd1( M );
|
||||||
Function* fibF = CreateFibFunction( M );
|
Function* fibF = CreateFibFunction( M );
|
||||||
|
|
||||||
// Now we create the JIT.
|
// Now we create the JIT.
|
||||||
ExecutionEngine* EE = EngineBuilder(M).create();
|
ExecutionEngine* EE = EngineBuilder(std::move(Owner)).create();
|
||||||
|
|
||||||
//~ std::cout << "We just constructed this LLVM module:\n\n" << *M;
|
//~ std::cout << "We just constructed this LLVM module:\n\n" << *M;
|
||||||
//~ std::cout << "\n\nRunning foo: " << std::flush;
|
//~ std::cout << "\n\nRunning foo: " << std::flush;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "llvm-c/ExecutionEngine.h"
|
#include "llvm-c/ExecutionEngine.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/ValueHandle.h"
|
#include "llvm/IR/ValueHandle.h"
|
||||||
#include "llvm/IR/ValueMap.h"
|
#include "llvm/IR/ValueMap.h"
|
||||||
#include "llvm/MC/MCCodeGenInfo.h"
|
#include "llvm/MC/MCCodeGenInfo.h"
|
||||||
@ -41,7 +42,6 @@ class GlobalValue;
|
|||||||
class JITEventListener;
|
class JITEventListener;
|
||||||
class JITMemoryManager;
|
class JITMemoryManager;
|
||||||
class MachineCodeInfo;
|
class MachineCodeInfo;
|
||||||
class Module;
|
|
||||||
class MutexGuard;
|
class MutexGuard;
|
||||||
class ObjectCache;
|
class ObjectCache;
|
||||||
class RTDyldMemoryManager;
|
class RTDyldMemoryManager;
|
||||||
@ -131,7 +131,7 @@ class ExecutionEngine {
|
|||||||
protected:
|
protected:
|
||||||
/// The list of Modules that we are JIT'ing from. We use a SmallVector to
|
/// The list of Modules that we are JIT'ing from. We use a SmallVector to
|
||||||
/// optimize for the case where there is only one module.
|
/// optimize for the case where there is only one module.
|
||||||
SmallVector<Module*, 1> Modules;
|
SmallVector<std::unique_ptr<Module>, 1> Modules;
|
||||||
|
|
||||||
void setDataLayout(const DataLayout *Val) { DL = Val; }
|
void setDataLayout(const DataLayout *Val) { DL = Val; }
|
||||||
|
|
||||||
@ -142,17 +142,18 @@ protected:
|
|||||||
// libraries, the execution engine implementations set these functions to ctor
|
// libraries, the execution engine implementations set these functions to ctor
|
||||||
// pointers at startup time if they are linked in.
|
// pointers at startup time if they are linked in.
|
||||||
static ExecutionEngine *(*JITCtor)(
|
static ExecutionEngine *(*JITCtor)(
|
||||||
Module *M,
|
std::unique_ptr<Module> M,
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
JITMemoryManager *JMM,
|
JITMemoryManager *JMM,
|
||||||
bool GVsWithCode,
|
bool GVsWithCode,
|
||||||
TargetMachine *TM);
|
TargetMachine *TM);
|
||||||
static ExecutionEngine *(*MCJITCtor)(
|
static ExecutionEngine *(*MCJITCtor)(
|
||||||
Module *M,
|
std::unique_ptr<Module> M,
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
RTDyldMemoryManager *MCJMM,
|
RTDyldMemoryManager *MCJMM,
|
||||||
TargetMachine *TM);
|
TargetMachine *TM);
|
||||||
static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr);
|
static ExecutionEngine *(*InterpCtor)(std::unique_ptr<Module> M,
|
||||||
|
std::string *ErrorStr);
|
||||||
|
|
||||||
/// LazyFunctionCreator - If an unknown function is needed, this function
|
/// LazyFunctionCreator - If an unknown function is needed, this function
|
||||||
/// pointer is invoked to create it. If this returns null, the JIT will
|
/// pointer is invoked to create it. If this returns null, the JIT will
|
||||||
@ -171,11 +172,9 @@ public:
|
|||||||
|
|
||||||
virtual ~ExecutionEngine();
|
virtual ~ExecutionEngine();
|
||||||
|
|
||||||
/// addModule - Add a Module to the list of modules that we can JIT from.
|
/// Add a Module to the list of modules that we can JIT from.
|
||||||
/// Note that this takes ownership of the Module: when the ExecutionEngine is
|
virtual void addModule(std::unique_ptr<Module> M) {
|
||||||
/// destroyed, it destroys the Module as well.
|
Modules.push_back(std::move(M));
|
||||||
virtual void addModule(Module *M) {
|
|
||||||
Modules.push_back(M);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// addObjectFile - Add an ObjectFile to the execution engine.
|
/// addObjectFile - Add an ObjectFile to the execution engine.
|
||||||
@ -274,11 +273,11 @@ public:
|
|||||||
/// \param isDtors - Run the destructors instead of constructors.
|
/// \param isDtors - Run the destructors instead of constructors.
|
||||||
virtual void runStaticConstructorsDestructors(bool isDtors);
|
virtual void runStaticConstructorsDestructors(bool isDtors);
|
||||||
|
|
||||||
/// runStaticConstructorsDestructors - This method is used to execute all of
|
/// This method is used to execute all of the static constructors or
|
||||||
/// the static constructors or destructors for a particular module.
|
/// destructors for a particular module.
|
||||||
///
|
///
|
||||||
/// \param isDtors - Run the destructors instead of constructors.
|
/// \param isDtors - Run the destructors instead of constructors.
|
||||||
void runStaticConstructorsDestructors(Module *module, bool isDtors);
|
void runStaticConstructorsDestructors(Module &module, bool isDtors);
|
||||||
|
|
||||||
|
|
||||||
/// runFunctionAsMain - This is a helper function which wraps runFunction to
|
/// runFunctionAsMain - This is a helper function which wraps runFunction to
|
||||||
@ -506,7 +505,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ExecutionEngine(Module *M);
|
explicit ExecutionEngine(std::unique_ptr<Module> M);
|
||||||
|
|
||||||
void emitGlobals();
|
void emitGlobals();
|
||||||
|
|
||||||
@ -526,12 +525,12 @@ namespace EngineKind {
|
|||||||
const static Kind Either = (Kind)(JIT | Interpreter);
|
const static Kind Either = (Kind)(JIT | Interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EngineBuilder - Builder class for ExecutionEngines. Use this by
|
/// Builder class for ExecutionEngines. Use this by stack-allocating a builder,
|
||||||
/// stack-allocating a builder, chaining the various set* methods, and
|
/// chaining the various set* methods, and terminating it with a .create()
|
||||||
/// terminating it with a .create() call.
|
/// call.
|
||||||
class EngineBuilder {
|
class EngineBuilder {
|
||||||
private:
|
private:
|
||||||
Module *M;
|
std::unique_ptr<Module> M;
|
||||||
EngineKind::Kind WhichEngine;
|
EngineKind::Kind WhichEngine;
|
||||||
std::string *ErrorStr;
|
std::string *ErrorStr;
|
||||||
CodeGenOpt::Level OptLevel;
|
CodeGenOpt::Level OptLevel;
|
||||||
@ -551,9 +550,8 @@ private:
|
|||||||
void InitEngine();
|
void InitEngine();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// EngineBuilder - Constructor for EngineBuilder. If create() is called and
|
/// Constructor for EngineBuilder.
|
||||||
/// is successful, the created engine takes ownership of the module.
|
EngineBuilder(std::unique_ptr<Module> M) : M(std::move(M)) {
|
||||||
EngineBuilder(Module *m) : M(m) {
|
|
||||||
InitEngine();
|
InitEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,20 +49,20 @@ void ObjectBuffer::anchor() {}
|
|||||||
void ObjectBufferStream::anchor() {}
|
void ObjectBufferStream::anchor() {}
|
||||||
|
|
||||||
ExecutionEngine *(*ExecutionEngine::JITCtor)(
|
ExecutionEngine *(*ExecutionEngine::JITCtor)(
|
||||||
Module *M,
|
std::unique_ptr<Module> M,
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
JITMemoryManager *JMM,
|
JITMemoryManager *JMM,
|
||||||
bool GVsWithCode,
|
bool GVsWithCode,
|
||||||
TargetMachine *TM) = nullptr;
|
TargetMachine *TM) = nullptr;
|
||||||
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
|
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
|
||||||
Module *M,
|
std::unique_ptr<Module >M,
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
RTDyldMemoryManager *MCJMM,
|
RTDyldMemoryManager *MCJMM,
|
||||||
TargetMachine *TM) = nullptr;
|
TargetMachine *TM) = nullptr;
|
||||||
ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
|
ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
|
||||||
std::string *ErrorStr) =nullptr;
|
std::string *ErrorStr) =nullptr;
|
||||||
|
|
||||||
ExecutionEngine::ExecutionEngine(Module *M)
|
ExecutionEngine::ExecutionEngine(std::unique_ptr<Module> M)
|
||||||
: EEState(*this),
|
: EEState(*this),
|
||||||
LazyFunctionCreator(nullptr) {
|
LazyFunctionCreator(nullptr) {
|
||||||
CompilingLazily = false;
|
CompilingLazily = false;
|
||||||
@ -77,14 +77,12 @@ ExecutionEngine::ExecutionEngine(Module *M)
|
|||||||
VerifyModules = false;
|
VerifyModules = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Modules.push_back(M);
|
|
||||||
assert(M && "Module is null?");
|
assert(M && "Module is null?");
|
||||||
|
Modules.push_back(std::move(M));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutionEngine::~ExecutionEngine() {
|
ExecutionEngine::~ExecutionEngine() {
|
||||||
clearAllGlobalMappings();
|
clearAllGlobalMappings();
|
||||||
for (unsigned i = 0, e = Modules.size(); i != e; ++i)
|
|
||||||
delete Modules[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -131,10 +129,10 @@ void ExecutionEngine::addArchive(std::unique_ptr<object::Archive> A) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ExecutionEngine::removeModule(Module *M) {
|
bool ExecutionEngine::removeModule(Module *M) {
|
||||||
for(SmallVectorImpl<Module *>::iterator I = Modules.begin(),
|
for (auto I = Modules.begin(), E = Modules.end(); I != E; ++I) {
|
||||||
E = Modules.end(); I != E; ++I) {
|
Module *Found = I->get();
|
||||||
Module *Found = *I;
|
|
||||||
if (Found == M) {
|
if (Found == M) {
|
||||||
|
I->release();
|
||||||
Modules.erase(I);
|
Modules.erase(I);
|
||||||
clearGlobalMappingsFromModule(M);
|
clearGlobalMappingsFromModule(M);
|
||||||
return true;
|
return true;
|
||||||
@ -307,10 +305,10 @@ void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE,
|
|||||||
return Array;
|
return Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecutionEngine::runStaticConstructorsDestructors(Module *module,
|
void ExecutionEngine::runStaticConstructorsDestructors(Module &module,
|
||||||
bool isDtors) {
|
bool isDtors) {
|
||||||
const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors";
|
const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors";
|
||||||
GlobalVariable *GV = module->getNamedGlobal(Name);
|
GlobalVariable *GV = module.getNamedGlobal(Name);
|
||||||
|
|
||||||
// If this global has internal linkage, or if it has a use, then it must be
|
// If this global has internal linkage, or if it has a use, then it must be
|
||||||
// an old-style (llvmgcc3) static ctor with __main linked in and in use. If
|
// an old-style (llvmgcc3) static ctor with __main linked in and in use. If
|
||||||
@ -348,8 +346,8 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module,
|
|||||||
|
|
||||||
void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
|
void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
|
||||||
// Execute global ctors/dtors for each module in the program.
|
// Execute global ctors/dtors for each module in the program.
|
||||||
for (Module *M : Modules)
|
for (std::unique_ptr<Module> &M : Modules)
|
||||||
runStaticConstructorsDestructors(M, isDtors);
|
runStaticConstructorsDestructors(*M, isDtors);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -474,10 +472,10 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
|
|||||||
|
|
||||||
ExecutionEngine *EE = nullptr;
|
ExecutionEngine *EE = nullptr;
|
||||||
if (UseMCJIT && ExecutionEngine::MCJITCtor)
|
if (UseMCJIT && ExecutionEngine::MCJITCtor)
|
||||||
EE = ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM,
|
EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr,
|
||||||
TheTM.release());
|
MCJMM ? MCJMM : JMM, TheTM.release());
|
||||||
else if (ExecutionEngine::JITCtor)
|
else if (ExecutionEngine::JITCtor)
|
||||||
EE = ExecutionEngine::JITCtor(M, ErrorStr, JMM,
|
EE = ExecutionEngine::JITCtor(std::move(M), ErrorStr, JMM,
|
||||||
AllocateGVsWithCode, TheTM.release());
|
AllocateGVsWithCode, TheTM.release());
|
||||||
|
|
||||||
if (EE) {
|
if (EE) {
|
||||||
@ -490,7 +488,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
|
|||||||
// an interpreter instead.
|
// an interpreter instead.
|
||||||
if (WhichEngine & EngineKind::Interpreter) {
|
if (WhichEngine & EngineKind::Interpreter) {
|
||||||
if (ExecutionEngine::InterpCtor)
|
if (ExecutionEngine::InterpCtor)
|
||||||
return ExecutionEngine::InterpCtor(M, ErrorStr);
|
return ExecutionEngine::InterpCtor(std::move(M), ErrorStr);
|
||||||
if (ErrorStr)
|
if (ErrorStr)
|
||||||
*ErrorStr = "Interpreter has not been linked in.";
|
*ErrorStr = "Interpreter has not been linked in.";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -110,7 +110,7 @@ LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
|
|||||||
LLVMModuleRef M,
|
LLVMModuleRef M,
|
||||||
char **OutError) {
|
char **OutError) {
|
||||||
std::string Error;
|
std::string Error;
|
||||||
EngineBuilder builder(unwrap(M));
|
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
|
||||||
builder.setEngineKind(EngineKind::Either)
|
builder.setEngineKind(EngineKind::Either)
|
||||||
.setErrorStr(&Error);
|
.setErrorStr(&Error);
|
||||||
if (ExecutionEngine *EE = builder.create()){
|
if (ExecutionEngine *EE = builder.create()){
|
||||||
@ -125,7 +125,7 @@ LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
|
|||||||
LLVMModuleRef M,
|
LLVMModuleRef M,
|
||||||
char **OutError) {
|
char **OutError) {
|
||||||
std::string Error;
|
std::string Error;
|
||||||
EngineBuilder builder(unwrap(M));
|
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
|
||||||
builder.setEngineKind(EngineKind::Interpreter)
|
builder.setEngineKind(EngineKind::Interpreter)
|
||||||
.setErrorStr(&Error);
|
.setErrorStr(&Error);
|
||||||
if (ExecutionEngine *Interp = builder.create()) {
|
if (ExecutionEngine *Interp = builder.create()) {
|
||||||
@ -141,7 +141,7 @@ LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
|||||||
unsigned OptLevel,
|
unsigned OptLevel,
|
||||||
char **OutError) {
|
char **OutError) {
|
||||||
std::string Error;
|
std::string Error;
|
||||||
EngineBuilder builder(unwrap(M));
|
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
|
||||||
builder.setEngineKind(EngineKind::JIT)
|
builder.setEngineKind(EngineKind::JIT)
|
||||||
.setErrorStr(&Error)
|
.setErrorStr(&Error)
|
||||||
.setOptLevel((CodeGenOpt::Level)OptLevel);
|
.setOptLevel((CodeGenOpt::Level)OptLevel);
|
||||||
@ -189,7 +189,7 @@ LLVMBool LLVMCreateMCJITCompilerForModule(
|
|||||||
targetOptions.EnableFastISel = options.EnableFastISel;
|
targetOptions.EnableFastISel = options.EnableFastISel;
|
||||||
|
|
||||||
std::string Error;
|
std::string Error;
|
||||||
EngineBuilder builder(unwrap(M));
|
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
|
||||||
builder.setEngineKind(EngineKind::JIT)
|
builder.setEngineKind(EngineKind::JIT)
|
||||||
.setErrorStr(&Error)
|
.setErrorStr(&Error)
|
||||||
.setUseMCJIT(true)
|
.setUseMCJIT(true)
|
||||||
@ -279,7 +279,7 @@ void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
|
void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
|
||||||
unwrap(EE)->addModule(unwrap(M));
|
unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP){
|
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP){
|
||||||
|
@ -30,9 +30,10 @@ static struct RegisterInterp {
|
|||||||
|
|
||||||
extern "C" void LLVMLinkInInterpreter() { }
|
extern "C" void LLVMLinkInInterpreter() { }
|
||||||
|
|
||||||
/// create - Create a new interpreter object. This can never fail.
|
/// Create a new interpreter object.
|
||||||
///
|
///
|
||||||
ExecutionEngine *Interpreter::create(Module *M, std::string* ErrStr) {
|
ExecutionEngine *Interpreter::create(std::unique_ptr<Module> M,
|
||||||
|
std::string *ErrStr) {
|
||||||
// Tell this Module to materialize everything and release the GVMaterializer.
|
// Tell this Module to materialize everything and release the GVMaterializer.
|
||||||
if (std::error_code EC = M->materializeAllPermanently()) {
|
if (std::error_code EC = M->materializeAllPermanently()) {
|
||||||
if (ErrStr)
|
if (ErrStr)
|
||||||
@ -41,14 +42,14 @@ ExecutionEngine *Interpreter::create(Module *M, std::string* ErrStr) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Interpreter(M);
|
return new Interpreter(std::move(M));
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Interpreter ctor - Initialize stuff
|
// Interpreter ctor - Initialize stuff
|
||||||
//
|
//
|
||||||
Interpreter::Interpreter(Module *M)
|
Interpreter::Interpreter(std::unique_ptr<Module> M)
|
||||||
: ExecutionEngine(M), TD(M) {
|
: ExecutionEngine(std::move(M)), TD(Modules.back().get()) {
|
||||||
|
|
||||||
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
|
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
|
||||||
setDataLayout(&TD);
|
setDataLayout(&TD);
|
||||||
|
@ -94,7 +94,7 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
|
|||||||
std::vector<Function*> AtExitHandlers;
|
std::vector<Function*> AtExitHandlers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Interpreter(Module *M);
|
explicit Interpreter(std::unique_ptr<Module> M);
|
||||||
~Interpreter();
|
~Interpreter();
|
||||||
|
|
||||||
/// runAtExitHandlers - Run any functions registered by the program's calls to
|
/// runAtExitHandlers - Run any functions registered by the program's calls to
|
||||||
@ -106,9 +106,10 @@ public:
|
|||||||
InterpCtor = create;
|
InterpCtor = create;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// create - Create an interpreter ExecutionEngine. This can never fail.
|
/// Create an interpreter ExecutionEngine.
|
||||||
///
|
///
|
||||||
static ExecutionEngine *create(Module *M, std::string *ErrorStr = nullptr);
|
static ExecutionEngine *create(std::unique_ptr<Module> M,
|
||||||
|
std::string *ErrorStr = nullptr);
|
||||||
|
|
||||||
/// run - Start execution with the specified function and arguments.
|
/// run - Start execution with the specified function and arguments.
|
||||||
///
|
///
|
||||||
|
@ -69,10 +69,9 @@ static struct RegisterJIT {
|
|||||||
extern "C" void LLVMLinkInJIT() {
|
extern "C" void LLVMLinkInJIT() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createJIT - This is the factory method for creating a JIT for the current
|
/// This is the factory method for creating a JIT for the current machine, it
|
||||||
/// machine, it does not fall back to the interpreter. This takes ownership
|
/// does not fall back to the interpreter.
|
||||||
/// of the module.
|
ExecutionEngine *JIT::createJIT(std::unique_ptr<Module> M,
|
||||||
ExecutionEngine *JIT::createJIT(Module *M,
|
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
JITMemoryManager *JMM,
|
JITMemoryManager *JMM,
|
||||||
bool GVsWithCode,
|
bool GVsWithCode,
|
||||||
@ -84,7 +83,7 @@ ExecutionEngine *JIT::createJIT(Module *M,
|
|||||||
|
|
||||||
// If the target supports JIT code generation, create the JIT.
|
// If the target supports JIT code generation, create the JIT.
|
||||||
if (TargetJITInfo *TJ = TM->getSubtargetImpl()->getJITInfo()) {
|
if (TargetJITInfo *TJ = TM->getSubtargetImpl()->getJITInfo()) {
|
||||||
return new JIT(M, *TM, *TJ, JMM, GVsWithCode);
|
return new JIT(std::move(M), *TM, *TJ, JMM, GVsWithCode);
|
||||||
} else {
|
} else {
|
||||||
if (ErrorStr)
|
if (ErrorStr)
|
||||||
*ErrorStr = "target does not support JIT code generation";
|
*ErrorStr = "target does not support JIT code generation";
|
||||||
@ -135,14 +134,15 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
|
JIT::JIT(std::unique_ptr<Module> M, TargetMachine &tm, TargetJITInfo &tji,
|
||||||
JITMemoryManager *jmm, bool GVsWithCode)
|
JITMemoryManager *jmm, bool GVsWithCode)
|
||||||
: ExecutionEngine(M), TM(tm), TJI(tji),
|
: ExecutionEngine(std::move(M)), TM(tm), TJI(tji),
|
||||||
JMM(jmm ? jmm : JITMemoryManager::CreateDefaultMemManager()),
|
JMM(jmm ? jmm : JITMemoryManager::CreateDefaultMemManager()),
|
||||||
AllocateGVsWithCode(GVsWithCode), isAlreadyCodeGenerating(false) {
|
AllocateGVsWithCode(GVsWithCode), isAlreadyCodeGenerating(false) {
|
||||||
setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
||||||
|
|
||||||
jitstate = new JITState(M);
|
Module *Mod = Modules.back().get();
|
||||||
|
jitstate = new JITState(Mod);
|
||||||
|
|
||||||
// Initialize JCE
|
// Initialize JCE
|
||||||
JCE = createEmitter(*this, JMM, TM);
|
JCE = createEmitter(*this, JMM, TM);
|
||||||
@ -153,8 +153,8 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
|
|||||||
// Add target data
|
// Add target data
|
||||||
MutexGuard locked(lock);
|
MutexGuard locked(lock);
|
||||||
FunctionPassManager &PM = jitstate->getPM();
|
FunctionPassManager &PM = jitstate->getPM();
|
||||||
M->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
Mod->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
||||||
PM.add(new DataLayoutPass(M));
|
PM.add(new DataLayoutPass(Mod));
|
||||||
|
|
||||||
// Turn the machine code intermediate representation into bytes in memory that
|
// Turn the machine code intermediate representation into bytes in memory that
|
||||||
// may be executed.
|
// may be executed.
|
||||||
@ -175,19 +175,19 @@ JIT::~JIT() {
|
|||||||
delete &TM;
|
delete &TM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// addModule - Add a new Module to the JIT. If we previously removed the last
|
/// Add a new Module to the JIT. If we previously removed the last Module, we
|
||||||
/// Module, we need re-initialize jitstate with a valid Module.
|
/// need re-initialize jitstate with a valid Module.
|
||||||
void JIT::addModule(Module *M) {
|
void JIT::addModule(std::unique_ptr<Module> M) {
|
||||||
MutexGuard locked(lock);
|
MutexGuard locked(lock);
|
||||||
|
|
||||||
if (Modules.empty()) {
|
if (Modules.empty()) {
|
||||||
assert(!jitstate && "jitstate should be NULL if Modules vector is empty!");
|
assert(!jitstate && "jitstate should be NULL if Modules vector is empty!");
|
||||||
|
|
||||||
jitstate = new JITState(M);
|
jitstate = new JITState(M.get());
|
||||||
|
|
||||||
FunctionPassManager &PM = jitstate->getPM();
|
FunctionPassManager &PM = jitstate->getPM();
|
||||||
M->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
M->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
||||||
PM.add(new DataLayoutPass(M));
|
PM.add(new DataLayoutPass(M.get()));
|
||||||
|
|
||||||
// Turn the machine code intermediate representation into bytes in memory
|
// Turn the machine code intermediate representation into bytes in memory
|
||||||
// that may be executed.
|
// that may be executed.
|
||||||
@ -199,11 +199,11 @@ void JIT::addModule(Module *M) {
|
|||||||
PM.doInitialization();
|
PM.doInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutionEngine::addModule(M);
|
ExecutionEngine::addModule(std::move(M));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// removeModule - If we are removing the last Module, invalidate the jitstate
|
/// If we are removing the last Module, invalidate the jitstate since the
|
||||||
/// since the PassManager it contains references a released Module.
|
/// PassManager it contains references a released Module.
|
||||||
bool JIT::removeModule(Module *M) {
|
bool JIT::removeModule(Module *M) {
|
||||||
bool result = ExecutionEngine::removeModule(M);
|
bool result = ExecutionEngine::removeModule(M);
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ bool JIT::removeModule(Module *M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!jitstate && !Modules.empty()) {
|
if (!jitstate && !Modules.empty()) {
|
||||||
jitstate = new JITState(Modules[0]);
|
jitstate = new JITState(Modules[0].get());
|
||||||
|
|
||||||
FunctionPassManager &PM = jitstate->getPM();
|
FunctionPassManager &PM = jitstate->getPM();
|
||||||
M->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
M->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
|
||||||
|
@ -78,7 +78,7 @@ class JIT : public ExecutionEngine {
|
|||||||
BasicBlockAddressMapTy BasicBlockAddressMap;
|
BasicBlockAddressMapTy BasicBlockAddressMap;
|
||||||
|
|
||||||
|
|
||||||
JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
|
JIT(std::unique_ptr<Module> M, TargetMachine &tm, TargetJITInfo &tji,
|
||||||
JITMemoryManager *JMM, bool AllocateGVsWithCode);
|
JITMemoryManager *JMM, bool AllocateGVsWithCode);
|
||||||
public:
|
public:
|
||||||
~JIT();
|
~JIT();
|
||||||
@ -91,7 +91,7 @@ public:
|
|||||||
///
|
///
|
||||||
TargetJITInfo &getJITInfo() const { return TJI; }
|
TargetJITInfo &getJITInfo() const { return TJI; }
|
||||||
|
|
||||||
void addModule(Module *M) override;
|
void addModule(std::unique_ptr<Module> M) override;
|
||||||
|
|
||||||
/// removeModule - Remove a Module from the list of modules. Returns true if
|
/// removeModule - Remove a Module from the list of modules. Returns true if
|
||||||
/// M is found.
|
/// M is found.
|
||||||
@ -167,7 +167,7 @@ public:
|
|||||||
///
|
///
|
||||||
JITCodeEmitter *getCodeEmitter() const { return JCE; }
|
JITCodeEmitter *getCodeEmitter() const { return JCE; }
|
||||||
|
|
||||||
static ExecutionEngine *createJIT(Module *M,
|
static ExecutionEngine *createJIT(std::unique_ptr<Module> M,
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
JITMemoryManager *JMM,
|
JITMemoryManager *JMM,
|
||||||
bool GVsWithCode,
|
bool GVsWithCode,
|
||||||
|
@ -43,7 +43,7 @@ static struct RegisterJIT {
|
|||||||
extern "C" void LLVMLinkInMCJIT() {
|
extern "C" void LLVMLinkInMCJIT() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutionEngine *MCJIT::createJIT(Module *M,
|
ExecutionEngine *MCJIT::createJIT(std::unique_ptr<Module> M,
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
RTDyldMemoryManager *MemMgr,
|
RTDyldMemoryManager *MemMgr,
|
||||||
TargetMachine *TM) {
|
TargetMachine *TM) {
|
||||||
@ -52,19 +52,14 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
|
|||||||
// FIXME: Don't do this here.
|
// FIXME: Don't do this here.
|
||||||
sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
|
sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
|
||||||
|
|
||||||
return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager());
|
return new MCJIT(std::move(M), TM,
|
||||||
|
MemMgr ? MemMgr : new SectionMemoryManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM)
|
MCJIT::MCJIT(std::unique_ptr<Module> M, TargetMachine *tm,
|
||||||
: ExecutionEngine(m), TM(tm), Ctx(nullptr), MemMgr(this, MM), Dyld(&MemMgr),
|
RTDyldMemoryManager *MM)
|
||||||
ObjCache(nullptr) {
|
: ExecutionEngine(std::move(M)), TM(tm), Ctx(nullptr), MemMgr(this, MM),
|
||||||
|
Dyld(&MemMgr), ObjCache(nullptr) {
|
||||||
OwnedModules.addModule(m);
|
|
||||||
setDataLayout(TM->getSubtargetImpl()->getDataLayout());
|
|
||||||
}
|
|
||||||
|
|
||||||
MCJIT::~MCJIT() {
|
|
||||||
MutexGuard locked(lock);
|
|
||||||
// FIXME: We are managing our modules, so we do not want the base class
|
// FIXME: We are managing our modules, so we do not want the base class
|
||||||
// ExecutionEngine to manage them as well. To avoid double destruction
|
// ExecutionEngine to manage them as well. To avoid double destruction
|
||||||
// of the first (and only) module added in ExecutionEngine constructor
|
// of the first (and only) module added in ExecutionEngine constructor
|
||||||
@ -75,7 +70,16 @@ MCJIT::~MCJIT() {
|
|||||||
// If so, additional functions: addModule, removeModule, FindFunctionNamed,
|
// If so, additional functions: addModule, removeModule, FindFunctionNamed,
|
||||||
// runStaticConstructorsDestructors could be moved back to EE as well.
|
// runStaticConstructorsDestructors could be moved back to EE as well.
|
||||||
//
|
//
|
||||||
|
std::unique_ptr<Module> First = std::move(Modules[0]);
|
||||||
Modules.clear();
|
Modules.clear();
|
||||||
|
|
||||||
|
OwnedModules.addModule(std::move(First));
|
||||||
|
setDataLayout(TM->getSubtargetImpl()->getDataLayout());
|
||||||
|
}
|
||||||
|
|
||||||
|
MCJIT::~MCJIT() {
|
||||||
|
MutexGuard locked(lock);
|
||||||
|
|
||||||
Dyld.deregisterEHFrames();
|
Dyld.deregisterEHFrames();
|
||||||
|
|
||||||
LoadedObjectList::iterator it, end;
|
LoadedObjectList::iterator it, end;
|
||||||
@ -93,9 +97,9 @@ MCJIT::~MCJIT() {
|
|||||||
delete TM;
|
delete TM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCJIT::addModule(Module *M) {
|
void MCJIT::addModule(std::unique_ptr<Module> M) {
|
||||||
MutexGuard locked(lock);
|
MutexGuard locked(lock);
|
||||||
OwnedModules.addModule(M);
|
OwnedModules.addModule(std::move(M));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCJIT::removeModule(Module *M) {
|
bool MCJIT::removeModule(Module *M) {
|
||||||
@ -389,7 +393,7 @@ void MCJIT::freeMachineCodeForFunction(Function *F) {
|
|||||||
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
|
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
|
||||||
bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
|
bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
|
||||||
for (; I != E; ++I) {
|
for (; I != E; ++I) {
|
||||||
ExecutionEngine::runStaticConstructorsDestructors(*I, isDtors);
|
ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,8 @@ private:
|
|||||||
// called.
|
// called.
|
||||||
|
|
||||||
class MCJIT : public ExecutionEngine {
|
class MCJIT : public ExecutionEngine {
|
||||||
MCJIT(Module *M, TargetMachine *tm, RTDyldMemoryManager *MemMgr);
|
MCJIT(std::unique_ptr<Module> M, TargetMachine *tm,
|
||||||
|
RTDyldMemoryManager *MemMgr);
|
||||||
|
|
||||||
typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
|
typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
|
||||||
|
|
||||||
@ -124,8 +125,8 @@ class MCJIT : public ExecutionEngine {
|
|||||||
ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
|
ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
|
||||||
ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }
|
ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }
|
||||||
|
|
||||||
void addModule(Module *M) {
|
void addModule(std::unique_ptr<Module> M) {
|
||||||
AddedModules.insert(M);
|
AddedModules.insert(M.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool removeModule(Module *M) {
|
bool removeModule(Module *M) {
|
||||||
@ -237,7 +238,7 @@ public:
|
|||||||
|
|
||||||
/// @name ExecutionEngine interface implementation
|
/// @name ExecutionEngine interface implementation
|
||||||
/// @{
|
/// @{
|
||||||
void addModule(Module *M) override;
|
void addModule(std::unique_ptr<Module> M) override;
|
||||||
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
|
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
|
||||||
void addArchive(std::unique_ptr<object::Archive> O) override;
|
void addArchive(std::unique_ptr<object::Archive> O) override;
|
||||||
bool removeModule(Module *M) override;
|
bool removeModule(Module *M) override;
|
||||||
@ -324,7 +325,7 @@ public:
|
|||||||
MCJITCtor = createJIT;
|
MCJITCtor = createJIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ExecutionEngine *createJIT(Module *M,
|
static ExecutionEngine *createJIT(std::unique_ptr<Module> M,
|
||||||
std::string *ErrorStr,
|
std::string *ErrorStr,
|
||||||
RTDyldMemoryManager *MemMgr,
|
RTDyldMemoryManager *MemMgr,
|
||||||
TargetMachine *TM);
|
TargetMachine *TM);
|
||||||
|
@ -346,7 +346,7 @@ static void addCygMingExtraModule(ExecutionEngine *EE,
|
|||||||
Triple TargetTriple(TargetTripleStr);
|
Triple TargetTriple(TargetTripleStr);
|
||||||
|
|
||||||
// Create a new module.
|
// Create a new module.
|
||||||
Module *M = new Module("CygMingHelper", Context);
|
std::unique_ptr<Module> M = make_unique<Module>("CygMingHelper", Context);
|
||||||
M->setTargetTriple(TargetTripleStr);
|
M->setTargetTriple(TargetTripleStr);
|
||||||
|
|
||||||
// Create an empty function named "__main".
|
// Create an empty function named "__main".
|
||||||
@ -354,11 +354,11 @@ static void addCygMingExtraModule(ExecutionEngine *EE,
|
|||||||
if (TargetTriple.isArch64Bit()) {
|
if (TargetTriple.isArch64Bit()) {
|
||||||
Result = Function::Create(
|
Result = Function::Create(
|
||||||
TypeBuilder<int64_t(void), false>::get(Context),
|
TypeBuilder<int64_t(void), false>::get(Context),
|
||||||
GlobalValue::ExternalLinkage, "__main", M);
|
GlobalValue::ExternalLinkage, "__main", M.get());
|
||||||
} else {
|
} else {
|
||||||
Result = Function::Create(
|
Result = Function::Create(
|
||||||
TypeBuilder<int32_t(void), false>::get(Context),
|
TypeBuilder<int32_t(void), false>::get(Context),
|
||||||
GlobalValue::ExternalLinkage, "__main", M);
|
GlobalValue::ExternalLinkage, "__main", M.get());
|
||||||
}
|
}
|
||||||
BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);
|
BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);
|
||||||
Builder.SetInsertPoint(BB);
|
Builder.SetInsertPoint(BB);
|
||||||
@ -370,7 +370,7 @@ static void addCygMingExtraModule(ExecutionEngine *EE,
|
|||||||
Builder.CreateRet(ReturnVal);
|
Builder.CreateRet(ReturnVal);
|
||||||
|
|
||||||
// Add this new module to the ExecutionEngine.
|
// Add this new module to the ExecutionEngine.
|
||||||
EE->addModule(M);
|
EE->addModule(std::move(M));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -399,7 +399,8 @@ int main(int argc, char **argv, char * const *envp) {
|
|||||||
|
|
||||||
// Load the bitcode...
|
// Load the bitcode...
|
||||||
SMDiagnostic Err;
|
SMDiagnostic Err;
|
||||||
Module *Mod = ParseIRFile(InputFile, Err, Context);
|
std::unique_ptr<Module> Owner(ParseIRFile(InputFile, Err, Context));
|
||||||
|
Module *Mod = Owner.get();
|
||||||
if (!Mod) {
|
if (!Mod) {
|
||||||
Err.print(argv[0], errs());
|
Err.print(argv[0], errs());
|
||||||
return 1;
|
return 1;
|
||||||
@ -435,7 +436,7 @@ int main(int argc, char **argv, char * const *envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ErrorMsg;
|
std::string ErrorMsg;
|
||||||
EngineBuilder builder(Mod);
|
EngineBuilder builder(std::move(Owner));
|
||||||
builder.setMArch(MArch);
|
builder.setMArch(MArch);
|
||||||
builder.setMCPU(MCPU);
|
builder.setMCPU(MCPU);
|
||||||
builder.setMAttrs(MAttrs);
|
builder.setMAttrs(MAttrs);
|
||||||
@ -512,7 +513,7 @@ int main(int argc, char **argv, char * const *envp) {
|
|||||||
|
|
||||||
// Load any additional modules specified on the command line.
|
// Load any additional modules specified on the command line.
|
||||||
for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) {
|
||||||
Module *XMod = ParseIRFile(ExtraModules[i], Err, Context);
|
std::unique_ptr<Module> XMod(ParseIRFile(ExtraModules[i], Err, Context));
|
||||||
if (!XMod) {
|
if (!XMod) {
|
||||||
Err.print(argv[0], errs());
|
Err.print(argv[0], errs());
|
||||||
return 1;
|
return 1;
|
||||||
@ -525,7 +526,7 @@ int main(int argc, char **argv, char * const *envp) {
|
|||||||
}
|
}
|
||||||
// else, we already printed a warning above.
|
// else, we already printed a warning above.
|
||||||
}
|
}
|
||||||
EE->addModule(XMod);
|
EE->addModule(std::move(XMod));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) {
|
||||||
|
@ -20,9 +20,10 @@ namespace {
|
|||||||
|
|
||||||
class ExecutionEngineTest : public testing::Test {
|
class ExecutionEngineTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
ExecutionEngineTest()
|
ExecutionEngineTest() {
|
||||||
: M(new Module("<main>", getGlobalContext())), Error(""),
|
auto Owner = make_unique<Module>("<main>", getGlobalContext());
|
||||||
Engine(EngineBuilder(M).setErrorStr(&Error).create()) {
|
M = Owner.get();
|
||||||
|
Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
@ -35,9 +36,9 @@ protected:
|
|||||||
GlobalValue::ExternalLinkage, nullptr, Name);
|
GlobalValue::ExternalLinkage, nullptr, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Module *const M;
|
|
||||||
std::string Error;
|
std::string Error;
|
||||||
const std::unique_ptr<ExecutionEngine> Engine;
|
Module *M; // Owned by ExecutionEngine.
|
||||||
|
std::unique_ptr<ExecutionEngine> Engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
|
TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
|
||||||
|
@ -60,15 +60,16 @@ struct RecordingJITEventListener : public JITEventListener {
|
|||||||
|
|
||||||
class JITEventListenerTest : public testing::Test {
|
class JITEventListenerTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
JITEventListenerTest()
|
JITEventListenerTest() {
|
||||||
: M(new Module("module", getGlobalContext())),
|
auto Owner = make_unique<Module>("module", getGlobalContext());
|
||||||
EE(EngineBuilder(M)
|
M = Owner.get();
|
||||||
|
EE.reset(EngineBuilder(std::move(Owner))
|
||||||
.setEngineKind(EngineKind::JIT)
|
.setEngineKind(EngineKind::JIT)
|
||||||
.create()) {
|
.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
Module *M;
|
Module *M;
|
||||||
const std::unique_ptr<ExecutionEngine> EE;
|
std::unique_ptr<ExecutionEngine> EE;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tests on SystemZ disabled as we're running the old JIT
|
// Tests on SystemZ disabled as we're running the old JIT
|
||||||
|
@ -184,15 +184,18 @@ class JITTest : public testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
M = new Module("<main>", Context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("<main>", Context);
|
||||||
|
M = Owner.get();
|
||||||
RJMM = createMemoryManager();
|
RJMM = createMemoryManager();
|
||||||
RJMM->setPoisonMemory(true);
|
RJMM->setPoisonMemory(true);
|
||||||
std::string Error;
|
std::string Error;
|
||||||
TargetOptions Options;
|
TargetOptions Options;
|
||||||
TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
|
TheJIT.reset(EngineBuilder(std::move(Owner))
|
||||||
|
.setEngineKind(EngineKind::JIT)
|
||||||
.setJITMemoryManager(RJMM)
|
.setJITMemoryManager(RJMM)
|
||||||
.setErrorStr(&Error)
|
.setErrorStr(&Error)
|
||||||
.setTargetOptions(Options).create());
|
.setTargetOptions(Options)
|
||||||
|
.create());
|
||||||
ASSERT_TRUE(TheJIT.get() != nullptr) << Error;
|
ASSERT_TRUE(TheJIT.get() != nullptr) << Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,14 +216,15 @@ class JITTest : public testing::Test {
|
|||||||
// stays alive after that.
|
// stays alive after that.
|
||||||
TEST(JIT, GlobalInFunction) {
|
TEST(JIT, GlobalInFunction) {
|
||||||
LLVMContext context;
|
LLVMContext context;
|
||||||
Module *M = new Module("<main>", context);
|
std::unique_ptr<Module> Owner = make_unique<Module>("<main>", context);
|
||||||
|
Module *M = Owner.get();
|
||||||
|
|
||||||
JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
|
JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
|
||||||
// Tell the memory manager to poison freed memory so that accessing freed
|
// Tell the memory manager to poison freed memory so that accessing freed
|
||||||
// memory is more easily tested.
|
// memory is more easily tested.
|
||||||
MemMgr->setPoisonMemory(true);
|
MemMgr->setPoisonMemory(true);
|
||||||
std::string Error;
|
std::string Error;
|
||||||
std::unique_ptr<ExecutionEngine> JIT(EngineBuilder(M)
|
std::unique_ptr<ExecutionEngine> JIT(EngineBuilder(std::move(Owner))
|
||||||
.setEngineKind(EngineKind::JIT)
|
.setEngineKind(EngineKind::JIT)
|
||||||
.setErrorStr(&Error)
|
.setErrorStr(&Error)
|
||||||
.setJITMemoryManager(MemMgr)
|
.setJITMemoryManager(MemMgr)
|
||||||
@ -638,9 +642,10 @@ ExecutionEngine *getJITFromBitcode(
|
|||||||
delete BitcodeBuffer;
|
delete BitcodeBuffer;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
M = ModuleOrErr.get();
|
std::unique_ptr<Module> Owner(ModuleOrErr.get());
|
||||||
|
M = Owner.get();
|
||||||
std::string errMsg;
|
std::string errMsg;
|
||||||
ExecutionEngine *TheJIT = EngineBuilder(M)
|
ExecutionEngine *TheJIT = EngineBuilder(std::move(Owner))
|
||||||
.setEngineKind(EngineKind::JIT)
|
.setEngineKind(EngineKind::JIT)
|
||||||
.setErrorStr(&errMsg)
|
.setErrorStr(&errMsg)
|
||||||
.create();
|
.create();
|
||||||
|
@ -24,20 +24,20 @@ namespace {
|
|||||||
#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \
|
#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \
|
||||||
&& !defined(__aarch64__)
|
&& !defined(__aarch64__)
|
||||||
|
|
||||||
bool LoadAssemblyInto(Module *M, const char *assembly) {
|
std::unique_ptr<Module> loadAssembly(LLVMContext &Context,
|
||||||
|
const char *Assembly) {
|
||||||
SMDiagnostic Error;
|
SMDiagnostic Error;
|
||||||
bool success =
|
std::unique_ptr<Module> Ret(
|
||||||
nullptr != ParseAssemblyString(assembly, M, Error, M->getContext());
|
ParseAssemblyString(Assembly, nullptr, Error, Context));
|
||||||
std::string errMsg;
|
std::string errMsg;
|
||||||
raw_string_ostream os(errMsg);
|
raw_string_ostream os(errMsg);
|
||||||
Error.print("", os);
|
Error.print("", os);
|
||||||
EXPECT_TRUE(success) << os.str();
|
EXPECT_TRUE((bool)Ret) << os.str();
|
||||||
return success;
|
return std::move(Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createModule1(LLVMContext &Context1, Module *&M1, Function *&FooF1) {
|
std::unique_ptr<Module> createModule1(LLVMContext &Context1, Function *&FooF1) {
|
||||||
M1 = new Module("test1", Context1);
|
std::unique_ptr<Module> Ret = loadAssembly(Context1,
|
||||||
LoadAssemblyInto(M1,
|
|
||||||
"define i32 @add1(i32 %ArgX1) { "
|
"define i32 @add1(i32 %ArgX1) { "
|
||||||
"entry: "
|
"entry: "
|
||||||
" %addresult = add i32 1, %ArgX1 "
|
" %addresult = add i32 1, %ArgX1 "
|
||||||
@ -49,12 +49,12 @@ void createModule1(LLVMContext &Context1, Module *&M1, Function *&FooF1) {
|
|||||||
" %add1 = call i32 @add1(i32 10) "
|
" %add1 = call i32 @add1(i32 10) "
|
||||||
" ret i32 %add1 "
|
" ret i32 %add1 "
|
||||||
"} ");
|
"} ");
|
||||||
FooF1 = M1->getFunction("foo1");
|
FooF1 = Ret->getFunction("foo1");
|
||||||
|
return std::move(Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
|
std::unique_ptr<Module> createModule2(LLVMContext &Context2, Function *&FooF2) {
|
||||||
M2 = new Module("test2", Context2);
|
std::unique_ptr<Module> Ret = loadAssembly(Context2,
|
||||||
LoadAssemblyInto(M2,
|
|
||||||
"define i32 @add2(i32 %ArgX2) { "
|
"define i32 @add2(i32 %ArgX2) { "
|
||||||
"entry: "
|
"entry: "
|
||||||
" %addresult = add i32 2, %ArgX2 "
|
" %addresult = add i32 2, %ArgX2 "
|
||||||
@ -66,24 +66,23 @@ void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
|
|||||||
" %add2 = call i32 @add2(i32 10) "
|
" %add2 = call i32 @add2(i32 10) "
|
||||||
" ret i32 %add2 "
|
" ret i32 %add2 "
|
||||||
"} ");
|
"} ");
|
||||||
FooF2 = M2->getFunction("foo2");
|
FooF2 = Ret->getFunction("foo2");
|
||||||
|
return std::move(Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MultiJitTest, EagerMode) {
|
TEST(MultiJitTest, EagerMode) {
|
||||||
LLVMContext Context1;
|
LLVMContext Context1;
|
||||||
Module *M1 = nullptr;
|
|
||||||
Function *FooF1 = nullptr;
|
Function *FooF1 = nullptr;
|
||||||
createModule1(Context1, M1, FooF1);
|
std::unique_ptr<Module> M1 = createModule1(Context1, FooF1);
|
||||||
|
|
||||||
LLVMContext Context2;
|
LLVMContext Context2;
|
||||||
Module *M2 = nullptr;
|
|
||||||
Function *FooF2 = nullptr;
|
Function *FooF2 = nullptr;
|
||||||
createModule2(Context2, M2, FooF2);
|
std::unique_ptr<Module> M2 = createModule2(Context2, FooF2);
|
||||||
|
|
||||||
// Now we create the JIT in eager mode
|
// Now we create the JIT in eager mode
|
||||||
std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
|
std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(std::move(M1)).create());
|
||||||
EE1->DisableLazyCompilation(true);
|
EE1->DisableLazyCompilation(true);
|
||||||
std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
|
std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(std::move(M2)).create());
|
||||||
EE2->DisableLazyCompilation(true);
|
EE2->DisableLazyCompilation(true);
|
||||||
|
|
||||||
// Call the `foo' function with no arguments:
|
// Call the `foo' function with no arguments:
|
||||||
@ -101,19 +100,17 @@ TEST(MultiJitTest, EagerMode) {
|
|||||||
|
|
||||||
TEST(MultiJitTest, LazyMode) {
|
TEST(MultiJitTest, LazyMode) {
|
||||||
LLVMContext Context1;
|
LLVMContext Context1;
|
||||||
Module *M1 = nullptr;
|
|
||||||
Function *FooF1 = nullptr;
|
Function *FooF1 = nullptr;
|
||||||
createModule1(Context1, M1, FooF1);
|
std::unique_ptr<Module> M1 = createModule1(Context1, FooF1);
|
||||||
|
|
||||||
LLVMContext Context2;
|
LLVMContext Context2;
|
||||||
Module *M2 = nullptr;
|
|
||||||
Function *FooF2 = nullptr;
|
Function *FooF2 = nullptr;
|
||||||
createModule2(Context2, M2, FooF2);
|
std::unique_ptr<Module> M2 = createModule2(Context2, FooF2);
|
||||||
|
|
||||||
// Now we create the JIT in lazy mode
|
// Now we create the JIT in lazy mode
|
||||||
std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
|
std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(std::move(M1)).create());
|
||||||
EE1->DisableLazyCompilation(false);
|
EE1->DisableLazyCompilation(false);
|
||||||
std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
|
std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(std::move(M2)).create());
|
||||||
EE2->DisableLazyCompilation(false);
|
EE2->DisableLazyCompilation(false);
|
||||||
|
|
||||||
// Call the `foo' function with no arguments:
|
// Call the `foo' function with no arguments:
|
||||||
@ -135,18 +132,16 @@ extern "C" {
|
|||||||
|
|
||||||
TEST(MultiJitTest, JitPool) {
|
TEST(MultiJitTest, JitPool) {
|
||||||
LLVMContext Context1;
|
LLVMContext Context1;
|
||||||
Module *M1 = nullptr;
|
|
||||||
Function *FooF1 = nullptr;
|
Function *FooF1 = nullptr;
|
||||||
createModule1(Context1, M1, FooF1);
|
std::unique_ptr<Module> M1 = createModule1(Context1, FooF1);
|
||||||
|
|
||||||
LLVMContext Context2;
|
LLVMContext Context2;
|
||||||
Module *M2 = nullptr;
|
|
||||||
Function *FooF2 = nullptr;
|
Function *FooF2 = nullptr;
|
||||||
createModule2(Context2, M2, FooF2);
|
std::unique_ptr<Module> M2 = createModule2(Context2, FooF2);
|
||||||
|
|
||||||
// Now we create two JITs
|
// Now we create two JITs
|
||||||
std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
|
std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(std::move(M1)).create());
|
||||||
std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
|
std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(std::move(M2)).create());
|
||||||
|
|
||||||
Function *F1 = EE1->FindFunctionNamed("foo1");
|
Function *F1 = EE1->FindFunctionNamed("foo1");
|
||||||
void *foo1 = EE1->getPointerToFunction(F1);
|
void *foo1 = EE1->getPointerToFunction(F1);
|
||||||
|
@ -94,8 +94,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_case) {
|
|||||||
Function *FA, *FB;
|
Function *FA, *FB;
|
||||||
createTwoModuleCase(A, FA, B, FB);
|
createTwoModuleCase(A, FA, B, FB);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
||||||
checkAdd(ptr);
|
checkAdd(ptr);
|
||||||
@ -114,8 +114,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_reverse_case) {
|
|||||||
Function *FA, *FB;
|
Function *FA, *FB;
|
||||||
createTwoModuleCase(A, FA, B, FB);
|
createTwoModuleCase(A, FA, B, FB);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
|
||||||
TheJIT->finalizeObject();
|
TheJIT->finalizeObject();
|
||||||
@ -135,8 +135,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_extern_reverse_case) {
|
|||||||
Function *FA, *FB;
|
Function *FA, *FB;
|
||||||
createTwoModuleExternCase(A, FA, B, FB);
|
createTwoModuleExternCase(A, FA, B, FB);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
|
||||||
TheJIT->finalizeObject();
|
TheJIT->finalizeObject();
|
||||||
@ -156,8 +156,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_extern_case) {
|
|||||||
Function *FA, *FB;
|
Function *FA, *FB;
|
||||||
createTwoModuleExternCase(A, FA, B, FB);
|
createTwoModuleExternCase(A, FA, B, FB);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
||||||
checkAdd(ptr);
|
checkAdd(ptr);
|
||||||
@ -177,8 +177,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) {
|
|||||||
createTwoModuleExternCase(A, FA1, B, FB);
|
createTwoModuleExternCase(A, FA1, B, FB);
|
||||||
FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1);
|
FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
|
||||||
TheJIT->finalizeObject();
|
TheJIT->finalizeObject();
|
||||||
@ -213,8 +213,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
|
|||||||
FB = startFunction<int32_t(void)>(B.get(), "FB");
|
FB = startFunction<int32_t(void)>(B.get(), "FB");
|
||||||
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
|
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
|
uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
|
||||||
TheJIT->finalizeObject();
|
TheJIT->finalizeObject();
|
||||||
@ -241,9 +241,9 @@ TEST_F(MCJITMultipleModuleTest, three_module_case) {
|
|||||||
Function *FA, *FB, *FC;
|
Function *FA, *FB, *FC;
|
||||||
createThreeModuleCase(A, FA, B, FB, C, FC);
|
createThreeModuleCase(A, FA, B, FB, C, FC);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
TheJIT->addModule(C.release());
|
TheJIT->addModule(std::move(C));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
|
||||||
checkAdd(ptr);
|
checkAdd(ptr);
|
||||||
@ -266,9 +266,9 @@ TEST_F(MCJITMultipleModuleTest, three_module_case_reverse_order) {
|
|||||||
Function *FA, *FB, *FC;
|
Function *FA, *FB, *FC;
|
||||||
createThreeModuleCase(A, FA, B, FB, C, FC);
|
createThreeModuleCase(A, FA, B, FB, C, FC);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
TheJIT->addModule(C.release());
|
TheJIT->addModule(std::move(C));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
||||||
checkAdd(ptr);
|
checkAdd(ptr);
|
||||||
@ -291,9 +291,9 @@ TEST_F(MCJITMultipleModuleTest, three_module_chain_case) {
|
|||||||
Function *FA, *FB, *FC;
|
Function *FA, *FB, *FC;
|
||||||
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
|
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
TheJIT->addModule(C.release());
|
TheJIT->addModule(std::move(C));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
|
||||||
checkAdd(ptr);
|
checkAdd(ptr);
|
||||||
@ -316,9 +316,9 @@ TEST_F(MCJITMultipleModuleTest, three_modules_chain_case_reverse_order) {
|
|||||||
Function *FA, *FB, *FC;
|
Function *FA, *FB, *FC;
|
||||||
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
|
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
TheJIT->addModule(C.release());
|
TheJIT->addModule(std::move(C));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
||||||
checkAdd(ptr);
|
checkAdd(ptr);
|
||||||
@ -341,8 +341,8 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case) {
|
|||||||
Function *FA, *FB1, *FB2;
|
Function *FA, *FB1, *FB2;
|
||||||
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
|
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
|
||||||
checkAccumulate(ptr);
|
checkAccumulate(ptr);
|
||||||
@ -362,8 +362,8 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case_reverse_order) {
|
|||||||
Function *FA, *FB1, *FB2;
|
Function *FA, *FB1, *FB2;
|
||||||
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
|
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
|
||||||
checkAccumulate(ptr);
|
checkAccumulate(ptr);
|
||||||
@ -383,8 +383,8 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case3) {
|
|||||||
Function *FA, *FB1, *FB2;
|
Function *FA, *FB1, *FB2;
|
||||||
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
|
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
|
||||||
|
|
||||||
createJIT(A.release());
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(B.release());
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
|
||||||
checkAccumulate(ptr);
|
checkAccumulate(ptr);
|
||||||
|
@ -114,7 +114,7 @@ protected:
|
|||||||
TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
|
TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
|
||||||
SKIP_UNSUPPORTED_PLATFORM;
|
SKIP_UNSUPPORTED_PLATFORM;
|
||||||
|
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
|
|
||||||
TheJIT->setObjectCache(nullptr);
|
TheJIT->setObjectCache(nullptr);
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ TEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) {
|
|||||||
// Save a copy of the module pointer before handing it off to MCJIT.
|
// Save a copy of the module pointer before handing it off to MCJIT.
|
||||||
const Module * SavedModulePointer = M.get();
|
const Module * SavedModulePointer = M.get();
|
||||||
|
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
|
|
||||||
TheJIT->setObjectCache(Cache.get());
|
TheJIT->setObjectCache(Cache.get());
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
|
|||||||
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
|
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
|
||||||
|
|
||||||
// Compile this module with an MCJIT engine
|
// Compile this module with an MCJIT engine
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
TheJIT->setObjectCache(Cache.get());
|
TheJIT->setObjectCache(Cache.get());
|
||||||
TheJIT->finalizeObject();
|
TheJIT->finalizeObject();
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
|
|||||||
const Module * SecondModulePointer = M.get();
|
const Module * SecondModulePointer = M.get();
|
||||||
|
|
||||||
// Create a new MCJIT instance to load this module then execute it.
|
// Create a new MCJIT instance to load this module then execute it.
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
TheJIT->setObjectCache(Cache.get());
|
TheJIT->setObjectCache(Cache.get());
|
||||||
compileAndRun();
|
compileAndRun();
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
|
|||||||
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
|
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
|
||||||
|
|
||||||
// Compile this module with an MCJIT engine
|
// Compile this module with an MCJIT engine
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
TheJIT->setObjectCache(Cache.get());
|
TheJIT->setObjectCache(Cache.get());
|
||||||
TheJIT->finalizeObject();
|
TheJIT->finalizeObject();
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
|
|||||||
const Module * SecondModulePointer = M.get();
|
const Module * SecondModulePointer = M.get();
|
||||||
|
|
||||||
// Create a new MCJIT instance to load this module then execute it.
|
// Create a new MCJIT instance to load this module then execute it.
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
TheJIT->setObjectCache(Cache.get());
|
TheJIT->setObjectCache(Cache.get());
|
||||||
|
|
||||||
// Verify that our object cache does not contain the module yet.
|
// Verify that our object cache does not contain the module yet.
|
||||||
|
@ -49,7 +49,7 @@ TEST_F(MCJITTest, global_variable) {
|
|||||||
|
|
||||||
int initialValue = 5;
|
int initialValue = 5;
|
||||||
GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue);
|
GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue);
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
void *globalPtr = TheJIT->getPointerToGlobal(Global);
|
void *globalPtr = TheJIT->getPointerToGlobal(Global);
|
||||||
EXPECT_TRUE(nullptr != globalPtr)
|
EXPECT_TRUE(nullptr != globalPtr)
|
||||||
<< "Unable to get pointer to global value from JIT";
|
<< "Unable to get pointer to global value from JIT";
|
||||||
@ -62,7 +62,7 @@ TEST_F(MCJITTest, add_function) {
|
|||||||
SKIP_UNSUPPORTED_PLATFORM;
|
SKIP_UNSUPPORTED_PLATFORM;
|
||||||
|
|
||||||
Function *F = insertAddFunction(M.get());
|
Function *F = insertAddFunction(M.get());
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
uint64_t addPtr = TheJIT->getFunctionAddress(F->getName().str());
|
uint64_t addPtr = TheJIT->getFunctionAddress(F->getName().str());
|
||||||
EXPECT_TRUE(0 != addPtr)
|
EXPECT_TRUE(0 != addPtr)
|
||||||
<< "Unable to get pointer to function from JIT";
|
<< "Unable to get pointer to function from JIT";
|
||||||
@ -83,7 +83,7 @@ TEST_F(MCJITTest, run_main) {
|
|||||||
|
|
||||||
int rc = 6;
|
int rc = 6;
|
||||||
Function *Main = insertMainFunction(M.get(), 6);
|
Function *Main = insertMainFunction(M.get(), 6);
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(Main->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(Main->getName().str());
|
||||||
EXPECT_TRUE(0 != ptr)
|
EXPECT_TRUE(0 != ptr)
|
||||||
<< "Unable to get pointer to main() from JIT";
|
<< "Unable to get pointer to main() from JIT";
|
||||||
@ -104,7 +104,7 @@ TEST_F(MCJITTest, return_global) {
|
|||||||
Value *ReadGlobal = Builder.CreateLoad(GV);
|
Value *ReadGlobal = Builder.CreateLoad(GV);
|
||||||
endFunctionWithRet(ReturnGlobal, ReadGlobal);
|
endFunctionWithRet(ReturnGlobal, ReadGlobal);
|
||||||
|
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
uint64_t rgvPtr = TheJIT->getFunctionAddress(ReturnGlobal->getName().str());
|
uint64_t rgvPtr = TheJIT->getFunctionAddress(ReturnGlobal->getName().str());
|
||||||
EXPECT_TRUE(0 != rgvPtr);
|
EXPECT_TRUE(0 != rgvPtr);
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ TEST_F(MCJITTest, multiple_functions) {
|
|||||||
Inner = Outer;
|
Inner = Outer;
|
||||||
}
|
}
|
||||||
|
|
||||||
createJIT(M.release());
|
createJIT(std::move(M));
|
||||||
uint64_t ptr = TheJIT->getFunctionAddress(Outer->getName().str());
|
uint64_t ptr = TheJIT->getFunctionAddress(Outer->getName().str());
|
||||||
EXPECT_TRUE(0 != ptr)
|
EXPECT_TRUE(0 != ptr)
|
||||||
<< "Unable to get pointer to outer function from JIT";
|
<< "Unable to get pointer to outer function from JIT";
|
||||||
|
@ -307,13 +307,13 @@ protected:
|
|||||||
UnsupportedEnvironments.push_back(Triple::Cygnus);
|
UnsupportedEnvironments.push_back(Triple::Cygnus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createJIT(Module *M) {
|
void createJIT(std::unique_ptr<Module> M) {
|
||||||
|
|
||||||
// Due to the EngineBuilder constructor, it is required to have a Module
|
// Due to the EngineBuilder constructor, it is required to have a Module
|
||||||
// in order to construct an ExecutionEngine (i.e. MCJIT)
|
// in order to construct an ExecutionEngine (i.e. MCJIT)
|
||||||
assert(M != 0 && "a non-null Module must be provided to create MCJIT");
|
assert(M != 0 && "a non-null Module must be provided to create MCJIT");
|
||||||
|
|
||||||
EngineBuilder EB(M);
|
EngineBuilder EB(std::move(M));
|
||||||
std::string Error;
|
std::string Error;
|
||||||
TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
|
TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
|
||||||
.setUseMCJIT(true) /* can this be folded into the EngineKind enum? */
|
.setUseMCJIT(true) /* can this be folded into the EngineKind enum? */
|
||||||
|
Reference in New Issue
Block a user