diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-11-03 16:25:20 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-11-03 16:25:20 +0000 |
| commit | 2f344637d61b9721858db5f180d0b76a5e994334 (patch) | |
| tree | 95fb5b2393d487b705758e69f71f9e221d47da7a /llvm/include | |
| parent | 96a9d8c8e5c083ca8150ec21ca98c4511b93849d (diff) | |
| download | bcm5719-llvm-2f344637d61b9721858db5f180d0b76a5e994334.tar.gz bcm5719-llvm-2f344637d61b9721858db5f180d0b76a5e994334.zip | |
Revert "[Orc] Directly emit machine code for the x86 resolver block and trampolines."
This reverts commit r251933.
It broke the build of examples/Kaleidoscope/Orc/fully_lazy/toy.cpp.
llvm-svn: 251937
Diffstat (limited to 'llvm/include')
4 files changed, 105 insertions, 83 deletions
diff --git a/llvm/include/llvm-c/OrcBindings.h b/llvm/include/llvm-c/OrcBindings.h index f6aff916999..78a7bc146ee 100644 --- a/llvm/include/llvm-c/OrcBindings.h +++ b/llvm/include/llvm-c/OrcBindings.h @@ -47,7 +47,8 @@ typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack, * client should not attempt to dispose of the Target Machine, or it will result * in a double-free. */ -LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM); +LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM, + LLVMContextRef Context); /** * Mangle the given symbol. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 8f4e844032c..9c37aa01681 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -242,7 +242,7 @@ private: // Create a callback, associate it with the stub for the function, // and set the compile action to compile the partition containing the // function. - auto CCInfo = CompileCallbackMgr.getCompileCallback(); + auto CCInfo = CompileCallbackMgr.getCompileCallback(SrcM.getContext()); StubInits[mangle(F.getName(), DL)] = std::make_pair(CCInfo.getAddress(), JITSymbolBase::flagsFromGlobalValue(F)); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index cabc95543d8..5ed8935980f 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -27,7 +27,8 @@ namespace llvm { namespace orc { -/// @brief Target-independent base class JITCompileCallbackManager. +/// @brief Base class for JITLayer independent aspects of +/// JITCompileCallbackManager. class JITCompileCallbackManagerBase { public: @@ -53,8 +54,13 @@ public: /// @brief Construct a JITCompileCallbackManagerBase. /// @param ErrorHandlerAddress The address of an error handler in the target /// process to be used if a compile callback fails. - JITCompileCallbackManagerBase(TargetAddress ErrorHandlerAddress) - : ErrorHandlerAddress(ErrorHandlerAddress) {} + /// @param NumTrampolinesPerBlock Number of trampolines to emit if there is no + /// available trampoline when getCompileCallback is + /// called. + JITCompileCallbackManagerBase(TargetAddress ErrorHandlerAddress, + unsigned NumTrampolinesPerBlock) + : ErrorHandlerAddress(ErrorHandlerAddress), + NumTrampolinesPerBlock(NumTrampolinesPerBlock) {} virtual ~JITCompileCallbackManagerBase() {} @@ -84,7 +90,7 @@ public: } /// @brief Reserve a compile callback. - virtual CompileCallbackInfo getCompileCallback() = 0; + virtual CompileCallbackInfo getCompileCallback(LLVMContext &Context) = 0; /// @brief Get a CompileCallbackInfo for an existing callback. CompileCallbackInfo getCompileCallbackInfo(TargetAddress TrampolineAddr) { @@ -107,6 +113,7 @@ public: protected: TargetAddress ErrorHandlerAddress; + unsigned NumTrampolinesPerBlock; typedef std::map<TargetAddress, CompileFtor> TrampolineMapT; TrampolineMapT ActiveTrampolines; @@ -117,54 +124,69 @@ private: }; /// @brief Manage compile callbacks. -template <typename TargetT> +template <typename JITLayerT, typename TargetT> class JITCompileCallbackManager : public JITCompileCallbackManagerBase { public: /// @brief Construct a JITCompileCallbackManager. + /// @param JIT JIT layer to emit callback trampolines, etc. into. + /// @param Context LLVMContext to use for trampoline & resolve block modules. /// @param ErrorHandlerAddress The address of an error handler in the target /// process to be used if a compile callback fails. - JITCompileCallbackManager(TargetAddress ErrorHandlerAddress) - : JITCompileCallbackManagerBase(ErrorHandlerAddress) { - - /// Set up the resolver block. - std::error_code EC; - ResolverBlock = - sys::OwningMemoryBlock( - sys::Memory::allocateMappedMemory(TargetT::ResolverCodeSize, nullptr, - sys::Memory::MF_READ | - sys::Memory::MF_WRITE, EC)); - assert(!EC && "Failed to allocate resolver block"); - - TargetT::writeResolverCode(static_cast<uint8_t*>(ResolverBlock.base()), - &reenter, this); - - EC = sys::Memory::protectMappedMemory(ResolverBlock.getMemoryBlock(), - sys::Memory::MF_READ | - sys::Memory::MF_EXEC); - assert(!EC && "Failed to mprotect resolver block"); + /// @param NumTrampolinesPerBlock Number of trampolines to allocate whenever + /// there is no existing callback trampoline. + /// (Trampolines are allocated in blocks for + /// efficiency.) + JITCompileCallbackManager(JITLayerT &JIT, RuntimeDyld::MemoryManager &MemMgr, + LLVMContext &Context, + TargetAddress ErrorHandlerAddress, + unsigned NumTrampolinesPerBlock) + : JITCompileCallbackManagerBase(ErrorHandlerAddress, + NumTrampolinesPerBlock), + JIT(JIT), MemMgr(MemMgr) { + emitResolverBlock(Context); } /// @brief Get/create a compile callback with the given signature. - CompileCallbackInfo getCompileCallback() final { - TargetAddress TrampolineAddr = getAvailableTrampolineAddr(); + CompileCallbackInfo getCompileCallback(LLVMContext &Context) final { + TargetAddress TrampolineAddr = getAvailableTrampolineAddr(Context); auto &Compile = this->ActiveTrampolines[TrampolineAddr]; return CompileCallbackInfo(TrampolineAddr, Compile); } private: - static TargetAddress reenter(void *CCMgr, void *TrampolineId) { - JITCompileCallbackManager *Mgr = - static_cast<JITCompileCallbackManager*>(CCMgr); - return Mgr->executeCompileCallback( - static_cast<TargetAddress>( - reinterpret_cast<uintptr_t>(TrampolineId))); + std::vector<std::unique_ptr<Module>> + SingletonSet(std::unique_ptr<Module> M) { + std::vector<std::unique_ptr<Module>> Ms; + Ms.push_back(std::move(M)); + return Ms; + } + + void emitResolverBlock(LLVMContext &Context) { + std::unique_ptr<Module> M(new Module("resolver_block_module", + Context)); + TargetT::insertResolverBlock(*M, *this); + auto NonResolver = + createLambdaResolver( + [](const std::string &Name) -> RuntimeDyld::SymbolInfo { + llvm_unreachable("External symbols in resolver block?"); + }, + [](const std::string &Name) -> RuntimeDyld::SymbolInfo { + llvm_unreachable("Dylib symbols in resolver block?"); + }); + auto H = JIT.addModuleSet(SingletonSet(std::move(M)), &MemMgr, + std::move(NonResolver)); + JIT.emitAndFinalize(H); + auto ResolverBlockSymbol = + JIT.findSymbolIn(H, TargetT::ResolverBlockName, false); + assert(ResolverBlockSymbol && "Failed to insert resolver block"); + ResolverBlockAddr = ResolverBlockSymbol.getAddress(); } - TargetAddress getAvailableTrampolineAddr() { + TargetAddress getAvailableTrampolineAddr(LLVMContext &Context) { if (this->AvailableTrampolines.empty()) - grow(); + grow(Context); assert(!this->AvailableTrampolines.empty() && "Failed to grow available trampolines."); TargetAddress TrampolineAddr = this->AvailableTrampolines.back(); @@ -172,41 +194,35 @@ private: return TrampolineAddr; } - void grow() { + void grow(LLVMContext &Context) { assert(this->AvailableTrampolines.empty() && "Growing prematurely?"); - - std::error_code EC; - auto TrampolineBlock = - sys::OwningMemoryBlock( - sys::Memory::allocateMappedMemory(TargetT::PageSize, nullptr, - sys::Memory::MF_READ | - sys::Memory::MF_WRITE, EC)); - assert(!EC && "Failed to allocate trampoline block"); - - - unsigned NumTrampolines = - (TargetT::PageSize - TargetT::PointerSize) / TargetT::TrampolineSize; - - uint8_t *TrampolineMem = static_cast<uint8_t*>(TrampolineBlock.base()); - TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(), - NumTrampolines); - - for (unsigned I = 0; I < NumTrampolines; ++I) - this->AvailableTrampolines.push_back( - static_cast<TargetAddress>( - reinterpret_cast<uintptr_t>( - TrampolineMem + (I * TargetT::TrampolineSize)))); - - EC = sys::Memory::protectMappedMemory(TrampolineBlock.getMemoryBlock(), - sys::Memory::MF_READ | - sys::Memory::MF_EXEC); - assert(!EC && "Failed to mprotect trampoline block"); - - TrampolineBlocks.push_back(std::move(TrampolineBlock)); + std::unique_ptr<Module> M(new Module("trampoline_block", Context)); + auto GetLabelName = + TargetT::insertCompileCallbackTrampolines(*M, ResolverBlockAddr, + this->NumTrampolinesPerBlock, + this->ActiveTrampolines.size()); + auto NonResolver = + createLambdaResolver( + [](const std::string &Name) -> RuntimeDyld::SymbolInfo { + llvm_unreachable("External symbols in trampoline block?"); + }, + [](const std::string &Name) -> RuntimeDyld::SymbolInfo { + llvm_unreachable("Dylib symbols in trampoline block?"); + }); + auto H = JIT.addModuleSet(SingletonSet(std::move(M)), &MemMgr, + std::move(NonResolver)); + JIT.emitAndFinalize(H); + for (unsigned I = 0; I < this->NumTrampolinesPerBlock; ++I) { + std::string Name = GetLabelName(I); + auto TrampolineSymbol = JIT.findSymbolIn(H, Name, false); + assert(TrampolineSymbol && "Failed to emit trampoline."); + this->AvailableTrampolines.push_back(TrampolineSymbol.getAddress()); + } } - sys::OwningMemoryBlock ResolverBlock; - std::vector<sys::OwningMemoryBlock> TrampolineBlocks; + JITLayerT &JIT; + RuntimeDyld::MemoryManager &MemMgr; + TargetAddress ResolverBlockAddr; }; /// @brief Base class for managing collections of named indirect stubs. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h index 3e57314ba2d..58273ae4616 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h @@ -26,24 +26,29 @@ namespace orc { class OrcX86_64 { public: - static const unsigned PageSize = 4096; - static const unsigned PointerSize = 8; - static const unsigned TrampolineSize = 8; - static const unsigned ResolverCodeSize = 0x78; + static const char *ResolverBlockName; - typedef TargetAddress (*JITReentryFn)(void *CallbackMgr, - void *TrampolineId); + /// @brief Insert module-level inline callback asm into module M for the + /// symbols managed by JITResolveCallbackHandler J. + static void insertResolverBlock(Module &M, + JITCompileCallbackManagerBase &JCBM); - /// @brief Write the resolver code into the given memory. The user is be - /// responsible for allocating the memory and setting permissions. - static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, - void *CallbackMgr); + /// @brief Get a label name from the given index. + typedef std::function<std::string(unsigned)> LabelNameFtor; - /// @brief Write the requsted number of trampolines into the given memory, - /// which must be big enough to hold 1 pointer, plus NumTrampolines - /// trampolines. - static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, - unsigned NumTrampolines); + /// @brief Insert the requested number of trampolines into the given module. + /// @param M Module to insert the call block into. + /// @param NumCalls Number of calls to create in the call block. + /// @param StartIndex Optional argument specifying the index suffix to start + /// with. + /// @return A functor that provides the symbol name for each entry in the call + /// block. + /// + static LabelNameFtor insertCompileCallbackTrampolines( + Module &M, + TargetAddress TrampolineAddr, + unsigned NumCalls, + unsigned StartIndex = 0); /// @brief Provide information about stub blocks generated by the /// makeIndirectStubsBlock function. |

