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:
Rafael Espindola
2014-08-19 04:04:25 +00:00
parent 4d48c3f2a4
commit 3f4ed32b43
27 changed files with 242 additions and 223 deletions

View File

@ -49,20 +49,20 @@ void ObjectBuffer::anchor() {}
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;
@ -77,14 +77,12 @@ ExecutionEngine::ExecutionEngine(Module *M)
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 {
@ -131,10 +129,10 @@ void ExecutionEngine::addArchive(std::unique_ptr<object::Archive> A) {
}
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;
@ -307,10 +305,10 @@ void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE,
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
@ -348,8 +346,8 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module,
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
@ -474,10 +472,10 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
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) {
@ -490,7 +488,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
// 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;

View File

@ -110,7 +110,7 @@ LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
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()){
@ -125,7 +125,7 @@ LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
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()) {
@ -141,7 +141,7 @@ LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
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);
@ -189,7 +189,7 @@ LLVMBool LLVMCreateMCJITCompilerForModule(
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)
@ -279,7 +279,7 @@ void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
}
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){

View File

@ -30,9 +30,10 @@ static struct RegisterInterp {
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)
@ -41,15 +42,15 @@ ExecutionEngine *Interpreter::create(Module *M, std::string* 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"

View File

@ -94,7 +94,7 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
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
@ -105,10 +105,11 @@ public:
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.
///

View File

@ -69,10 +69,9 @@ static struct RegisterJIT {
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,
@ -84,7 +83,7 @@ ExecutionEngine *JIT::createJIT(Module *M,
// 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";
@ -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)
: 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);
@ -153,8 +153,8 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
// 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.
@ -175,19 +175,19 @@ JIT::~JIT() {
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.
@ -199,11 +199,11 @@ void JIT::addModule(Module *M) {
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);
@ -215,7 +215,7 @@ bool JIT::removeModule(Module *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());

View File

@ -78,7 +78,7 @@ class JIT : public ExecutionEngine {
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();
@ -91,7 +91,7 @@ public:
///
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.
@ -167,7 +167,7 @@ public:
///
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,

View File

@ -43,7 +43,7 @@ static struct RegisterJIT {
extern "C" void LLVMLinkInMCJIT() {
}
ExecutionEngine *MCJIT::createJIT(Module *M,
ExecutionEngine *MCJIT::createJIT(std::unique_ptr<Module> M,
std::string *ErrorStr,
RTDyldMemoryManager *MemMgr,
TargetMachine *TM) {
@ -52,19 +52,14 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
// 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
@ -75,7 +70,16 @@ MCJIT::~MCJIT() {
// 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;
@ -93,9 +97,9 @@ MCJIT::~MCJIT() {
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) {
@ -389,7 +393,7 @@ void MCJIT::freeMachineCodeForFunction(Function *F) {
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
for (; I != E; ++I) {
ExecutionEngine::runStaticConstructorsDestructors(*I, isDtors);
ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
}
}

View File

@ -101,7 +101,8 @@ private:
// 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;
@ -124,8 +125,8 @@ class MCJIT : public ExecutionEngine {
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) {
@ -237,7 +238,7 @@ public:
/// @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;
@ -324,7 +325,7 @@ public:
MCJITCtor = createJIT;
}
static ExecutionEngine *createJIT(Module *M,
static ExecutionEngine *createJIT(std::unique_ptr<Module> M,
std::string *ErrorStr,
RTDyldMemoryManager *MemMgr,
TargetMachine *TM);