#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
+#include "llvm/ExecutionEngine/OrcMCJITReplacement.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
cl::desc("Force interpretation: disable JIT"),
cl::init(false));
- cl::opt<bool> DebugIR(
- "debug-ir", cl::desc("Generate debug information to allow debugging IR."),
- cl::init(false));
+ cl::opt<bool> UseOrcMCJITReplacement("use-orcmcjit",
+ cl::desc("Use the experimental "
+ "OrcMCJITReplacement as a "
+ "drop-in replacement for "
+ "MCJIT."),
+ cl::init(false));
// The MCJIT supports building for a target address space separate from
// the JIT compilation process. Use a forked process and a copying
}
virtual ~LLIObjectCache() {}
- void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) override {
+ void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {
const std::string ModuleID = M->getModuleIdentifier();
std::string CacheName;
if (!getCacheFilename(ModuleID, CacheName))
return;
- std::string errStr;
if (!CacheDir.empty()) { // Create user-defined cache dir.
SmallString<128> dir(CacheName);
sys::path::remove_filename(dir);
sys::fs::create_directories(Twine(dir));
}
- raw_fd_ostream outfile(CacheName.c_str(), errStr, sys::fs::F_None);
- outfile.write(Obj->getBufferStart(), Obj->getBufferSize());
+ std::error_code EC;
+ raw_fd_ostream outfile(CacheName, EC, sys::fs::F_None);
+ outfile.write(Obj.getBufferStart(), Obj.getBufferSize());
outfile.close();
}
- MemoryBuffer* getObject(const Module* M) override {
+ std::unique_ptr<MemoryBuffer> getObject(const Module* M) override {
const std::string ModuleID = M->getModuleIdentifier();
std::string CacheName;
if (!getCacheFilename(ModuleID, CacheName))
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;
}
}
- if (DebugIR) {
- ModulePass *DebugIRPass = createDebugIRPass();
- DebugIRPass->runOnModule(*Mod);
- }
-
std::string ErrorMsg;
- EngineBuilder builder(Mod);
+ EngineBuilder builder(std::move(Owner));
builder.setMArch(MArch);
builder.setMCPU(MCPU);
builder.setMAttrs(MAttrs);
builder.setEngineKind(ForceInterpreter
? EngineKind::Interpreter
: EngineKind::JIT);
+ builder.setUseOrcMCJITReplacement(UseOrcMCJITReplacement);
// If we are supposed to override the target triple, do so now.
if (!TargetTriple.empty())
RTDyldMM = new RemoteMemoryManager();
else
RTDyldMM = new SectionMemoryManager();
- builder.setMCJITMemoryManager(RTDyldMM);
- } else {
- if (RemoteMCJIT) {
- errs() << "error: Remote process execution requires -use-mcjit\n";
- exit(1);
- }
- builder.setJITMemoryManager(ForceInterpreter ? nullptr :
- JITMemoryManager::CreateDefaultMemManager());
+
+ // Deliberately construct a temp std::unique_ptr to pass in. Do not null out
+ // RTDyldMM: We still use it below, even though we don't own it.
+ builder.setMCJITMemoryManager(
+ std::unique_ptr<RTDyldMemoryManager>(RTDyldMM));
+ } else if (RemoteMCJIT) {
+ errs() << "error: Remote process execution does not work with the "
+ "interpreter.\n";
+ exit(1);
}
CodeGenOpt::Level OLvl = CodeGenOpt::Default;
// 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;
CacheName.append(ExtraModules[i]);
XMod->setModuleIdentifier(CacheName);
}
- EE->addModule(XMod);
+ EE->addModule(std::move(XMod));
}
for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) {
- ErrorOr<std::unique_ptr<object::ObjectFile>> Obj =
+ ErrorOr<object::OwningBinary<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ExtraObjects[i]);
if (!Obj) {
Err.print(argv[0], errs());
return 1;
}
- EE->addObjectFile(std::move(Obj.get()));
+ object::OwningBinary<object::ObjectFile> &O = Obj.get();
+ EE->addObjectFile(std::move(O));
}
for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> ArBuf =
+ ErrorOr<std::unique_ptr<MemoryBuffer>> ArBufOrErr =
MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]);
- if (!ArBuf) {
+ if (!ArBufOrErr) {
Err.print(argv[0], errs());
return 1;
}
+ std::unique_ptr<MemoryBuffer> &ArBuf = ArBufOrErr.get();
ErrorOr<std::unique_ptr<object::Archive>> ArOrErr =
- object::Archive::create(std::move(ArBuf.get()));
+ object::Archive::create(ArBuf->getMemBufferRef());
if (std::error_code EC = ArOrErr.getError()) {
errs() << EC.message();
return 1;
}
- EE->addArchive(std::move(ArOrErr.get()));
+ std::unique_ptr<object::Archive> &Ar = ArOrErr.get();
+
+ object::OwningBinary<object::Archive> OB(std::move(Ar), std::move(ArBuf));
+
+ EE->addArchive(std::move(OB));
}
// If the target is Cygwin/MingW and we are generating remote code, we
// If the user specifically requested an argv[0] to pass into the program,
// do it now.
if (!FakeArgv0.empty()) {
- InputFile = FakeArgv0;
+ InputFile = static_cast<std::string>(FakeArgv0);
} else {
// Otherwise, if there is a .bc suffix on the executable strip it off, it
// might confuse the program.
// function later on to make an explicit call, so get the function now.
Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context),
Type::getInt32Ty(Context),
- NULL);
+ nullptr);
// Run static constructors.
if (!ForceInterpreter) {