forked from OSchip/llvm-project
172 lines
5.9 KiB
C++
172 lines
5.9 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 llvm {
|
|
namespace orc {
|
|
|
|
Expected<std::unique_ptr<LLJIT>>
|
|
LLJIT::Create(std::unique_ptr<ExecutionSession> ES,
|
|
std::unique_ptr<TargetMachine> TM, DataLayout DL) {
|
|
return std::unique_ptr<LLJIT>(
|
|
new LLJIT(std::move(ES), std::move(TM), std::move(DL)));
|
|
}
|
|
|
|
Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
|
|
auto InternedName = ES->getSymbolStringPool().intern(Name);
|
|
SymbolMap Symbols({{InternedName, Sym}});
|
|
return Main.define(absoluteSymbols(std::move(Symbols)));
|
|
}
|
|
|
|
Error LLJIT::addIRModule(VSO &V, std::unique_ptr<Module> M) {
|
|
assert(M && "Can not add null module");
|
|
|
|
if (auto Err = applyDataLayout(*M))
|
|
return Err;
|
|
|
|
auto K = ES->allocateVModule();
|
|
Resolvers[K] = createResolverFor(V);
|
|
return CompileLayer.add(V, K, std::move(M));
|
|
}
|
|
|
|
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(VSO &V,
|
|
StringRef Name) {
|
|
return llvm::orc::lookup({&V}, ES->getSymbolStringPool().intern(Name));
|
|
}
|
|
|
|
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
|
|
std::unique_ptr<TargetMachine> TM, DataLayout DL)
|
|
: ES(std::move(ES)), Main(this->ES->createVSO("main")), TM(std::move(TM)),
|
|
DL(std::move(DL)),
|
|
ObjLinkingLayer(*this->ES,
|
|
[this](VModuleKey K) { return getRTDyldResources(K); }),
|
|
CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),
|
|
CtorRunner(Main), DtorRunner(Main) {
|
|
VSOLookupOrder[&Main] = VSOList({&Main});
|
|
}
|
|
|
|
std::shared_ptr<SymbolResolver> LLJIT::takeSymbolResolver(VModuleKey K) {
|
|
auto ResolverI = Resolvers.find(K);
|
|
assert(ResolverI != Resolvers.end() && "Missing resolver");
|
|
auto Resolver = std::move(ResolverI->second);
|
|
Resolvers.erase(ResolverI);
|
|
return Resolver;
|
|
}
|
|
|
|
RTDyldObjectLinkingLayer2::Resources LLJIT::getRTDyldResources(VModuleKey K) {
|
|
return orc::RTDyldObjectLinkingLayer2::Resources(
|
|
{llvm::make_unique<SectionMemoryManager>(), takeSymbolResolver(K)});
|
|
}
|
|
|
|
std::string LLJIT::mangle(StringRef UnmangledName) {
|
|
std::string MangledName;
|
|
{
|
|
raw_string_ostream MangledNameStream(MangledName);
|
|
Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
|
|
}
|
|
return MangledName;
|
|
}
|
|
|
|
std::unique_ptr<SymbolResolver> LLJIT::createResolverFor(VSO &V) {
|
|
return createSymbolResolver(
|
|
[&](SymbolFlagsMap &Flags, const SymbolNameSet &Symbols) {
|
|
return V.lookupFlags(Flags, Symbols);
|
|
},
|
|
[&, this](std::shared_ptr<AsynchronousSymbolQuery> Q,
|
|
SymbolNameSet Symbols) {
|
|
assert(VSOLookupOrder.count(&V) && "No VSO lookup order for V");
|
|
SymbolNameSet Unresolved = std::move(Symbols);
|
|
for (auto *LV : VSOLookupOrder[&V])
|
|
Unresolved = LV->lookup(Q, std::move(Unresolved));
|
|
return Unresolved;
|
|
});
|
|
}
|
|
|
|
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(std::unique_ptr<ExecutionSession> ES,
|
|
std::unique_ptr<TargetMachine> TM, DataLayout DL,
|
|
LLVMContext &Ctx) {
|
|
const Triple &TT = TM->getTargetTriple();
|
|
|
|
auto CCMgr = createLocalCompileCallbackManager(TT, *ES, 0);
|
|
if (!CCMgr)
|
|
return make_error<StringError>(
|
|
std::string("No callback manager available for ") + TT.str(),
|
|
inconvertibleErrorCode());
|
|
|
|
auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
|
|
if (!ISMBuilder)
|
|
return make_error<StringError>(
|
|
std::string("No indirect stubs manager builder for ") + TT.str(),
|
|
inconvertibleErrorCode());
|
|
|
|
return std::unique_ptr<LLLazyJIT>(
|
|
new LLLazyJIT(std::move(ES), std::move(TM), std::move(DL), Ctx,
|
|
std::move(CCMgr), std::move(ISMBuilder)));
|
|
}
|
|
|
|
Error LLLazyJIT::addLazyIRModule(VSO &V, std::unique_ptr<Module> M) {
|
|
assert(M && "Can not add null module");
|
|
|
|
if (auto Err = applyDataLayout(*M))
|
|
return Err;
|
|
|
|
makeAllSymbolsExternallyAccessible(*M);
|
|
|
|
recordCtorDtors(*M);
|
|
|
|
auto K = ES->allocateVModule();
|
|
setSymbolResolver(K, createResolverFor(V));
|
|
return CODLayer.add(V, K, std::move(M));
|
|
}
|
|
|
|
LLLazyJIT::LLLazyJIT(
|
|
std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
|
|
DataLayout DL, LLVMContext &Ctx,
|
|
std::unique_ptr<JITCompileCallbackManager> CCMgr,
|
|
std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
|
|
: LLJIT(std::move(ES), std::move(TM), std::move(DL)),
|
|
CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),
|
|
CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder),
|
|
[this](VModuleKey K) { return takeSymbolResolver(K); },
|
|
[this](VModuleKey K, std::shared_ptr<SymbolResolver> R) {
|
|
setSymbolResolver(K, std::move(R));
|
|
},
|
|
[&]() -> LLVMContext & { return Ctx; }) {}
|
|
|
|
void LLLazyJIT::setSymbolResolver(VModuleKey K,
|
|
std::shared_ptr<SymbolResolver> R) {
|
|
assert(!Resolvers.count(K) && "Resolver already present for VModule K");
|
|
Resolvers[K] = std::move(R);
|
|
}
|
|
|
|
} // End namespace orc.
|
|
} // End namespace llvm.
|