You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.207
Former-commit-id: 3b152f462918d427ce18620a2cbe4f8b79650449
This commit is contained in:
parent
8e12397d70
commit
eb85e2fc17
@ -1,16 +0,0 @@
|
||||
add_llvm_library(LLVMOrcJIT
|
||||
ExecutionUtils.cpp
|
||||
IndirectionUtils.cpp
|
||||
NullResolver.cpp
|
||||
OrcABISupport.cpp
|
||||
OrcCBindings.cpp
|
||||
OrcError.cpp
|
||||
OrcMCJITReplacement.cpp
|
||||
RPCUtils.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/Orc
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
@ -1,102 +0,0 @@
|
||||
//===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===//
|
||||
//
|
||||
// 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/ExecutionUtils.h"
|
||||
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End)
|
||||
: InitList(
|
||||
GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr),
|
||||
I((InitList && End) ? InitList->getNumOperands() : 0) {
|
||||
}
|
||||
|
||||
bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const {
|
||||
assert(InitList == Other.InitList && "Incomparable iterators.");
|
||||
return I == Other.I;
|
||||
}
|
||||
|
||||
bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const {
|
||||
return !(*this == Other);
|
||||
}
|
||||
|
||||
CtorDtorIterator& CtorDtorIterator::operator++() {
|
||||
++I;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CtorDtorIterator CtorDtorIterator::operator++(int) {
|
||||
CtorDtorIterator Temp = *this;
|
||||
++I;
|
||||
return Temp;
|
||||
}
|
||||
|
||||
CtorDtorIterator::Element CtorDtorIterator::operator*() const {
|
||||
ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I));
|
||||
assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors");
|
||||
|
||||
Constant *FuncC = CS->getOperand(1);
|
||||
Function *Func = nullptr;
|
||||
|
||||
// Extract function pointer, pulling off any casts.
|
||||
while (FuncC) {
|
||||
if (Function *F = dyn_cast_or_null<Function>(FuncC)) {
|
||||
Func = F;
|
||||
break;
|
||||
} else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
|
||||
if (CE->isCast())
|
||||
FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
|
||||
else
|
||||
break;
|
||||
} else {
|
||||
// This isn't anything we recognize. Bail out with Func left set to null.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
|
||||
Value *Data = CS->getOperand(2);
|
||||
return Element(Priority->getZExtValue(), Func, Data);
|
||||
}
|
||||
|
||||
iterator_range<CtorDtorIterator> getConstructors(const Module &M) {
|
||||
const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors");
|
||||
return make_range(CtorDtorIterator(CtorsList, false),
|
||||
CtorDtorIterator(CtorsList, true));
|
||||
}
|
||||
|
||||
iterator_range<CtorDtorIterator> getDestructors(const Module &M) {
|
||||
const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors");
|
||||
return make_range(CtorDtorIterator(DtorsList, false),
|
||||
CtorDtorIterator(DtorsList, true));
|
||||
}
|
||||
|
||||
void LocalCXXRuntimeOverrides::runDestructors() {
|
||||
auto& CXXDestructorDataPairs = DSOHandleOverride;
|
||||
for (auto &P : CXXDestructorDataPairs)
|
||||
P.first(P.second);
|
||||
CXXDestructorDataPairs.clear();
|
||||
}
|
||||
|
||||
int LocalCXXRuntimeOverrides::CXAAtExitOverride(DestructorPtr Destructor,
|
||||
void *Arg, void *DSOHandle) {
|
||||
auto& CXXDestructorDataPairs =
|
||||
*reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle);
|
||||
CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
@ -1,267 +0,0 @@
|
||||
//===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===//
|
||||
//
|
||||
// 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/IndirectionUtils.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/Transforms/Utils/Cloning.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
void JITCompileCallbackManager::anchor() {}
|
||||
void IndirectStubsManager::anchor() {}
|
||||
|
||||
std::unique_ptr<JITCompileCallbackManager>
|
||||
createLocalCompileCallbackManager(const Triple &T,
|
||||
JITTargetAddress ErrorHandlerAddress) {
|
||||
switch (T.getArch()) {
|
||||
default: return nullptr;
|
||||
|
||||
case Triple::aarch64: {
|
||||
typedef orc::LocalJITCompileCallbackManager<orc::OrcAArch64> CCMgrT;
|
||||
return llvm::make_unique<CCMgrT>(ErrorHandlerAddress);
|
||||
}
|
||||
|
||||
case Triple::x86: {
|
||||
typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT;
|
||||
return llvm::make_unique<CCMgrT>(ErrorHandlerAddress);
|
||||
}
|
||||
|
||||
case Triple::x86_64: {
|
||||
if ( T.getOS() == Triple::OSType::Win32 ) {
|
||||
typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT;
|
||||
return llvm::make_unique<CCMgrT>(ErrorHandlerAddress);
|
||||
} else {
|
||||
typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_SysV> CCMgrT;
|
||||
return llvm::make_unique<CCMgrT>(ErrorHandlerAddress);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::function<std::unique_ptr<IndirectStubsManager>()>
|
||||
createLocalIndirectStubsManagerBuilder(const Triple &T) {
|
||||
switch (T.getArch()) {
|
||||
default: return nullptr;
|
||||
|
||||
case Triple::aarch64:
|
||||
return [](){
|
||||
return llvm::make_unique<
|
||||
orc::LocalIndirectStubsManager<orc::OrcAArch64>>();
|
||||
};
|
||||
|
||||
case Triple::x86:
|
||||
return [](){
|
||||
return llvm::make_unique<
|
||||
orc::LocalIndirectStubsManager<orc::OrcI386>>();
|
||||
};
|
||||
|
||||
case Triple::x86_64:
|
||||
if (T.getOS() == Triple::OSType::Win32) {
|
||||
return [](){
|
||||
return llvm::make_unique<
|
||||
orc::LocalIndirectStubsManager<orc::OrcX86_64_Win32>>();
|
||||
};
|
||||
} else {
|
||||
return [](){
|
||||
return llvm::make_unique<
|
||||
orc::LocalIndirectStubsManager<orc::OrcX86_64_SysV>>();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Constant* createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr) {
|
||||
Constant *AddrIntVal =
|
||||
ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr);
|
||||
Constant *AddrPtrVal =
|
||||
ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
|
||||
PointerType::get(&FT, 0));
|
||||
return AddrPtrVal;
|
||||
}
|
||||
|
||||
GlobalVariable* createImplPointer(PointerType &PT, Module &M,
|
||||
const Twine &Name, Constant *Initializer) {
|
||||
auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
|
||||
Initializer, Name, nullptr,
|
||||
GlobalValue::NotThreadLocal, 0, true);
|
||||
IP->setVisibility(GlobalValue::HiddenVisibility);
|
||||
return IP;
|
||||
}
|
||||
|
||||
void makeStub(Function &F, Value &ImplPointer) {
|
||||
assert(F.isDeclaration() && "Can't turn a definition into a stub.");
|
||||
assert(F.getParent() && "Function isn't in a module.");
|
||||
Module &M = *F.getParent();
|
||||
BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
|
||||
IRBuilder<> Builder(EntryBlock);
|
||||
LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer);
|
||||
std::vector<Value*> CallArgs;
|
||||
for (auto &A : F.args())
|
||||
CallArgs.push_back(&A);
|
||||
CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
|
||||
Call->setTailCall();
|
||||
Call->setAttributes(F.getAttributes());
|
||||
if (F.getReturnType()->isVoidTy())
|
||||
Builder.CreateRetVoid();
|
||||
else
|
||||
Builder.CreateRet(Call);
|
||||
}
|
||||
|
||||
// Utility class for renaming global values and functions during partitioning.
|
||||
class GlobalRenamer {
|
||||
public:
|
||||
|
||||
static bool needsRenaming(const Value &New) {
|
||||
return !New.hasName() || New.getName().startswith("\01L");
|
||||
}
|
||||
|
||||
const std::string& getRename(const Value &Orig) {
|
||||
// See if we have a name for this global.
|
||||
{
|
||||
auto I = Names.find(&Orig);
|
||||
if (I != Names.end())
|
||||
return I->second;
|
||||
}
|
||||
|
||||
// Nope. Create a new one.
|
||||
// FIXME: Use a more robust uniquing scheme. (This may blow up if the user
|
||||
// writes a "__orc_anon[[:digit:]]* method).
|
||||
unsigned ID = Names.size();
|
||||
std::ostringstream NameStream;
|
||||
NameStream << "__orc_anon" << ID++;
|
||||
auto I = Names.insert(std::make_pair(&Orig, NameStream.str()));
|
||||
return I.first->second;
|
||||
}
|
||||
private:
|
||||
DenseMap<const Value*, std::string> Names;
|
||||
};
|
||||
|
||||
static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
|
||||
if (V.hasLocalLinkage()) {
|
||||
if (R.needsRenaming(V))
|
||||
V.setName(R.getRename(V));
|
||||
V.setLinkage(GlobalValue::ExternalLinkage);
|
||||
V.setVisibility(GlobalValue::HiddenVisibility);
|
||||
}
|
||||
V.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
|
||||
assert(!R.needsRenaming(V) && "Invalid global name.");
|
||||
}
|
||||
|
||||
void makeAllSymbolsExternallyAccessible(Module &M) {
|
||||
GlobalRenamer Renamer;
|
||||
|
||||
for (auto &F : M)
|
||||
raiseVisibilityOnValue(F, Renamer);
|
||||
|
||||
for (auto &GV : M.globals())
|
||||
raiseVisibilityOnValue(GV, Renamer);
|
||||
|
||||
for (auto &A : M.aliases())
|
||||
raiseVisibilityOnValue(A, Renamer);
|
||||
}
|
||||
|
||||
Function* cloneFunctionDecl(Module &Dst, const Function &F,
|
||||
ValueToValueMapTy *VMap) {
|
||||
assert(F.getParent() != &Dst && "Can't copy decl over existing function.");
|
||||
Function *NewF =
|
||||
Function::Create(cast<FunctionType>(F.getValueType()),
|
||||
F.getLinkage(), F.getName(), &Dst);
|
||||
NewF->copyAttributesFrom(&F);
|
||||
|
||||
if (VMap) {
|
||||
(*VMap)[&F] = NewF;
|
||||
auto NewArgI = NewF->arg_begin();
|
||||
for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
|
||||
++ArgI, ++NewArgI)
|
||||
(*VMap)[&*ArgI] = &*NewArgI;
|
||||
}
|
||||
|
||||
return NewF;
|
||||
}
|
||||
|
||||
void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap,
|
||||
ValueMaterializer *Materializer,
|
||||
Function *NewF) {
|
||||
assert(!OrigF.isDeclaration() && "Nothing to move");
|
||||
if (!NewF)
|
||||
NewF = cast<Function>(VMap[&OrigF]);
|
||||
else
|
||||
assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
|
||||
assert(NewF && "Function mapping missing from VMap.");
|
||||
assert(NewF->getParent() != OrigF.getParent() &&
|
||||
"moveFunctionBody should only be used to move bodies between "
|
||||
"modules.");
|
||||
|
||||
SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
|
||||
CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
|
||||
"", nullptr, nullptr, Materializer);
|
||||
OrigF.deleteBody();
|
||||
}
|
||||
|
||||
GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
|
||||
ValueToValueMapTy *VMap) {
|
||||
assert(GV.getParent() != &Dst && "Can't copy decl over existing global var.");
|
||||
GlobalVariable *NewGV = new GlobalVariable(
|
||||
Dst, GV.getValueType(), GV.isConstant(),
|
||||
GV.getLinkage(), nullptr, GV.getName(), nullptr,
|
||||
GV.getThreadLocalMode(), GV.getType()->getAddressSpace());
|
||||
NewGV->copyAttributesFrom(&GV);
|
||||
if (VMap)
|
||||
(*VMap)[&GV] = NewGV;
|
||||
return NewGV;
|
||||
}
|
||||
|
||||
void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
|
||||
ValueToValueMapTy &VMap,
|
||||
ValueMaterializer *Materializer,
|
||||
GlobalVariable *NewGV) {
|
||||
assert(OrigGV.hasInitializer() && "Nothing to move");
|
||||
if (!NewGV)
|
||||
NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
|
||||
else
|
||||
assert(VMap[&OrigGV] == NewGV &&
|
||||
"Incorrect global variable mapping in VMap.");
|
||||
assert(NewGV->getParent() != OrigGV.getParent() &&
|
||||
"moveGlobalVariable should only be used to move initializers between "
|
||||
"modules");
|
||||
|
||||
NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
|
||||
nullptr, Materializer));
|
||||
}
|
||||
|
||||
GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA,
|
||||
ValueToValueMapTy &VMap) {
|
||||
assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
|
||||
auto *NewA = GlobalAlias::create(OrigA.getValueType(),
|
||||
OrigA.getType()->getPointerAddressSpace(),
|
||||
OrigA.getLinkage(), OrigA.getName(), &Dst);
|
||||
NewA->copyAttributesFrom(&OrigA);
|
||||
VMap[&OrigA] = NewA;
|
||||
return NewA;
|
||||
}
|
||||
|
||||
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
|
||||
ValueToValueMapTy &VMap) {
|
||||
auto *MFs = Src.getModuleFlagsMetadata();
|
||||
if (!MFs)
|
||||
return;
|
||||
for (auto *MF : MFs->operands())
|
||||
Dst.addModuleFlag(MapMetadata(MF, VMap));
|
||||
}
|
||||
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
@ -1,22 +0,0 @@
|
||||
;===- ./lib/ExecutionEngine/MCJIT/LLVMBuild.txt ----------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = OrcJIT
|
||||
parent = ExecutionEngine
|
||||
required_libraries = Core ExecutionEngine Object RuntimeDyld Support TransformUtils
|
@ -1,26 +0,0 @@
|
||||
//===---------- NullResolver.cpp - Reject symbol lookup requests ----------===//
|
||||
//
|
||||
// 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/NullResolver.h"
|
||||
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
JITSymbol NullResolver::findSymbol(const std::string &Name) {
|
||||
llvm_unreachable("Unexpected cross-object symbol reference");
|
||||
}
|
||||
|
||||
JITSymbol NullResolver::findSymbolInLogicalDylib(const std::string &Name) {
|
||||
llvm_unreachable("Unexpected cross-object symbol reference");
|
||||
}
|
||||
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
File diff suppressed because it is too large
Load Diff
@ -1,128 +0,0 @@
|
||||
//===----------- OrcCBindings.cpp - C bindings for the Orc APIs -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OrcCBindingsStack.h"
|
||||
#include "llvm-c/OrcBindings.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod) {
|
||||
return wrap(new std::shared_ptr<Module>(unwrap(Mod)));
|
||||
}
|
||||
|
||||
void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod) {
|
||||
delete unwrap(SharedMod);
|
||||
}
|
||||
|
||||
LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {
|
||||
TargetMachine *TM2(unwrap(TM));
|
||||
|
||||
Triple T(TM2->getTargetTriple());
|
||||
|
||||
auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0);
|
||||
auto IndirectStubsMgrBuilder =
|
||||
orc::createLocalIndirectStubsManagerBuilder(T);
|
||||
|
||||
OrcCBindingsStack *JITStack = new OrcCBindingsStack(
|
||||
*TM2, std::move(CompileCallbackMgr), IndirectStubsMgrBuilder);
|
||||
|
||||
return wrap(JITStack);
|
||||
}
|
||||
|
||||
const char *LLVMOrcGetErrorMsg(LLVMOrcJITStackRef JITStack) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
return J.getErrorMessage().c_str();
|
||||
}
|
||||
|
||||
void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName,
|
||||
const char *SymbolName) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
std::string Mangled = J.mangle(SymbolName);
|
||||
*MangledName = new char[Mangled.size() + 1];
|
||||
strcpy(*MangledName, Mangled.c_str());
|
||||
}
|
||||
|
||||
void LLVMOrcDisposeMangledSymbol(char *MangledName) { delete[] MangledName; }
|
||||
|
||||
LLVMOrcErrorCode
|
||||
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcTargetAddress *RetAddr,
|
||||
LLVMOrcLazyCompileCallbackFn Callback,
|
||||
void *CallbackCtx) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
return J.createLazyCompileCallback(*RetAddr, Callback, CallbackCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack,
|
||||
const char *StubName,
|
||||
LLVMOrcTargetAddress InitAddr) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
return J.createIndirectStub(StubName, InitAddr);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
|
||||
const char *StubName,
|
||||
LLVMOrcTargetAddress NewAddr) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
return J.setIndirectStubPointer(StubName, NewAddr);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode
|
||||
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcModuleHandle *RetHandle,
|
||||
LLVMSharedModuleRef Mod,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
std::shared_ptr<Module> *M(unwrap(Mod));
|
||||
return J.addIRModuleEager(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode
|
||||
LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcModuleHandle *RetHandle,
|
||||
LLVMSharedModuleRef Mod,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
std::shared_ptr<Module> *M(unwrap(Mod));
|
||||
return J.addIRModuleLazy(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode
|
||||
LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcModuleHandle *RetHandle,
|
||||
LLVMMemoryBufferRef Obj,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
std::unique_ptr<MemoryBuffer> O(unwrap(Obj));
|
||||
return J.addObject(*RetHandle, std::move(O), SymbolResolver,
|
||||
SymbolResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcModuleHandle H) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
return J.removeModule(H);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcTargetAddress *RetAddr,
|
||||
const char *SymbolName) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
return J.findSymbolAddress(*RetAddr, SymbolName, true);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) {
|
||||
auto *J = unwrap(JITStack);
|
||||
auto Err = J->shutdown();
|
||||
delete J;
|
||||
return Err;
|
||||
}
|
@ -1,409 +0,0 @@
|
||||
//===- OrcCBindingsStack.h - Orc JIT stack for C bindings -----*- C++ -*---===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||
#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||
|
||||
#include "llvm-c/OrcBindings.h"
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class OrcCBindingsStack;
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
|
||||
LLVMSharedModuleRef)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
class GenericHandle {
|
||||
public:
|
||||
virtual ~GenericHandle() = default;
|
||||
|
||||
virtual JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) = 0;
|
||||
virtual Error removeModule() = 0;
|
||||
};
|
||||
|
||||
template <typename LayerT> class GenericHandleImpl : public GenericHandle {
|
||||
public:
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle)
|
||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||
|
||||
JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) override {
|
||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
Error removeModule() override { return Layer.removeModule(Handle); }
|
||||
|
||||
private:
|
||||
LayerT &Layer;
|
||||
typename LayerT::ModuleHandleT Handle;
|
||||
};
|
||||
|
||||
template <>
|
||||
class GenericHandleImpl<orc::RTDyldObjectLinkingLayer>
|
||||
: public GenericHandle {
|
||||
private:
|
||||
using LayerT = orc::RTDyldObjectLinkingLayer;
|
||||
public:
|
||||
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
|
||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||
|
||||
JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) override {
|
||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
Error removeModule() override { return Layer.removeObject(Handle); }
|
||||
|
||||
private:
|
||||
LayerT &Layer;
|
||||
typename LayerT::ObjHandleT Handle;
|
||||
};
|
||||
|
||||
|
||||
template <typename LayerT, typename HandleT>
|
||||
std::unique_ptr<GenericHandleImpl<LayerT>>
|
||||
createGenericHandle(LayerT &Layer, HandleT Handle) {
|
||||
return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
|
||||
std::move(Handle));
|
||||
}
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
class OrcCBindingsStack {
|
||||
public:
|
||||
|
||||
using CompileCallbackMgr = orc::JITCompileCallbackManager;
|
||||
using ObjLayerT = orc::RTDyldObjectLinkingLayer;
|
||||
using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
|
||||
using CODLayerT =
|
||||
orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
|
||||
|
||||
using CallbackManagerBuilder =
|
||||
std::function<std::unique_ptr<CompileCallbackMgr>()>;
|
||||
|
||||
using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
|
||||
|
||||
private:
|
||||
|
||||
using OwningObject = object::OwningBinary<object::ObjectFile>;
|
||||
|
||||
public:
|
||||
using ModuleHandleT = unsigned;
|
||||
|
||||
OrcCBindingsStack(TargetMachine &TM,
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr,
|
||||
IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
|
||||
: DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
|
||||
CCMgr(std::move(CCMgr)),
|
||||
ObjectLayer(
|
||||
[]() {
|
||||
return std::make_shared<SectionMemoryManager>();
|
||||
}),
|
||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
|
||||
CODLayer(CompileLayer,
|
||||
[](Function &F) { return std::set<Function *>({&F}); },
|
||||
*this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
|
||||
CXXRuntimeOverrides(
|
||||
[this](const std::string &S) { return mangle(S); }) {}
|
||||
|
||||
LLVMOrcErrorCode shutdown() {
|
||||
// Run any destructors registered with __cxa_atexit.
|
||||
CXXRuntimeOverrides.runDestructors();
|
||||
// Run any IR destructors.
|
||||
for (auto &DtorRunner : IRStaticDestructorRunners)
|
||||
if (auto Err = DtorRunner.runViaLayer(*this))
|
||||
return mapError(std::move(Err));
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
std::string mangle(StringRef Name) {
|
||||
std::string MangledName;
|
||||
{
|
||||
raw_string_ostream MangledNameStream(MangledName);
|
||||
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
|
||||
}
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
template <typename PtrTy>
|
||||
static PtrTy fromTargetAddress(JITTargetAddress Addr) {
|
||||
return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
|
||||
}
|
||||
|
||||
|
||||
LLVMOrcErrorCode
|
||||
createLazyCompileCallback(JITTargetAddress &RetAddr,
|
||||
LLVMOrcLazyCompileCallbackFn Callback,
|
||||
void *CallbackCtx) {
|
||||
if (auto CCInfoOrErr = CCMgr->getCompileCallback()) {
|
||||
auto &CCInfo = *CCInfoOrErr;
|
||||
CCInfo.setCompileAction([=]() -> JITTargetAddress {
|
||||
return Callback(wrap(this), CallbackCtx);
|
||||
});
|
||||
RetAddr = CCInfo.getAddress();
|
||||
return LLVMOrcErrSuccess;
|
||||
} else
|
||||
return mapError(CCInfoOrErr.takeError());
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode createIndirectStub(StringRef StubName,
|
||||
JITTargetAddress Addr) {
|
||||
return mapError(
|
||||
IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported));
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode setIndirectStubPointer(StringRef Name,
|
||||
JITTargetAddress Addr) {
|
||||
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
|
||||
}
|
||||
|
||||
std::shared_ptr<JITSymbolResolver>
|
||||
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return orc::createLambdaResolver(
|
||||
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name)
|
||||
-> JITSymbol {
|
||||
// Search order:
|
||||
// 1. JIT'd symbols.
|
||||
// 2. Runtime overrides.
|
||||
// 3. External resolver (if present).
|
||||
|
||||
if (auto Sym = CODLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return Sym.takeError();
|
||||
|
||||
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
|
||||
return Sym;
|
||||
|
||||
if (ExternalResolver)
|
||||
return JITSymbol(
|
||||
ExternalResolver(Name.c_str(), ExternalResolverCtx),
|
||||
JITSymbolFlags::Exported);
|
||||
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) -> JITSymbol {
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename LayerT>
|
||||
LLVMOrcErrorCode
|
||||
addIRModule(ModuleHandleT &RetHandle, LayerT &Layer,
|
||||
std::shared_ptr<Module> M,
|
||||
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
|
||||
// Attach a data-layout if one isn't already present.
|
||||
if (M->getDataLayout().isDefault())
|
||||
M->setDataLayout(DL);
|
||||
|
||||
// Record the static constructors and destructors. We have to do this before
|
||||
// we hand over ownership of the module to the JIT.
|
||||
std::vector<std::string> CtorNames, DtorNames;
|
||||
for (auto Ctor : orc::getConstructors(*M))
|
||||
CtorNames.push_back(mangle(Ctor.Func->getName()));
|
||||
for (auto Dtor : orc::getDestructors(*M))
|
||||
DtorNames.push_back(mangle(Dtor.Func->getName()));
|
||||
|
||||
// Create the resolver.
|
||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||
|
||||
// Add the module to the JIT.
|
||||
ModuleHandleT H;
|
||||
if (auto LHOrErr = Layer.addModule(std::move(M), std::move(Resolver)))
|
||||
H = createHandle(Layer, *LHOrErr);
|
||||
else
|
||||
return mapError(LHOrErr.takeError());
|
||||
|
||||
// Run the static constructors, and save the static destructor runner for
|
||||
// execution when the JIT is torn down.
|
||||
orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
|
||||
if (auto Err = CtorRunner.runViaLayer(*this))
|
||||
return mapError(std::move(Err));
|
||||
|
||||
IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
|
||||
|
||||
RetHandle = H;
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode addIRModuleEager(ModuleHandleT &RetHandle,
|
||||
std::shared_ptr<Module> M,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(RetHandle, CompileLayer, std::move(M),
|
||||
llvm::make_unique<SectionMemoryManager>(),
|
||||
std::move(ExternalResolver), ExternalResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode addIRModuleLazy(ModuleHandleT &RetHandle,
|
||||
std::shared_ptr<Module> M,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(RetHandle, CODLayer, std::move(M),
|
||||
llvm::make_unique<SectionMemoryManager>(),
|
||||
std::move(ExternalResolver), ExternalResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode removeModule(ModuleHandleT H) {
|
||||
if (auto Err = GenericHandles[H]->removeModule())
|
||||
return mapError(std::move(Err));
|
||||
GenericHandles[H] = nullptr;
|
||||
FreeHandleIndexes.push_back(H);
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle,
|
||||
std::unique_ptr<MemoryBuffer> ObjBuffer,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
if (auto ObjOrErr =
|
||||
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())) {
|
||||
auto &Obj = *ObjOrErr;
|
||||
auto OwningObj =
|
||||
std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
|
||||
|
||||
// Create the resolver.
|
||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||
|
||||
ModuleHandleT H;
|
||||
if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
|
||||
std::move(Resolver)))
|
||||
H = createHandle(ObjectLayer, *HOrErr);
|
||||
else
|
||||
return mapError(HOrErr.takeError());
|
||||
|
||||
RetHandle = H;
|
||||
|
||||
return LLVMOrcErrSuccess;
|
||||
} else
|
||||
return mapError(ObjOrErr.takeError());
|
||||
}
|
||||
|
||||
JITSymbol findSymbol(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
|
||||
return Sym;
|
||||
return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode findSymbolAddress(JITTargetAddress &RetAddr,
|
||||
const std::string &Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
RetAddr = 0;
|
||||
if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) {
|
||||
// Successful lookup, non-null symbol:
|
||||
if (auto AddrOrErr = Sym.getAddress()) {
|
||||
RetAddr = *AddrOrErr;
|
||||
return LLVMOrcErrSuccess;
|
||||
} else
|
||||
return mapError(AddrOrErr.takeError());
|
||||
} else if (auto Err = Sym.takeError()) {
|
||||
// Lookup failure - report error.
|
||||
return mapError(std::move(Err));
|
||||
}
|
||||
// Otherwise we had a successful lookup but got a null result. We already
|
||||
// set RetAddr to '0' above, so just return success.
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
const std::string &getErrorMessage() const { return ErrMsg; }
|
||||
|
||||
private:
|
||||
template <typename LayerT, typename HandleT>
|
||||
unsigned createHandle(LayerT &Layer, HandleT Handle) {
|
||||
unsigned NewHandle;
|
||||
if (!FreeHandleIndexes.empty()) {
|
||||
NewHandle = FreeHandleIndexes.back();
|
||||
FreeHandleIndexes.pop_back();
|
||||
GenericHandles[NewHandle] =
|
||||
detail::createGenericHandle(Layer, std::move(Handle));
|
||||
return NewHandle;
|
||||
} else {
|
||||
NewHandle = GenericHandles.size();
|
||||
GenericHandles.push_back(
|
||||
detail::createGenericHandle(Layer, std::move(Handle)));
|
||||
}
|
||||
return NewHandle;
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode mapError(Error Err) {
|
||||
LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
|
||||
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
|
||||
// Handler of last resort.
|
||||
Result = LLVMOrcErrGeneric;
|
||||
ErrMsg = "";
|
||||
raw_string_ostream ErrStream(ErrMsg);
|
||||
EIB.log(ErrStream);
|
||||
});
|
||||
return Result;
|
||||
}
|
||||
|
||||
DataLayout DL;
|
||||
SectionMemoryManager CCMgrMemMgr;
|
||||
|
||||
std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
|
||||
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr;
|
||||
ObjLayerT ObjectLayer;
|
||||
CompileLayerT CompileLayer;
|
||||
CODLayerT CODLayer;
|
||||
|
||||
std::vector<std::unique_ptr<detail::GenericHandle>> GenericHandles;
|
||||
std::vector<unsigned> FreeHandleIndexes;
|
||||
|
||||
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
|
||||
std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
|
||||
std::string ErrMsg;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
@ -1,95 +0,0 @@
|
||||
//===---------------- OrcError.cpp - Error codes for ORC ------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Error codes for ORC.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/OrcError.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::orc;
|
||||
|
||||
namespace {
|
||||
|
||||
// FIXME: This class is only here to support the transition to llvm::Error. It
|
||||
// will be removed once this transition is complete. Clients should prefer to
|
||||
// deal with the Error value directly, rather than converting to error_code.
|
||||
class OrcErrorCategory : public std::error_category {
|
||||
public:
|
||||
const char *name() const noexcept override { return "orc"; }
|
||||
|
||||
std::string message(int condition) const override {
|
||||
switch (static_cast<OrcErrorCode>(condition)) {
|
||||
case OrcErrorCode::RemoteAllocatorDoesNotExist:
|
||||
return "Remote allocator does not exist";
|
||||
case OrcErrorCode::RemoteAllocatorIdAlreadyInUse:
|
||||
return "Remote allocator Id already in use";
|
||||
case OrcErrorCode::RemoteMProtectAddrUnrecognized:
|
||||
return "Remote mprotect call references unallocated memory";
|
||||
case OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist:
|
||||
return "Remote indirect stubs owner does not exist";
|
||||
case OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse:
|
||||
return "Remote indirect stubs owner Id already in use";
|
||||
case OrcErrorCode::RPCConnectionClosed:
|
||||
return "RPC connection closed";
|
||||
case OrcErrorCode::RPCCouldNotNegotiateFunction:
|
||||
return "Could not negotiate RPC function";
|
||||
case OrcErrorCode::RPCResponseAbandoned:
|
||||
return "RPC response abandoned";
|
||||
case OrcErrorCode::JITSymbolNotFound:
|
||||
return "JIT symbol not found";
|
||||
case OrcErrorCode::UnexpectedRPCCall:
|
||||
return "Unexpected RPC call";
|
||||
case OrcErrorCode::UnexpectedRPCResponse:
|
||||
return "Unexpected RPC response";
|
||||
case OrcErrorCode::UnknownErrorCodeFromRemote:
|
||||
return "Unknown error returned from remote RPC function "
|
||||
"(Use StringError to get error message)";
|
||||
case OrcErrorCode::UnknownResourceHandle:
|
||||
return "Unknown resource handle";
|
||||
}
|
||||
llvm_unreachable("Unhandled error code");
|
||||
}
|
||||
};
|
||||
|
||||
static ManagedStatic<OrcErrorCategory> OrcErrCat;
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
char JITSymbolNotFound::ID = 0;
|
||||
|
||||
std::error_code orcError(OrcErrorCode ErrCode) {
|
||||
typedef std::underlying_type<OrcErrorCode>::type UT;
|
||||
return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat);
|
||||
}
|
||||
|
||||
JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName)
|
||||
: SymbolName(std::move(SymbolName)) {}
|
||||
|
||||
std::error_code JITSymbolNotFound::convertToErrorCode() const {
|
||||
typedef std::underlying_type<OrcErrorCode>::type UT;
|
||||
return std::error_code(static_cast<UT>(OrcErrorCode::JITSymbolNotFound),
|
||||
*OrcErrCat);
|
||||
}
|
||||
|
||||
void JITSymbolNotFound::log(raw_ostream &OS) const {
|
||||
OS << "Could not find symbol '" << SymbolName << "'";
|
||||
}
|
||||
|
||||
const std::string &JITSymbolNotFound::getSymbolName() const {
|
||||
return SymbolName;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
//===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OrcMCJITReplacement.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
|
||||
namespace {
|
||||
|
||||
static struct RegisterJIT {
|
||||
RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
|
||||
} JITRegistrator;
|
||||
|
||||
}
|
||||
|
||||
extern "C" void LLVMLinkInOrcMCJITReplacement() {}
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
GenericValue
|
||||
OrcMCJITReplacement::runFunction(Function *F,
|
||||
ArrayRef<GenericValue> ArgValues) {
|
||||
assert(F && "Function *F was null at entry to run()");
|
||||
|
||||
void *FPtr = getPointerToFunction(F);
|
||||
assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
|
||||
FunctionType *FTy = F->getFunctionType();
|
||||
Type *RetTy = FTy->getReturnType();
|
||||
|
||||
assert((FTy->getNumParams() == ArgValues.size() ||
|
||||
(FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
|
||||
"Wrong number of arguments passed into function!");
|
||||
assert(FTy->getNumParams() == ArgValues.size() &&
|
||||
"This doesn't support passing arguments through varargs (yet)!");
|
||||
|
||||
// Handle some common cases first. These cases correspond to common `main'
|
||||
// prototypes.
|
||||
if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
|
||||
switch (ArgValues.size()) {
|
||||
case 3:
|
||||
if (FTy->getParamType(0)->isIntegerTy(32) &&
|
||||
FTy->getParamType(1)->isPointerTy() &&
|
||||
FTy->getParamType(2)->isPointerTy()) {
|
||||
int (*PF)(int, char **, const char **) =
|
||||
(int (*)(int, char **, const char **))(intptr_t)FPtr;
|
||||
|
||||
// Call the function.
|
||||
GenericValue rv;
|
||||
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
|
||||
(char **)GVTOP(ArgValues[1]),
|
||||
(const char **)GVTOP(ArgValues[2])));
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (FTy->getParamType(0)->isIntegerTy(32) &&
|
||||
FTy->getParamType(1)->isPointerTy()) {
|
||||
int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
|
||||
|
||||
// Call the function.
|
||||
GenericValue rv;
|
||||
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
|
||||
(char **)GVTOP(ArgValues[1])));
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
|
||||
GenericValue rv;
|
||||
int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
|
||||
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle cases where no arguments are passed first.
|
||||
if (ArgValues.empty()) {
|
||||
GenericValue rv;
|
||||
switch (RetTy->getTypeID()) {
|
||||
default:
|
||||
llvm_unreachable("Unknown return type for function call!");
|
||||
case Type::IntegerTyID: {
|
||||
unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
|
||||
if (BitWidth == 1)
|
||||
rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
|
||||
else if (BitWidth <= 8)
|
||||
rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
|
||||
else if (BitWidth <= 16)
|
||||
rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
|
||||
else if (BitWidth <= 32)
|
||||
rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
|
||||
else if (BitWidth <= 64)
|
||||
rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
|
||||
else
|
||||
llvm_unreachable("Integer types > 64 bits not supported");
|
||||
return rv;
|
||||
}
|
||||
case Type::VoidTyID:
|
||||
rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
|
||||
return rv;
|
||||
case Type::FloatTyID:
|
||||
rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
|
||||
return rv;
|
||||
case Type::DoubleTyID:
|
||||
rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
|
||||
return rv;
|
||||
case Type::X86_FP80TyID:
|
||||
case Type::FP128TyID:
|
||||
case Type::PPC_FP128TyID:
|
||||
llvm_unreachable("long double not supported yet");
|
||||
case Type::PointerTyID:
|
||||
return PTOGV(((void *(*)())(intptr_t)FPtr)());
|
||||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("Full-featured argument passing not supported yet!");
|
||||
}
|
||||
|
||||
void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) {
|
||||
for (auto &M : LocalModules)
|
||||
ExecutionEngine::runStaticConstructorsDestructors(*M, isDtors);
|
||||
}
|
||||
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
@ -1,418 +0,0 @@
|
||||
//===- OrcMCJITReplacement.h - Orc based MCJIT replacement ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Orc based MCJIT replacement.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
|
||||
#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ObjectCache;
|
||||
|
||||
namespace orc {
|
||||
|
||||
class OrcMCJITReplacement : public ExecutionEngine {
|
||||
// OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
|
||||
// Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
|
||||
// expecting - see finalizeMemory.
|
||||
class MCJITReplacementMemMgr : public MCJITMemoryManager {
|
||||
public:
|
||||
MCJITReplacementMemMgr(OrcMCJITReplacement &M,
|
||||
std::shared_ptr<MCJITMemoryManager> ClientMM)
|
||||
: M(M), ClientMM(std::move(ClientMM)) {}
|
||||
|
||||
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID,
|
||||
StringRef SectionName) override {
|
||||
uint8_t *Addr =
|
||||
ClientMM->allocateCodeSection(Size, Alignment, SectionID,
|
||||
SectionName);
|
||||
M.SectionsAllocatedSinceLastLoad.insert(Addr);
|
||||
return Addr;
|
||||
}
|
||||
|
||||
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID, StringRef SectionName,
|
||||
bool IsReadOnly) override {
|
||||
uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
|
||||
SectionName, IsReadOnly);
|
||||
M.SectionsAllocatedSinceLastLoad.insert(Addr);
|
||||
return Addr;
|
||||
}
|
||||
|
||||
void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
|
||||
uintptr_t RODataSize, uint32_t RODataAlign,
|
||||
uintptr_t RWDataSize,
|
||||
uint32_t RWDataAlign) override {
|
||||
return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign,
|
||||
RODataSize, RODataAlign,
|
||||
RWDataSize, RWDataAlign);
|
||||
}
|
||||
|
||||
bool needsToReserveAllocationSpace() override {
|
||||
return ClientMM->needsToReserveAllocationSpace();
|
||||
}
|
||||
|
||||
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
|
||||
size_t Size) override {
|
||||
return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
|
||||
}
|
||||
|
||||
void deregisterEHFrames() override {
|
||||
return ClientMM->deregisterEHFrames();
|
||||
}
|
||||
|
||||
void notifyObjectLoaded(RuntimeDyld &RTDyld,
|
||||
const object::ObjectFile &O) override {
|
||||
return ClientMM->notifyObjectLoaded(RTDyld, O);
|
||||
}
|
||||
|
||||
void notifyObjectLoaded(ExecutionEngine *EE,
|
||||
const object::ObjectFile &O) override {
|
||||
return ClientMM->notifyObjectLoaded(EE, O);
|
||||
}
|
||||
|
||||
bool finalizeMemory(std::string *ErrMsg = nullptr) override {
|
||||
// Each set of objects loaded will be finalized exactly once, but since
|
||||
// symbol lookup during relocation may recursively trigger the
|
||||
// loading/relocation of other modules, and since we're forwarding all
|
||||
// finalizeMemory calls to a single underlying memory manager, we need to
|
||||
// defer forwarding the call on until all necessary objects have been
|
||||
// loaded. Otherwise, during the relocation of a leaf object, we will end
|
||||
// up finalizing memory, causing a crash further up the stack when we
|
||||
// attempt to apply relocations to finalized memory.
|
||||
// To avoid finalizing too early, look at how many objects have been
|
||||
// loaded but not yet finalized. This is a bit of a hack that relies on
|
||||
// the fact that we're lazily emitting object files: The only way you can
|
||||
// get more than one set of objects loaded but not yet finalized is if
|
||||
// they were loaded during relocation of another set.
|
||||
if (M.UnfinalizedSections.size() == 1)
|
||||
return ClientMM->finalizeMemory(ErrMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
OrcMCJITReplacement &M;
|
||||
std::shared_ptr<MCJITMemoryManager> ClientMM;
|
||||
};
|
||||
|
||||
class LinkingResolver : public JITSymbolResolver {
|
||||
public:
|
||||
LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
|
||||
|
||||
JITSymbol findSymbol(const std::string &Name) override {
|
||||
return M.ClientResolver->findSymbol(Name);
|
||||
}
|
||||
|
||||
JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
|
||||
if (auto Sym = M.findMangledSymbol(Name))
|
||||
return Sym;
|
||||
return M.ClientResolver->findSymbolInLogicalDylib(Name);
|
||||
}
|
||||
|
||||
private:
|
||||
OrcMCJITReplacement &M;
|
||||
};
|
||||
|
||||
private:
|
||||
static ExecutionEngine *
|
||||
createOrcMCJITReplacement(std::string *ErrorMsg,
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver,
|
||||
std::unique_ptr<TargetMachine> TM) {
|
||||
return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
|
||||
std::move(TM));
|
||||
}
|
||||
|
||||
public:
|
||||
OrcMCJITReplacement(
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> ClientResolver,
|
||||
std::unique_ptr<TargetMachine> TM)
|
||||
: ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
|
||||
MemMgr(std::make_shared<MCJITReplacementMemMgr>(*this,
|
||||
std::move(MemMgr))),
|
||||
Resolver(std::make_shared<LinkingResolver>(*this)),
|
||||
ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
|
||||
NotifyFinalized(*this),
|
||||
ObjectLayer([this]() { return this->MemMgr; }, NotifyObjectLoaded,
|
||||
NotifyFinalized),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
|
||||
LazyEmitLayer(CompileLayer) {}
|
||||
|
||||
static void Register() {
|
||||
OrcMCJITReplacementCtor = createOrcMCJITReplacement;
|
||||
}
|
||||
|
||||
void addModule(std::unique_ptr<Module> M) override {
|
||||
// If this module doesn't have a DataLayout attached then attach the
|
||||
// default.
|
||||
if (M->getDataLayout().isDefault()) {
|
||||
M->setDataLayout(getDataLayout());
|
||||
} else {
|
||||
assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
|
||||
}
|
||||
auto *MPtr = M.release();
|
||||
ShouldDelete[MPtr] = true;
|
||||
auto Deleter = [this](Module *Mod) {
|
||||
auto I = ShouldDelete.find(Mod);
|
||||
if (I != ShouldDelete.end() && I->second)
|
||||
delete Mod;
|
||||
};
|
||||
LocalModules.push_back(std::shared_ptr<Module>(MPtr, std::move(Deleter)));
|
||||
cantFail(LazyEmitLayer.addModule(LocalModules.back(), Resolver));
|
||||
}
|
||||
|
||||
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
|
||||
auto Obj =
|
||||
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O),
|
||||
nullptr);
|
||||
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
|
||||
}
|
||||
|
||||
void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
|
||||
auto Obj =
|
||||
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O));
|
||||
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
|
||||
}
|
||||
|
||||
void addArchive(object::OwningBinary<object::Archive> A) override {
|
||||
Archives.push_back(std::move(A));
|
||||
}
|
||||
|
||||
bool removeModule(Module *M) override {
|
||||
for (auto I = LocalModules.begin(), E = LocalModules.end(); I != E; ++I) {
|
||||
if (I->get() == M) {
|
||||
ShouldDelete[M] = false;
|
||||
LocalModules.erase(I);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t getSymbolAddress(StringRef Name) {
|
||||
return cantFail(findSymbol(Name).getAddress());
|
||||
}
|
||||
|
||||
JITSymbol findSymbol(StringRef Name) {
|
||||
return findMangledSymbol(Mangle(Name));
|
||||
}
|
||||
|
||||
void finalizeObject() override {
|
||||
// This is deprecated - Aim to remove in ExecutionEngine.
|
||||
// REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
|
||||
}
|
||||
|
||||
void mapSectionAddress(const void *LocalAddress,
|
||||
uint64_t TargetAddress) override {
|
||||
for (auto &P : UnfinalizedSections)
|
||||
if (P.second.count(LocalAddress))
|
||||
ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
|
||||
}
|
||||
|
||||
uint64_t getGlobalValueAddress(const std::string &Name) override {
|
||||
return getSymbolAddress(Name);
|
||||
}
|
||||
|
||||
uint64_t getFunctionAddress(const std::string &Name) override {
|
||||
return getSymbolAddress(Name);
|
||||
}
|
||||
|
||||
void *getPointerToFunction(Function *F) override {
|
||||
uint64_t FAddr = getSymbolAddress(F->getName());
|
||||
return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
|
||||
}
|
||||
|
||||
void *getPointerToNamedFunction(StringRef Name,
|
||||
bool AbortOnFailure = true) override {
|
||||
uint64_t Addr = getSymbolAddress(Name);
|
||||
if (!Addr && AbortOnFailure)
|
||||
llvm_unreachable("Missing symbol!");
|
||||
return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
|
||||
}
|
||||
|
||||
GenericValue runFunction(Function *F,
|
||||
ArrayRef<GenericValue> ArgValues) override;
|
||||
|
||||
void setObjectCache(ObjectCache *NewCache) override {
|
||||
CompileLayer.getCompiler().setObjectCache(NewCache);
|
||||
}
|
||||
|
||||
void setProcessAllSections(bool ProcessAllSections) override {
|
||||
ObjectLayer.setProcessAllSections(ProcessAllSections);
|
||||
}
|
||||
|
||||
void runStaticConstructorsDestructors(bool isDtors) override;
|
||||
|
||||
private:
|
||||
JITSymbol findMangledSymbol(StringRef Name) {
|
||||
if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
if (auto Sym = ClientResolver->findSymbol(Name))
|
||||
return Sym;
|
||||
if (auto Sym = scanArchives(Name))
|
||||
return Sym;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JITSymbol scanArchives(StringRef Name) {
|
||||
for (object::OwningBinary<object::Archive> &OB : Archives) {
|
||||
object::Archive *A = OB.getBinary();
|
||||
// Look for our symbols in each Archive
|
||||
auto OptionalChildOrErr = A->findSym(Name);
|
||||
if (!OptionalChildOrErr)
|
||||
report_fatal_error(OptionalChildOrErr.takeError());
|
||||
auto &OptionalChild = *OptionalChildOrErr;
|
||||
if (OptionalChild) {
|
||||
// FIXME: Support nested archives?
|
||||
Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
|
||||
OptionalChild->getAsBinary();
|
||||
if (!ChildBinOrErr) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(ChildBinOrErr.takeError());
|
||||
continue;
|
||||
}
|
||||
std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
|
||||
if (ChildBin->isObject()) {
|
||||
std::unique_ptr<object::ObjectFile> ChildObj(
|
||||
static_cast<object::ObjectFile*>(ChildBinOrErr->release()));
|
||||
auto Obj =
|
||||
std::make_shared<object::OwningBinary<object::ObjectFile>>(
|
||||
std::move(ChildObj), nullptr);
|
||||
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
|
||||
if (auto Sym = ObjectLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class NotifyObjectLoadedT {
|
||||
public:
|
||||
using LoadedObjInfoListT =
|
||||
std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>;
|
||||
|
||||
NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
|
||||
|
||||
void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H,
|
||||
const RTDyldObjectLinkingLayer::ObjectPtr &Obj,
|
||||
const RuntimeDyld::LoadedObjectInfo &Info) const {
|
||||
M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
|
||||
M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
|
||||
M.MemMgr->notifyObjectLoaded(&M, *Obj->getBinary());
|
||||
}
|
||||
private:
|
||||
OrcMCJITReplacement &M;
|
||||
};
|
||||
|
||||
class NotifyFinalizedT {
|
||||
public:
|
||||
NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
|
||||
|
||||
void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H) {
|
||||
M.UnfinalizedSections.erase(H);
|
||||
}
|
||||
|
||||
private:
|
||||
OrcMCJITReplacement &M;
|
||||
};
|
||||
|
||||
std::string Mangle(StringRef Name) {
|
||||
std::string MangledName;
|
||||
{
|
||||
raw_string_ostream MangledNameStream(MangledName);
|
||||
Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout());
|
||||
}
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
using ObjectLayerT = RTDyldObjectLinkingLayer;
|
||||
using CompileLayerT = IRCompileLayer<ObjectLayerT, orc::SimpleCompiler>;
|
||||
using LazyEmitLayerT = LazyEmittingLayer<CompileLayerT>;
|
||||
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
std::shared_ptr<MCJITReplacementMemMgr> MemMgr;
|
||||
std::shared_ptr<LinkingResolver> Resolver;
|
||||
std::shared_ptr<JITSymbolResolver> ClientResolver;
|
||||
Mangler Mang;
|
||||
|
||||
// IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr
|
||||
// delete blocks in LocalModules refer to the ShouldDelete map, so
|
||||
// LocalModules needs to be destructed before ShouldDelete.
|
||||
std::map<Module*, bool> ShouldDelete;
|
||||
std::vector<std::shared_ptr<Module>> LocalModules;
|
||||
|
||||
NotifyObjectLoadedT NotifyObjectLoaded;
|
||||
NotifyFinalizedT NotifyFinalized;
|
||||
|
||||
ObjectLayerT ObjectLayer;
|
||||
CompileLayerT CompileLayer;
|
||||
LazyEmitLayerT LazyEmitLayer;
|
||||
|
||||
// We need to store ObjLayerT::ObjSetHandles for each of the object sets
|
||||
// that have been emitted but not yet finalized so that we can forward the
|
||||
// mapSectionAddress calls appropriately.
|
||||
using SectionAddrSet = std::set<const void *>;
|
||||
struct ObjHandleCompare {
|
||||
bool operator()(ObjectLayerT::ObjHandleT H1,
|
||||
ObjectLayerT::ObjHandleT H2) const {
|
||||
return &*H1 < &*H2;
|
||||
}
|
||||
};
|
||||
SectionAddrSet SectionsAllocatedSinceLastLoad;
|
||||
std::map<ObjectLayerT::ObjHandleT, SectionAddrSet, ObjHandleCompare>
|
||||
UnfinalizedSections;
|
||||
|
||||
std::vector<object::OwningBinary<object::Archive>> Archives;
|
||||
};
|
||||
|
||||
} // end namespace orc
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H
|
@ -1,55 +0,0 @@
|
||||
//===--------------- RPCUtils.cpp - RPCUtils implementation ---------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// RPCUtils implementation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/RPCUtils.h"
|
||||
|
||||
char llvm::orc::rpc::RPCFatalError::ID = 0;
|
||||
char llvm::orc::rpc::ConnectionClosed::ID = 0;
|
||||
char llvm::orc::rpc::ResponseAbandoned::ID = 0;
|
||||
char llvm::orc::rpc::CouldNotNegotiate::ID = 0;
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
namespace rpc {
|
||||
|
||||
std::error_code ConnectionClosed::convertToErrorCode() const {
|
||||
return orcError(OrcErrorCode::RPCConnectionClosed);
|
||||
}
|
||||
|
||||
void ConnectionClosed::log(raw_ostream &OS) const {
|
||||
OS << "RPC connection already closed";
|
||||
}
|
||||
|
||||
std::error_code ResponseAbandoned::convertToErrorCode() const {
|
||||
return orcError(OrcErrorCode::RPCResponseAbandoned);
|
||||
}
|
||||
|
||||
void ResponseAbandoned::log(raw_ostream &OS) const {
|
||||
OS << "RPC response abandoned";
|
||||
}
|
||||
|
||||
CouldNotNegotiate::CouldNotNegotiate(std::string Signature)
|
||||
: Signature(std::move(Signature)) {}
|
||||
|
||||
std::error_code CouldNotNegotiate::convertToErrorCode() const {
|
||||
return orcError(OrcErrorCode::RPCCouldNotNegotiateFunction);
|
||||
}
|
||||
|
||||
void CouldNotNegotiate::log(raw_ostream &OS) const {
|
||||
OS << "Could not negotiate RPC function " << Signature;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace rpc
|
||||
} // end namespace orc
|
||||
} // end namespace llvm
|
Reference in New Issue
Block a user