//Read the BrainF program
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)
delete in;
- addMainFunction(mod);
+ addMainFunction(Mod.get());
//Verify generated code
- if (verifyModule(*mod)) {
+ if (verifyModule(*Mod)) {
errs() << "Error: module failed verification. This shouldn't happen.\n";
abort();
}
InitializeNativeTarget();
outs() << "------- Running JIT -------\n";
- ExecutionEngine *ee = EngineBuilder(mod).create();
+ Module &M = *Mod;
+ ExecutionEngine *ee = EngineBuilder(std::move(Mod)).create();
std::vector<GenericValue> args;
- Function *brainf_func = mod->getFunction("brainf");
+ Function *brainf_func = M.getFunction("brainf");
GenericValue gv = ee->runFunction(brainf_func, args);
} else {
- WriteBitcodeToFile(mod, *out);
+ WriteBitcodeToFile(Mod.get(), *out);
}
//Clean up
if (out != &outs())
delete out;
- delete mod;
llvm_shutdown();
llvm::IRBuilder<> theBuilder(context);
// 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();
// Build engine with JIT
- llvm::EngineBuilder factory(module);
+ llvm::EngineBuilder factory(std::move(Owner));
factory.setEngineKind(llvm::EngineKind::JIT);
factory.setAllocateGVsWithCode(false);
factory.setTargetOptions(Opts);
LLVMContext Context;
// 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:
- Function *FibF = CreateFibFunction(M.get(), Context);
+ Function *FibF = CreateFibFunction(M, Context);
// Now we going to create JIT
std::string errStr;
ExecutionEngine *EE =
- EngineBuilder(M.get())
+ EngineBuilder(std::move(Owner))
.setErrorStr(&errStr)
.setEngineKind(EngineKind::JIT)
.create();
LLVMContext Context;
// 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
// function will have a return type of "int" and take an argument of "int".
builder.CreateRet(Add1CallRes);
// 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() << "\n\nRunning foo: ";
getNextToken();
// 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.
std::string ErrStr;
- TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ TheExecutionEngine =
+ EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
if (!TheExecutionEngine) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
exit(1);
getNextToken();
// 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.
std::string ErrStr;
- TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ TheExecutionEngine =
+ EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
if (!TheExecutionEngine) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
exit(1);
getNextToken();
// 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.
std::string ErrStr;
- TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ TheExecutionEngine =
+ EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
if (!TheExecutionEngine) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
exit(1);
getNextToken();
// 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.
std::string ErrStr;
- TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ TheExecutionEngine =
+ EngineBuilder(std::move(Owner)).setErrorStr(&ErrStr).create();
if (!TheExecutionEngine) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
exit(1);
LLVMContext Context;
// 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* fibF = CreateFibFunction( M );
// 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 << "\n\nRunning foo: " << std::flush;
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/MC/MCCodeGenInfo.h"
class JITEventListener;
class JITMemoryManager;
class MachineCodeInfo;
-class Module;
class MutexGuard;
class ObjectCache;
class RTDyldMemoryManager;
protected:
/// 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.
- SmallVector<Module*, 1> Modules;
+ SmallVector<std::unique_ptr<Module>, 1> Modules;
void setDataLayout(const DataLayout *Val) { DL = Val; }
// libraries, the execution engine implementations set these functions to ctor
// pointers at startup time if they are linked in.
static ExecutionEngine *(*JITCtor)(
- Module *M,
+ std::unique_ptr<Module> M,
std::string *ErrorStr,
JITMemoryManager *JMM,
bool GVsWithCode,
TargetMachine *TM);
static ExecutionEngine *(*MCJITCtor)(
- Module *M,
+ std::unique_ptr<Module> M,
std::string *ErrorStr,
RTDyldMemoryManager *MCJMM,
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
/// pointer is invoked to create it. If this returns null, the JIT will
virtual ~ExecutionEngine();
- /// addModule - 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
- /// destroyed, it destroys the Module as well.
- virtual void addModule(Module *M) {
- Modules.push_back(M);
+ /// Add a Module to the list of modules that we can JIT from.
+ virtual void addModule(std::unique_ptr<Module> M) {
+ Modules.push_back(std::move(M));
}
/// addObjectFile - Add an ObjectFile to the execution engine.
/// \param isDtors - Run the destructors instead of constructors.
virtual void runStaticConstructorsDestructors(bool isDtors);
- /// runStaticConstructorsDestructors - This method is used to execute all of
- /// the static constructors or destructors for a particular module.
+ /// This method is used to execute all of the static constructors or
+ /// destructors for a particular module.
///
/// \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
}
protected:
- explicit ExecutionEngine(Module *M);
+ explicit ExecutionEngine(std::unique_ptr<Module> M);
void emitGlobals();
const static Kind Either = (Kind)(JIT | Interpreter);
}
-/// EngineBuilder - Builder class for ExecutionEngines. Use this by
-/// stack-allocating a builder, chaining the various set* methods, and
-/// terminating it with a .create() call.
+/// Builder class for ExecutionEngines. Use this by stack-allocating a builder,
+/// chaining the various set* methods, and terminating it with a .create()
+/// call.
class EngineBuilder {
private:
- Module *M;
+ std::unique_ptr<Module> M;
EngineKind::Kind WhichEngine;
std::string *ErrorStr;
CodeGenOpt::Level OptLevel;
void InitEngine();
public:
- /// EngineBuilder - Constructor for EngineBuilder. If create() is called and
- /// is successful, the created engine takes ownership of the module.
- EngineBuilder(Module *m) : M(m) {
+ /// Constructor for EngineBuilder.
+ EngineBuilder(std::unique_ptr<Module> M) : M(std::move(M)) {
InitEngine();
}
void ObjectBufferStream::anchor() {}
ExecutionEngine *(*ExecutionEngine::JITCtor)(
- Module *M,
+ std::unique_ptr<Module> M,
std::string *ErrorStr,
JITMemoryManager *JMM,
bool GVsWithCode,
TargetMachine *TM) = nullptr;
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
- Module *M,
+ std::unique_ptr<Module >M,
std::string *ErrorStr,
RTDyldMemoryManager *MCJMM,
TargetMachine *TM) = nullptr;
-ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
+ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
std::string *ErrorStr) =nullptr;
-ExecutionEngine::ExecutionEngine(Module *M)
+ExecutionEngine::ExecutionEngine(std::unique_ptr<Module> M)
: EEState(*this),
LazyFunctionCreator(nullptr) {
CompilingLazily = false;
VerifyModules = false;
#endif
- Modules.push_back(M);
assert(M && "Module is null?");
+ Modules.push_back(std::move(M));
}
ExecutionEngine::~ExecutionEngine() {
clearAllGlobalMappings();
- for (unsigned i = 0, e = Modules.size(); i != e; ++i)
- delete Modules[i];
}
namespace {
}
bool ExecutionEngine::removeModule(Module *M) {
- for(SmallVectorImpl<Module *>::iterator I = Modules.begin(),
- E = Modules.end(); I != E; ++I) {
- Module *Found = *I;
+ for (auto I = Modules.begin(), E = Modules.end(); I != E; ++I) {
+ Module *Found = I->get();
if (Found == M) {
+ I->release();
Modules.erase(I);
clearGlobalMappingsFromModule(M);
return true;
return Array;
}
-void ExecutionEngine::runStaticConstructorsDestructors(Module *module,
+void ExecutionEngine::runStaticConstructorsDestructors(Module &module,
bool isDtors) {
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
// an old-style (llvmgcc3) static ctor with __main linked in and in use. If
void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
// Execute global ctors/dtors for each module in the program.
- for (Module *M : Modules)
- runStaticConstructorsDestructors(M, isDtors);
+ for (std::unique_ptr<Module> &M : Modules)
+ runStaticConstructorsDestructors(*M, isDtors);
}
#ifndef NDEBUG
ExecutionEngine *EE = nullptr;
if (UseMCJIT && ExecutionEngine::MCJITCtor)
- EE = ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM,
- TheTM.release());
+ EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr,
+ MCJMM ? MCJMM : JMM, TheTM.release());
else if (ExecutionEngine::JITCtor)
- EE = ExecutionEngine::JITCtor(M, ErrorStr, JMM,
+ EE = ExecutionEngine::JITCtor(std::move(M), ErrorStr, JMM,
AllocateGVsWithCode, TheTM.release());
if (EE) {
// an interpreter instead.
if (WhichEngine & EngineKind::Interpreter) {
if (ExecutionEngine::InterpCtor)
- return ExecutionEngine::InterpCtor(M, ErrorStr);
+ return ExecutionEngine::InterpCtor(std::move(M), ErrorStr);
if (ErrorStr)
*ErrorStr = "Interpreter has not been linked in.";
return nullptr;
LLVMModuleRef M,
char **OutError) {
std::string Error;
- EngineBuilder builder(unwrap(M));
+ EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
builder.setEngineKind(EngineKind::Either)
.setErrorStr(&Error);
if (ExecutionEngine *EE = builder.create()){
LLVMModuleRef M,
char **OutError) {
std::string Error;
- EngineBuilder builder(unwrap(M));
+ EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
builder.setEngineKind(EngineKind::Interpreter)
.setErrorStr(&Error);
if (ExecutionEngine *Interp = builder.create()) {
unsigned OptLevel,
char **OutError) {
std::string Error;
- EngineBuilder builder(unwrap(M));
+ EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
builder.setEngineKind(EngineKind::JIT)
.setErrorStr(&Error)
.setOptLevel((CodeGenOpt::Level)OptLevel);
targetOptions.EnableFastISel = options.EnableFastISel;
std::string Error;
- EngineBuilder builder(unwrap(M));
+ EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
builder.setEngineKind(EngineKind::JIT)
.setErrorStr(&Error)
.setUseMCJIT(true)
}
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){
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.
if (std::error_code EC = M->materializeAllPermanently()) {
if (ErrStr)
return nullptr;
}
- return new Interpreter(M);
+ return new Interpreter(std::move(M));
}
//===----------------------------------------------------------------------===//
// Interpreter ctor - Initialize stuff
//
-Interpreter::Interpreter(Module *M)
- : ExecutionEngine(M), TD(M) {
-
+Interpreter::Interpreter(std::unique_ptr<Module> M)
+ : ExecutionEngine(std::move(M)), TD(Modules.back().get()) {
+
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
setDataLayout(&TD);
// Initialize the "backend"
std::vector<Function*> AtExitHandlers;
public:
- explicit Interpreter(Module *M);
+ explicit Interpreter(std::unique_ptr<Module> M);
~Interpreter();
/// runAtExitHandlers - Run any functions registered by the program's calls to
static void Register() {
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.
///
extern "C" void LLVMLinkInJIT() {
}
-/// createJIT - This is the factory method for creating a JIT for the current
-/// machine, it does not fall back to the interpreter. This takes ownership
-/// of the module.
-ExecutionEngine *JIT::createJIT(Module *M,
+/// This is the factory method for creating a JIT for the current machine, it
+/// does not fall back to the interpreter.
+ExecutionEngine *JIT::createJIT(std::unique_ptr<Module> M,
std::string *ErrorStr,
JITMemoryManager *JMM,
bool GVsWithCode,
// If the target supports JIT code generation, create the JIT.
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 {
if (ErrorStr)
*ErrorStr = "target does not support JIT code generation";
}
}
-JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
+JIT::JIT(std::unique_ptr<Module> M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *jmm, bool GVsWithCode)
- : ExecutionEngine(M), TM(tm), TJI(tji),
+ : ExecutionEngine(std::move(M)), TM(tm), TJI(tji),
JMM(jmm ? jmm : JITMemoryManager::CreateDefaultMemManager()),
AllocateGVsWithCode(GVsWithCode), isAlreadyCodeGenerating(false) {
setDataLayout(TM.getSubtargetImpl()->getDataLayout());
- jitstate = new JITState(M);
+ Module *Mod = Modules.back().get();
+ jitstate = new JITState(Mod);
// Initialize JCE
JCE = createEmitter(*this, JMM, TM);
// Add target data
MutexGuard locked(lock);
FunctionPassManager &PM = jitstate->getPM();
- M->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
- PM.add(new DataLayoutPass(M));
+ Mod->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
+ PM.add(new DataLayoutPass(Mod));
// Turn the machine code intermediate representation into bytes in memory that
// may be executed.
delete &TM;
}
-/// addModule - Add a new Module to the JIT. If we previously removed the last
-/// Module, we need re-initialize jitstate with a valid Module.
-void JIT::addModule(Module *M) {
+/// Add a new Module to the JIT. If we previously removed the last Module, we
+/// need re-initialize jitstate with a valid Module.
+void JIT::addModule(std::unique_ptr<Module> M) {
MutexGuard locked(lock);
if (Modules.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();
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
// that may be executed.
PM.doInitialization();
}
- ExecutionEngine::addModule(M);
+ ExecutionEngine::addModule(std::move(M));
}
-/// removeModule - If we are removing the last Module, invalidate the jitstate
-/// since the PassManager it contains references a released Module.
+/// If we are removing the last Module, invalidate the jitstate since the
+/// PassManager it contains references a released Module.
bool JIT::removeModule(Module *M) {
bool result = ExecutionEngine::removeModule(M);
}
if (!jitstate && !Modules.empty()) {
- jitstate = new JITState(Modules[0]);
+ jitstate = new JITState(Modules[0].get());
FunctionPassManager &PM = jitstate->getPM();
M->setDataLayout(TM.getSubtargetImpl()->getDataLayout());
BasicBlockAddressMapTy BasicBlockAddressMap;
- JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
+ JIT(std::unique_ptr<Module> M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM, bool AllocateGVsWithCode);
public:
~JIT();
///
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
/// M is found.
///
JITCodeEmitter *getCodeEmitter() const { return JCE; }
- static ExecutionEngine *createJIT(Module *M,
+ static ExecutionEngine *createJIT(std::unique_ptr<Module> M,
std::string *ErrorStr,
JITMemoryManager *JMM,
bool GVsWithCode,
extern "C" void LLVMLinkInMCJIT() {
}
-ExecutionEngine *MCJIT::createJIT(Module *M,
+ExecutionEngine *MCJIT::createJIT(std::unique_ptr<Module> M,
std::string *ErrorStr,
RTDyldMemoryManager *MemMgr,
TargetMachine *TM) {
// FIXME: Don't do this here.
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)
- : ExecutionEngine(m), TM(tm), Ctx(nullptr), MemMgr(this, MM), Dyld(&MemMgr),
- ObjCache(nullptr) {
-
- OwnedModules.addModule(m);
- setDataLayout(TM->getSubtargetImpl()->getDataLayout());
-}
-
-MCJIT::~MCJIT() {
- MutexGuard locked(lock);
+MCJIT::MCJIT(std::unique_ptr<Module> M, TargetMachine *tm,
+ RTDyldMemoryManager *MM)
+ : ExecutionEngine(std::move(M)), TM(tm), Ctx(nullptr), MemMgr(this, MM),
+ Dyld(&MemMgr), ObjCache(nullptr) {
// FIXME: We are managing our modules, so we do not want the base class
// ExecutionEngine to manage them as well. To avoid double destruction
// of the first (and only) module added in ExecutionEngine constructor
// If so, additional functions: addModule, removeModule, FindFunctionNamed,
// runStaticConstructorsDestructors could be moved back to EE as well.
//
+ std::unique_ptr<Module> First = std::move(Modules[0]);
Modules.clear();
+
+ OwnedModules.addModule(std::move(First));
+ setDataLayout(TM->getSubtargetImpl()->getDataLayout());
+}
+
+MCJIT::~MCJIT() {
+ MutexGuard locked(lock);
+
Dyld.deregisterEHFrames();
LoadedObjectList::iterator it, end;
delete TM;
}
-void MCJIT::addModule(Module *M) {
+void MCJIT::addModule(std::unique_ptr<Module> M) {
MutexGuard locked(lock);
- OwnedModules.addModule(M);
+ OwnedModules.addModule(std::move(M));
}
bool MCJIT::removeModule(Module *M) {
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
for (; I != E; ++I) {
- ExecutionEngine::runStaticConstructorsDestructors(*I, isDtors);
+ ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
}
}
// called.
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;
ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }
- void addModule(Module *M) {
- AddedModules.insert(M);
+ void addModule(std::unique_ptr<Module> M) {
+ AddedModules.insert(M.release());
}
bool removeModule(Module *M) {
/// @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 addArchive(std::unique_ptr<object::Archive> O) override;
bool removeModule(Module *M) override;
MCJITCtor = createJIT;
}
- static ExecutionEngine *createJIT(Module *M,
+ static ExecutionEngine *createJIT(std::unique_ptr<Module> M,
std::string *ErrorStr,
RTDyldMemoryManager *MemMgr,
TargetMachine *TM);
Triple TargetTriple(TargetTripleStr);
// Create a new module.
- Module *M = new Module("CygMingHelper", Context);
+ std::unique_ptr<Module> M = make_unique<Module>("CygMingHelper", Context);
M->setTargetTriple(TargetTripleStr);
// Create an empty function named "__main".
if (TargetTriple.isArch64Bit()) {
Result = Function::Create(
TypeBuilder<int64_t(void), false>::get(Context),
- GlobalValue::ExternalLinkage, "__main", M);
+ GlobalValue::ExternalLinkage, "__main", M.get());
} else {
Result = Function::Create(
TypeBuilder<int32_t(void), false>::get(Context),
- GlobalValue::ExternalLinkage, "__main", M);
+ GlobalValue::ExternalLinkage, "__main", M.get());
}
BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);
Builder.SetInsertPoint(BB);
Builder.CreateRet(ReturnVal);
// Add this new module to the ExecutionEngine.
- EE->addModule(M);
+ EE->addModule(std::move(M));
}
// Load the bitcode...
SMDiagnostic Err;
- Module *Mod = ParseIRFile(InputFile, Err, Context);
+ std::unique_ptr<Module> Owner(ParseIRFile(InputFile, Err, Context));
+ Module *Mod = Owner.get();
if (!Mod) {
Err.print(argv[0], errs());
return 1;
}
std::string ErrorMsg;
- EngineBuilder builder(Mod);
+ EngineBuilder builder(std::move(Owner));
builder.setMArch(MArch);
builder.setMCPU(MCPU);
builder.setMAttrs(MAttrs);
// Load any additional modules specified on the command line.
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) {
Err.print(argv[0], errs());
return 1;
}
// 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) {
class ExecutionEngineTest : public testing::Test {
protected:
- ExecutionEngineTest()
- : M(new Module("<main>", getGlobalContext())), Error(""),
- Engine(EngineBuilder(M).setErrorStr(&Error).create()) {
+ ExecutionEngineTest() {
+ auto Owner = make_unique<Module>("<main>", getGlobalContext());
+ M = Owner.get();
+ Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create());
}
virtual void SetUp() {
GlobalValue::ExternalLinkage, nullptr, Name);
}
- Module *const M;
std::string Error;
- const std::unique_ptr<ExecutionEngine> Engine;
+ Module *M; // Owned by ExecutionEngine.
+ std::unique_ptr<ExecutionEngine> Engine;
};
TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
class JITEventListenerTest : public testing::Test {
protected:
- JITEventListenerTest()
- : M(new Module("module", getGlobalContext())),
- EE(EngineBuilder(M)
- .setEngineKind(EngineKind::JIT)
- .create()) {
- }
+ JITEventListenerTest() {
+ auto Owner = make_unique<Module>("module", getGlobalContext());
+ M = Owner.get();
+ EE.reset(EngineBuilder(std::move(Owner))
+ .setEngineKind(EngineKind::JIT)
+ .create());
+ }
Module *M;
- const std::unique_ptr<ExecutionEngine> EE;
+ std::unique_ptr<ExecutionEngine> EE;
};
// Tests on SystemZ disabled as we're running the old JIT
}
virtual void SetUp() {
- M = new Module("<main>", Context);
+ std::unique_ptr<Module> Owner = make_unique<Module>("<main>", Context);
+ M = Owner.get();
RJMM = createMemoryManager();
RJMM->setPoisonMemory(true);
std::string Error;
TargetOptions Options;
- TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
- .setJITMemoryManager(RJMM)
- .setErrorStr(&Error)
- .setTargetOptions(Options).create());
+ TheJIT.reset(EngineBuilder(std::move(Owner))
+ .setEngineKind(EngineKind::JIT)
+ .setJITMemoryManager(RJMM)
+ .setErrorStr(&Error)
+ .setTargetOptions(Options)
+ .create());
ASSERT_TRUE(TheJIT.get() != nullptr) << Error;
}
// stays alive after that.
TEST(JIT, GlobalInFunction) {
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();
// Tell the memory manager to poison freed memory so that accessing freed
// memory is more easily tested.
MemMgr->setPoisonMemory(true);
std::string Error;
- std::unique_ptr<ExecutionEngine> JIT(EngineBuilder(M)
+ std::unique_ptr<ExecutionEngine> JIT(EngineBuilder(std::move(Owner))
.setEngineKind(EngineKind::JIT)
.setErrorStr(&Error)
.setJITMemoryManager(MemMgr)
delete BitcodeBuffer;
return nullptr;
}
- M = ModuleOrErr.get();
+ std::unique_ptr<Module> Owner(ModuleOrErr.get());
+ M = Owner.get();
std::string errMsg;
- ExecutionEngine *TheJIT = EngineBuilder(M)
+ ExecutionEngine *TheJIT = EngineBuilder(std::move(Owner))
.setEngineKind(EngineKind::JIT)
.setErrorStr(&errMsg)
.create();
#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \
&& !defined(__aarch64__)
-bool LoadAssemblyInto(Module *M, const char *assembly) {
+std::unique_ptr<Module> loadAssembly(LLVMContext &Context,
+ const char *Assembly) {
SMDiagnostic Error;
- bool success =
- nullptr != ParseAssemblyString(assembly, M, Error, M->getContext());
+ std::unique_ptr<Module> Ret(
+ ParseAssemblyString(Assembly, nullptr, Error, Context));
std::string errMsg;
raw_string_ostream os(errMsg);
Error.print("", os);
- EXPECT_TRUE(success) << os.str();
- return success;
+ EXPECT_TRUE((bool)Ret) << os.str();
+ return std::move(Ret);
}
-void createModule1(LLVMContext &Context1, Module *&M1, Function *&FooF1) {
- M1 = new Module("test1", Context1);
- LoadAssemblyInto(M1,
+std::unique_ptr<Module> createModule1(LLVMContext &Context1, Function *&FooF1) {
+ std::unique_ptr<Module> Ret = loadAssembly(Context1,
"define i32 @add1(i32 %ArgX1) { "
"entry: "
" %addresult = add i32 1, %ArgX1 "
" %add1 = call i32 @add1(i32 10) "
" ret i32 %add1 "
"} ");
- FooF1 = M1->getFunction("foo1");
+ FooF1 = Ret->getFunction("foo1");
+ return std::move(Ret);
}
-void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
- M2 = new Module("test2", Context2);
- LoadAssemblyInto(M2,
+std::unique_ptr<Module> createModule2(LLVMContext &Context2, Function *&FooF2) {
+ std::unique_ptr<Module> Ret = loadAssembly(Context2,
"define i32 @add2(i32 %ArgX2) { "
"entry: "
" %addresult = add i32 2, %ArgX2 "
" %add2 = call i32 @add2(i32 10) "
" ret i32 %add2 "
"} ");
- FooF2 = M2->getFunction("foo2");
+ FooF2 = Ret->getFunction("foo2");
+ return std::move(Ret);
}
TEST(MultiJitTest, EagerMode) {
LLVMContext Context1;
- Module *M1 = nullptr;
Function *FooF1 = nullptr;
- createModule1(Context1, M1, FooF1);
+ std::unique_ptr<Module> M1 = createModule1(Context1, FooF1);
LLVMContext Context2;
- Module *M2 = nullptr;
Function *FooF2 = nullptr;
- createModule2(Context2, M2, FooF2);
+ std::unique_ptr<Module> M2 = createModule2(Context2, FooF2);
// 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);
- std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(std::move(M2)).create());
EE2->DisableLazyCompilation(true);
// Call the `foo' function with no arguments:
TEST(MultiJitTest, LazyMode) {
LLVMContext Context1;
- Module *M1 = nullptr;
Function *FooF1 = nullptr;
- createModule1(Context1, M1, FooF1);
+ std::unique_ptr<Module> M1 = createModule1(Context1, FooF1);
LLVMContext Context2;
- Module *M2 = nullptr;
Function *FooF2 = nullptr;
- createModule2(Context2, M2, FooF2);
+ std::unique_ptr<Module> M2 = createModule2(Context2, FooF2);
// 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);
- std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(std::move(M2)).create());
EE2->DisableLazyCompilation(false);
// Call the `foo' function with no arguments:
TEST(MultiJitTest, JitPool) {
LLVMContext Context1;
- Module *M1 = nullptr;
Function *FooF1 = nullptr;
- createModule1(Context1, M1, FooF1);
+ std::unique_ptr<Module> M1 = createModule1(Context1, FooF1);
LLVMContext Context2;
- Module *M2 = nullptr;
Function *FooF2 = nullptr;
- createModule2(Context2, M2, FooF2);
+ std::unique_ptr<Module> M2 = createModule2(Context2, FooF2);
// Now we create two JITs
- std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
- std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(std::move(M1)).create());
+ std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(std::move(M2)).create());
Function *F1 = EE1->FindFunctionNamed("foo1");
void *foo1 = EE1->getPointerToFunction(F1);
Function *FA, *FB;
createTwoModuleCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
Function *FA, *FB;
createTwoModuleCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
Function *FA, *FB;
createTwoModuleExternCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
Function *FA, *FB;
createTwoModuleExternCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
createTwoModuleExternCase(A, FA1, B, FB);
FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
FB = startFunction<int32_t(void)>(B.get(), "FB");
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
Function *FA, *FB, *FC;
createThreeModuleCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
checkAdd(ptr);
Function *FA, *FB, *FC;
createThreeModuleCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
Function *FA, *FB, *FC;
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
checkAdd(ptr);
Function *FA, *FB, *FC;
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAccumulate(ptr);
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
checkAccumulate(ptr);
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
checkAccumulate(ptr);
TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
SKIP_UNSUPPORTED_PLATFORM;
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(nullptr);
// Save a copy of the module pointer before handing it off to MCJIT.
const Module * SavedModulePointer = M.get();
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
// Compile this module with an MCJIT engine
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
TheJIT->finalizeObject();
const Module * SecondModulePointer = M.get();
// Create a new MCJIT instance to load this module then execute it.
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
compileAndRun();
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
// Compile this module with an MCJIT engine
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
TheJIT->finalizeObject();
const Module * SecondModulePointer = M.get();
// Create a new MCJIT instance to load this module then execute it.
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
// Verify that our object cache does not contain the module yet.
int initialValue = 5;
GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue);
- createJIT(M.release());
+ createJIT(std::move(M));
void *globalPtr = TheJIT->getPointerToGlobal(Global);
EXPECT_TRUE(nullptr != globalPtr)
<< "Unable to get pointer to global value from JIT";
SKIP_UNSUPPORTED_PLATFORM;
Function *F = insertAddFunction(M.get());
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t addPtr = TheJIT->getFunctionAddress(F->getName().str());
EXPECT_TRUE(0 != addPtr)
<< "Unable to get pointer to function from JIT";
int rc = 6;
Function *Main = insertMainFunction(M.get(), 6);
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t ptr = TheJIT->getFunctionAddress(Main->getName().str());
EXPECT_TRUE(0 != ptr)
<< "Unable to get pointer to main() from JIT";
Value *ReadGlobal = Builder.CreateLoad(GV);
endFunctionWithRet(ReturnGlobal, ReadGlobal);
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t rgvPtr = TheJIT->getFunctionAddress(ReturnGlobal->getName().str());
EXPECT_TRUE(0 != rgvPtr);
Inner = Outer;
}
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t ptr = TheJIT->getFunctionAddress(Outer->getName().str());
EXPECT_TRUE(0 != ptr)
<< "Unable to get pointer to outer function from JIT";
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
// in order to construct an ExecutionEngine (i.e. 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;
TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
.setUseMCJIT(true) /* can this be folded into the EngineKind enum? */