summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-11-03 16:25:20 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-11-03 16:25:20 +0000
commit2f344637d61b9721858db5f180d0b76a5e994334 (patch)
tree95fb5b2393d487b705758e69f71f9e221d47da7a /llvm/include
parent96a9d8c8e5c083ca8150ec21ca98c4511b93849d (diff)
downloadbcm5719-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')
-rw-r--r--llvm/include/llvm-c/OrcBindings.h3
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h2
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h148
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h35
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.
OpenPOWER on IntegriCloud