mirror of
https://github.com/RPCS3/llvm.git
synced 2026-08-28 05:10:05 -04:00
54d4881c35
This adds two arguments to the main ExecutionSession::lookup method: MatchNonExportedInJD, and MatchNonExported. These control whether and where hidden symbols should be matched when searching a list of JITDylibs. A similar effect could have been achieved by filtering search results, but this would have involved materializing symbol definitions (since materialization is triggered on lookup) only to throw the results away, among other issues. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344467 91177308-0d34-0410-b5e6-96231b3b80d8
217 lines
7.5 KiB
C++
217 lines
7.5 KiB
C++
//===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
|
|
#include "llvm/ExecutionEngine/Orc/OrcError.h"
|
|
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
|
#include "llvm/IR/Mangler.h"
|
|
|
|
namespace {
|
|
|
|
// A SimpleCompiler that owns its TargetMachine.
|
|
class TMOwningSimpleCompiler : public llvm::orc::SimpleCompiler {
|
|
public:
|
|
TMOwningSimpleCompiler(std::unique_ptr<llvm::TargetMachine> TM)
|
|
: llvm::orc::SimpleCompiler(*TM), TM(std::move(TM)) {}
|
|
private:
|
|
// FIXME: shared because std::functions (and thus
|
|
// IRCompileLayer2::CompileFunction) are not moveable.
|
|
std::shared_ptr<llvm::TargetMachine> TM;
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
namespace llvm {
|
|
namespace orc {
|
|
|
|
LLJIT::~LLJIT() {
|
|
if (CompileThreads)
|
|
CompileThreads->wait();
|
|
}
|
|
|
|
Expected<std::unique_ptr<LLJIT>>
|
|
LLJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
|
|
unsigned NumCompileThreads) {
|
|
|
|
if (NumCompileThreads == 0) {
|
|
// If NumCompileThreads == 0 then create a single-threaded LLJIT instance.
|
|
auto TM = JTMB.createTargetMachine();
|
|
if (!TM)
|
|
return TM.takeError();
|
|
return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
|
|
std::move(*TM), std::move(DL)));
|
|
}
|
|
|
|
return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
|
|
std::move(JTMB), std::move(DL),
|
|
NumCompileThreads));
|
|
}
|
|
|
|
Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
|
|
auto InternedName = ES->intern(Name);
|
|
SymbolMap Symbols({{InternedName, Sym}});
|
|
return Main.define(absoluteSymbols(std::move(Symbols)));
|
|
}
|
|
|
|
Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
|
|
assert(TSM && "Can not add null module");
|
|
|
|
if (auto Err = applyDataLayout(*TSM.getModule()))
|
|
return Err;
|
|
|
|
auto K = ES->allocateVModule();
|
|
return CompileLayer.add(JD, K, std::move(TSM));
|
|
}
|
|
|
|
Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
|
|
assert(Obj && "Can not add null object");
|
|
|
|
auto K = ES->allocateVModule();
|
|
return ObjLinkingLayer.add(JD, K, std::move(Obj));
|
|
}
|
|
|
|
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
|
|
StringRef Name) {
|
|
return ES->lookup({&JD}, ES->intern(Name));
|
|
}
|
|
|
|
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
|
|
std::unique_ptr<TargetMachine> TM, DataLayout DL)
|
|
: ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
|
|
ObjLinkingLayer(*this->ES,
|
|
[this](VModuleKey K) { return getMemoryManager(K); }),
|
|
CompileLayer(*this->ES, ObjLinkingLayer,
|
|
TMOwningSimpleCompiler(std::move(TM))),
|
|
CtorRunner(Main), DtorRunner(Main) {}
|
|
|
|
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
|
|
DataLayout DL, unsigned NumCompileThreads)
|
|
: ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
|
|
ObjLinkingLayer(*this->ES,
|
|
[this](VModuleKey K) { return getMemoryManager(K); }),
|
|
CompileLayer(*this->ES, ObjLinkingLayer,
|
|
MultiThreadedSimpleCompiler(std::move(JTMB))),
|
|
CtorRunner(Main), DtorRunner(Main) {
|
|
assert(NumCompileThreads != 0 &&
|
|
"Multithreaded LLJIT instance can not be created with 0 threads");
|
|
|
|
// Move modules to new contexts when they're emitted so that we can compile
|
|
// them in parallel.
|
|
CompileLayer.setCloneToNewContextOnEmit(true);
|
|
|
|
// Create a thread pool to compile on and set the execution session
|
|
// dispatcher to use the thread pool.
|
|
CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads);
|
|
this->ES->setDispatchMaterialization(
|
|
[this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
|
|
// FIXME: Switch to move capture once we have c++14.
|
|
auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
|
|
auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
|
|
CompileThreads->async(std::move(Work));
|
|
});
|
|
}
|
|
|
|
std::unique_ptr<RuntimeDyld::MemoryManager>
|
|
LLJIT::getMemoryManager(VModuleKey K) {
|
|
return llvm::make_unique<SectionMemoryManager>();
|
|
}
|
|
|
|
std::string LLJIT::mangle(StringRef UnmangledName) {
|
|
std::string MangledName;
|
|
{
|
|
raw_string_ostream MangledNameStream(MangledName);
|
|
Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
|
|
}
|
|
return MangledName;
|
|
}
|
|
|
|
Error LLJIT::applyDataLayout(Module &M) {
|
|
if (M.getDataLayout().isDefault())
|
|
M.setDataLayout(DL);
|
|
|
|
if (M.getDataLayout() != DL)
|
|
return make_error<StringError>(
|
|
"Added modules have incompatible data layouts",
|
|
inconvertibleErrorCode());
|
|
|
|
return Error::success();
|
|
}
|
|
|
|
void LLJIT::recordCtorDtors(Module &M) {
|
|
CtorRunner.add(getConstructors(M));
|
|
DtorRunner.add(getDestructors(M));
|
|
}
|
|
|
|
Expected<std::unique_ptr<LLLazyJIT>>
|
|
LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
|
|
unsigned NumCompileThreads) {
|
|
auto ES = llvm::make_unique<ExecutionSession>();
|
|
|
|
const Triple &TT = JTMB.getTargetTriple();
|
|
|
|
auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, 0);
|
|
if (!LCTMgr)
|
|
return LCTMgr.takeError();
|
|
|
|
auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
|
|
if (!ISMBuilder)
|
|
return make_error<StringError>(
|
|
std::string("No indirect stubs manager builder for ") + TT.str(),
|
|
inconvertibleErrorCode());
|
|
|
|
if (NumCompileThreads == 0) {
|
|
auto TM = JTMB.createTargetMachine();
|
|
if (!TM)
|
|
return TM.takeError();
|
|
return std::unique_ptr<LLLazyJIT>(
|
|
new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL),
|
|
std::move(*LCTMgr), std::move(ISMBuilder)));
|
|
}
|
|
|
|
return std::unique_ptr<LLLazyJIT>(new LLLazyJIT(
|
|
std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads,
|
|
std::move(*LCTMgr), std::move(ISMBuilder)));
|
|
}
|
|
|
|
Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
|
|
assert(TSM && "Can not add null module");
|
|
|
|
if (auto Err = applyDataLayout(*TSM.getModule()))
|
|
return Err;
|
|
|
|
recordCtorDtors(*TSM.getModule());
|
|
|
|
auto K = ES->allocateVModule();
|
|
return CODLayer.add(JD, K, std::move(TSM));
|
|
}
|
|
|
|
LLLazyJIT::LLLazyJIT(
|
|
std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
|
|
DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr,
|
|
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
|
|
: LLJIT(std::move(ES), std::move(TM), std::move(DL)),
|
|
LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
|
|
CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
|
|
std::move(ISMBuilder)) {}
|
|
|
|
LLLazyJIT::LLLazyJIT(
|
|
std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
|
|
DataLayout DL, unsigned NumCompileThreads,
|
|
std::unique_ptr<LazyCallThroughManager> LCTMgr,
|
|
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
|
|
: LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads),
|
|
LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
|
|
CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
|
|
std::move(ISMBuilder)) {
|
|
CODLayer.setCloneToNewContextOnEmit(true);
|
|
}
|
|
|
|
} // End namespace orc.
|
|
} // End namespace llvm.
|