summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/examples/Kaleidoscope/Orc/initial/toy.cpp16
-rw-r--r--llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp16
-rw-r--r--llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp20
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h56
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h22
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h15
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/JITSymbol.h55
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h114
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h72
-rw-r--r--llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h4
10 files changed, 227 insertions, 163 deletions
diff --git a/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp b/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp
index f075af156c2..0940578ec0b 100644
--- a/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp
@@ -1149,8 +1149,8 @@ public:
// new module. Create one that resolves symbols by looking back into the JIT.
auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
[&](const std::string &S) {
- return getMangledSymbolAddress(S);
- },
+ return findMangledSymbol(S).getAddress();
+ },
[](const std::string &S) { return 0; } );
return CompileLayer.addModuleSet(std::move(S), std::move(MM));
@@ -1158,17 +1158,17 @@ public:
void removeModule(ModuleHandleT H) { CompileLayer.removeModuleSet(H); }
- uint64_t getMangledSymbolAddress(const std::string &Name) {
- return CompileLayer.getSymbolAddress(Name, false);
+ JITSymbol findMangledSymbol(const std::string &Name) {
+ return CompileLayer.findSymbol(Name, false);
}
- uint64_t getSymbolAddress(const std::string Name) {
+ JITSymbol findSymbol(const std::string Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mang.getNameWithPrefix(MangledNameStream, Name);
}
- return getMangledSymbolAddress(MangledName);
+ return findMangledSymbol(MangledName);
}
private:
@@ -1228,11 +1228,11 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {
auto H = J.addModule(C.takeM());
// Get the address of the JIT'd function in memory.
- uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr");
+ auto ExprSymbol = J.findSymbol("__anon_expr");
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr;
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
#ifdef MINIMAL_STDERR_OUTPUT
FP();
#else
diff --git a/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp b/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp
index 1a2043f5933..7125cba0f40 100644
--- a/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp
@@ -1150,8 +1150,8 @@ public:
// new module. Create one that resolves symbols by looking back into the JIT.
auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
[&](const std::string &S) {
- return getMangledSymbolAddress(S);
- },
+ return findMangledSymbol(S).getAddress();
+ },
[](const std::string &S) { return 0; } );
return LazyEmitLayer.addModuleSet(std::move(S), std::move(MM));
@@ -1159,17 +1159,17 @@ public:
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
- uint64_t getMangledSymbolAddress(const std::string &Name) {
- return LazyEmitLayer.getSymbolAddress(Name, false);
+ JITSymbol findMangledSymbol(const std::string &Name) {
+ return LazyEmitLayer.findSymbol(Name, false);
}
- uint64_t getSymbolAddress(const std::string Name) {
+ JITSymbol findSymbol(const std::string Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mang.getNameWithPrefix(MangledNameStream, Name);
}
- return getMangledSymbolAddress(MangledName);
+ return findMangledSymbol(MangledName);
}
private:
@@ -1230,11 +1230,11 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {
auto H = J.addModule(C.takeM());
// Get the address of the JIT'd function in memory.
- uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr");
+ auto ExprSymbol = J.findSymbol("__anon_expr");
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr;
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
#ifdef MINIMAL_STDERR_OUTPUT
FP();
#else
diff --git a/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp b/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp
index 2963f30e2ed..11a17dd9aee 100644
--- a/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp
@@ -1174,8 +1174,8 @@ public:
auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
[&](const std::string &Name) -> uint64_t {
// First try to find 'Name' within the JIT.
- if (uint64_t Addr = getMangledSymbolAddress(Name))
- return Addr;
+ if (auto Symbol = findMangledSymbol(Name))
+ return Symbol.getAddress();
// If we don't find 'Name' in the JIT, see if we have some AST
// for it.
@@ -1192,8 +1192,8 @@ public:
// finished with it.
Session.FunctionDefs.erase(DefI);
- return getMangledSymbolAddress(Name);
- },
+ return findMangledSymbol(Name).getAddress();
+ },
[](const std::string &S) { return 0; } );
return LazyEmitLayer.addModuleSet(std::move(S), std::move(MM));
@@ -1201,12 +1201,12 @@ public:
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
- uint64_t getMangledSymbolAddress(const std::string &Name) {
- return LazyEmitLayer.getSymbolAddress(Name, false);
+ JITSymbol findMangledSymbol(const std::string &Name) {
+ return LazyEmitLayer.findSymbol(Name, false);
}
- uint64_t getSymbolAddress(const std::string &Name) {
- return getMangledSymbolAddress(Mangle(Name));
+ JITSymbol findSymbol(const std::string &Name) {
+ return findMangledSymbol(Mangle(Name));
}
private:
@@ -1253,11 +1253,11 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {
auto H = J.addModule(C.takeM());
// Get the address of the JIT'd function in memory.
- uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr");
+ auto ExprSymbol = J.findSymbol("__anon_expr");
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr;
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
#ifdef MINIMAL_STDERR_OUTPUT
FP();
#else
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 31eb1430943..25381f1bdd8 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -78,24 +78,25 @@ public:
void removeLogicalModule(LMHandle LMH) { Handles.erase(LMH); }
/// @brief Look up a symbol in this context.
- uint64_t lookup(LMHandle LMH, const std::string &Name) {
- if (uint64_t Addr = lookupOnlyIn(LMH, Name))
- return Addr;
+ JITSymbol findSymbol(LMHandle LMH, const std::string &Name) {
+ if (auto Symbol = findSymbolIn(LMH, Name))
+ return Symbol;
for (auto I = Handles.begin(), E = Handles.end(); I != E; ++I)
if (I != LMH)
- if (uint64_t Addr = lookupOnlyIn(I, Name))
- return Addr;
+ if (auto Symbol = findSymbolIn(I, Name))
+ return Symbol;
- return 0;
+ return nullptr;
}
private:
- uint64_t lookupOnlyIn(LMHandle LMH, const std::string &Name) {
+
+ JITSymbol findSymbolIn(LMHandle LMH, const std::string &Name) {
for (auto H : *LMH)
- if (uint64_t Addr = BaseLayer.lookupSymbolAddressIn(H, Name, false))
- return Addr;
- return 0;
+ if (auto Symbol = BaseLayer.findSymbolIn(H, Name, false))
+ return Symbol;
+ return nullptr;
}
BaseLayerT &BaseLayer;
@@ -190,7 +191,9 @@ public:
MSI.JITResolveCallbackHandlers.push_back(
createCallbackHandlerFromJITIndirections(
Indirections, MSI.PersistentManglers.back(),
- [=](StringRef S) { return DylibLookup->lookup(LMH, S); }));
+ [=](StringRef S) {
+ return DylibLookup->findSymbol(LMH, S).getAddress();
+ }));
// Insert callback asm code into the first module.
InsertCallbackAsm(*ExplodedModules[0],
@@ -209,12 +212,12 @@ public:
std::move(MSet),
createLookasideRTDyldMM<SectionMemoryManager>(
[=](const std::string &Name) {
- if (uint64_t Addr = DylibLookup->lookup(LMH, Name))
- return Addr;
- return getSymbolAddress(Name, true);
+ if (auto Symbol = DylibLookup->findSymbol(LMH, Name))
+ return Symbol.getAddress();
+ return findSymbol(Name, true).getAddress();
},
[=](const std::string &Name) {
- return DylibLookup->lookup(LMH, Name);
+ return DylibLookup->findSymbol(LMH, Name).getAddress();
}));
DylibLookup->addToLogicalModule(LMH, H);
MSI.BaseLayerModuleSetHandles.push_back(H);
@@ -222,7 +225,7 @@ public:
initializeFuncAddrs(*MSI.JITResolveCallbackHandlers.back(), Indirections,
MSI.PersistentManglers.back(), [=](StringRef S) {
- return DylibLookup->lookup(LMH, S);
+ return DylibLookup->findSymbol(LMH, S).getAddress();
});
}
@@ -238,23 +241,24 @@ public:
ModuleSetInfos.erase(H);
}
- /// @brief Get the address of a symbol provided by this layer, or some layer
- /// below this one.
- uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly);
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of a symbol provided by this layer, or some layer
/// below this one.
- uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second;
for (auto &BH : BaseLayerHandles) {
- if (uint64_t Addr =
- BaseLayer.lookupSymbolAddressIn(BH, Name, ExportedSymbolsOnly))
- return Addr;
+ if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly))
+ return Symbol;
}
- return 0;
+ return nullptr;
}
private:
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index 3076c12089a..873deb67376 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
+#include "JITSymbol.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Object/ObjectFile.h"
@@ -89,18 +90,25 @@ public:
/// @brief Remove the module set associated with the handle H.
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
- /// @brief Get the address of a loaded symbol. This call is forwarded to the
- /// base layer's getSymbolAddress implementation.
- uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly);
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of the given symbol in the context of the set of
/// compiled modules represented by the handle H. This call is
/// forwarded to the base layer's implementation.
- uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return BaseLayer.lookupSymbolAddressIn(H, Name, ExportedSymbolsOnly);
+ /// @param H The handle for the module set to search in.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it is found in the
+ /// given module set.
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
private:
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index 151b040be84..0bc71bfdf33 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
+#include "JITSymbol.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include <sstream>
@@ -84,7 +85,7 @@ public:
///
/// This is expected to be called by code in the JIT process itself, in
/// order to resolve a function.
- virtual uint64_t resolve(StubIndex StubIdx) = 0;
+ virtual TargetAddress resolve(StubIndex StubIdx) = 0;
private:
FuncNameList FuncNames;
@@ -97,9 +98,9 @@ public:
JITResolveCallbackHandlerImpl(LookupFtor Lookup, UpdateFtor Update)
: Lookup(std::move(Lookup)), Update(std::move(Update)) {}
- uint64_t resolve(StubIndex StubIdx) override {
+ TargetAddress resolve(StubIndex StubIdx) override {
const std::string &FuncName = getFuncName(StubIdx);
- uint64_t Addr = Lookup(FuncName);
+ TargetAddress Addr = Lookup(FuncName);
Update(FuncName, Addr);
return Addr;
}
@@ -211,10 +212,10 @@ createCallbackHandlerFromJITIndirections(const JITIndirections &Indirs,
[=](const std::string &S) {
return Lookup(NM.getMangledName(GetImplName(S)));
},
- [=](const std::string &S, uint64_t Addr) {
+ [=](const std::string &S, TargetAddress Addr) {
void *ImplPtr = reinterpret_cast<void *>(
Lookup(NM.getMangledName(GetAddrName(S))));
- memcpy(ImplPtr, &Addr, sizeof(uint64_t));
+ memcpy(ImplPtr, &Addr, sizeof(TargetAddress));
});
for (const auto &FuncName : Indirs.IndirectedNames)
@@ -248,12 +249,12 @@ void initializeFuncAddrs(JITResolveCallbackHandler &J,
// Now update indirects to point to the JIT resolve callback asm.
for (JITResolveCallbackHandler::StubIndex I = 0; I < J.getNumFuncs(); ++I) {
- uint64_t ResolveCallbackIdxAddr =
+ TargetAddress ResolveCallbackIdxAddr =
Lookup(getJITResolveCallbackIndexLabel(I));
void *AddrPtr = reinterpret_cast<void *>(
Lookup(NM.getMangledName(Indirs.GetAddrName(J.getFuncName(I)))));
assert(AddrPtr && "Can't find stub addr global to initialize.");
- memcpy(AddrPtr, &ResolveCallbackIdxAddr, sizeof(uint64_t));
+ memcpy(AddrPtr, &ResolveCallbackIdxAddr, sizeof(TargetAddress));
}
}
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/JITSymbol.h b/llvm/include/llvm/ExecutionEngine/Orc/JITSymbol.h
new file mode 100644
index 00000000000..c55e43c2a17
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/JITSymbol.h
@@ -0,0 +1,55 @@
+//===----------- JITSymbol.h - JIT symbol abstraction -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Abstraction for target process addresses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
+#define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
+
+#include <functional>
+
+namespace llvm {
+
+/// @brief Represents an address in the target process's address space.
+typedef uint64_t TargetAddress;
+
+/// @brief Represents a symbol in the JIT.
+class JITSymbol {
+public:
+ typedef std::function<TargetAddress()> GetAddressFtor;
+
+ JITSymbol(std::nullptr_t) : CachedAddr(0) {}
+
+ JITSymbol(GetAddressFtor GetAddress)
+ : CachedAddr(0), GetAddress(std::move(GetAddress)) {}
+
+ /// @brief Returns true if the symbol exists, false otherwise.
+ explicit operator bool() const { return CachedAddr || GetAddress; }
+
+ /// @brief Get the address of the symbol in the target address space. Returns
+ /// '0' if the symbol does not exist.
+ TargetAddress getAddress() {
+ if (GetAddress) {
+ CachedAddr = GetAddress();
+ assert(CachedAddr && "Symbol could not be materialized.");
+ GetAddress = nullptr;
+ }
+ return CachedAddr;
+ }
+
+private:
+ TargetAddress CachedAddr;
+ GetAddressFtor GetAddress;
+};
+
+}
+
+#endif // LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
index 428a263e202..a56f8b6f9a2 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
+#include "JITSymbol.h"
#include "LookasideRTDyldMM.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/IR/GlobalValue.h"
@@ -26,8 +27,8 @@ namespace llvm {
///
/// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does
/// not immediately emit them the layer below. Instead, emissing to the base
-/// layer is deferred until some symbol in the module set is requested via
-/// getSymbolAddress.
+/// layer is deferred until the first time the client requests the address
+/// (via JITSymbol::getAddress) for a symbol contained in this layer.
template <typename BaseLayerT> class LazyEmittingLayer {
public:
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT;
@@ -38,32 +39,37 @@ private:
EmissionDeferredSet() : EmitState(NotEmitted) {}
virtual ~EmissionDeferredSet() {}
- uint64_t Search(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
+ JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
switch (EmitState) {
- case NotEmitted:
- if (Provides(Name, ExportedSymbolsOnly)) {
- EmitState = Emitting;
- Handle = Emit(B);
- EmitState = Emitted;
- } else
- return 0;
- break;
- case Emitting:
- // The module has been added to the base layer but we haven't gotten a
- // handle back yet so we can't use lookupSymbolAddressIn. Just return
- // '0' here - LazyEmittingLayer::getSymbolAddress will do a global
- // search in the base layer when it doesn't find the symbol here, so
- // we'll find it in the end.
- return 0;
- case Emitted:
- // Nothing to do. Go ahead and search the base layer.
- break;
+ case NotEmitted:
+ if (provides(Name, ExportedSymbolsOnly))
+ return JITSymbol(
+ [this,ExportedSymbolsOnly,Name,&B]() -> TargetAddress {
+ if (EmitState == Emitting)
+ return 0;
+ else if (EmitState != Emitted) {
+ EmitState = Emitting;
+ Handle = emit(B);
+ EmitState = Emitted;
+ }
+ return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly)
+ .getAddress();
+ });
+ else
+ return nullptr;
+ case Emitting:
+ // Calling "emit" can trigger external symbol lookup (e.g. to check for
+ // pre-existing definitions of common-symbol), but it will never find in
+ // this module that it would not have found already, so return null from
+ // here.
+ return nullptr;
+ case Emitted:
+ return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
}
-
- return B.lookupSymbolAddressIn(Handle, Name, ExportedSymbolsOnly);
+ llvm_unreachable("Invalid emit-state.");
}
- void RemoveModulesFromBaseLayer(BaseLayerT &BaseLayer) {
+ void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
if (EmitState != NotEmitted)
BaseLayer.removeModuleSet(Handle);
}
@@ -74,8 +80,8 @@ private:
std::unique_ptr<RTDyldMemoryManager> MM);
protected:
- virtual bool Provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
- virtual BaseLayerHandleT Emit(BaseLayerT &BaseLayer) = 0;
+ virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
+ virtual BaseLayerHandleT emit(BaseLayerT &BaseLayer) = 0;
private:
enum { NotEmitted, Emitting, Emitted } EmitState;
@@ -90,14 +96,14 @@ private:
: Ms(std::move(Ms)), MM(std::move(MM)) {}
protected:
- BaseLayerHandleT Emit(BaseLayerT &BaseLayer) override {
+ BaseLayerHandleT emit(BaseLayerT &BaseLayer) override {
// We don't need the mangled names set any more: Once we've emitted this
// to the base layer we'll just look for symbols there.
MangledNames.reset();
return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
}
- bool Provides(StringRef Name, bool ExportedSymbolsOnly) const override {
+ bool provides(StringRef Name, bool ExportedSymbolsOnly) const override {
// FIXME: We could clean all this up if we had a way to reliably demangle
// names: We could just demangle name and search, rather than
// mangling everything else.
@@ -190,12 +196,6 @@ public:
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
/// @brief Add the given set of modules to the lazy emitting layer.
- ///
- /// This method stores the set of modules in a side table, rather than
- /// immediately emitting them to the next layer of the JIT. When the address
- /// of a symbol provided by this set is requested (via getSymbolAddress) it
- /// triggers the emission of this set to the layer below (along with the given
- /// memory manager instance), and returns the address of the requested symbol.
template <typename ModuleSetT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
std::unique_ptr<RTDyldMemoryManager> MM) {
@@ -209,39 +209,35 @@ public:
/// This method will free the memory associated with the given module set,
/// both in this layer, and the base layer.
void removeModuleSet(ModuleSetHandleT H) {
- (*H)->RemoveModulesFromBaseLayer(BaseLayer);
+ (*H)->removeModulesFromBaseLayer(BaseLayer);
ModuleSetList.erase(H);
}
- /// @brief Get the address of a symbol provided by this layer, or some layer
- /// below this one.
- ///
- /// When called for a symbol that has been added to this layer (via
- /// addModuleSet) but not yet emitted, this will trigger the emission of the
- /// module set containing the definiton of the symbol.
- uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
- // Look up symbol among existing definitions.
- if (uint64_t Addr = BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly))
- return Addr;
-
- // If not found then search the deferred sets. The call to 'Search' will
- // cause the set to be emitted to the next layer if it provides a definition
- // of 'Name'.
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ // Look for the symbol among existing definitions.
+ if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
+ return Symbol;
+
+ // If not found then search the deferred sets. If any of these contain a
+ // definition of 'Name' then they will return a JITSymbol that will emit
+ // the corresponding module when the symbol address is requested.
for (auto &DeferredSet : ModuleSetList)
- if (uint64_t Addr =
- DeferredSet->Search(Name, ExportedSymbolsOnly, BaseLayer))
- return Addr;
+ if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer))
+ return Symbol;
- // If no definition found anywhere return 0.
- return 0;
+ // If no definition found anywhere return a null symbol.
+ return nullptr;
}
/// @brief Get the address of the given symbol in the context of the set of
- /// compiled modules represented by the handle H. This call is
- /// forwarded to the base layer's implementation.
- uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return (*H)->Search(Name, ExportedSymbolsOnly, BaseLayer);
+ /// compiled modules represented by the handle H.
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
}
};
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index 957fec40ad3..ce306e67dde 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+#include "JITSymbol.h"
#include "LookasideRTDyldMM.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
@@ -24,6 +25,7 @@ namespace llvm {
class ObjectLinkingLayerBase {
protected:
+
/// @brief Holds a set of objects to be allocated/linked as a unit in the JIT.
///
/// An instance of this class will be created for each set of objects added
@@ -48,7 +50,7 @@ protected:
return RTDyld->loadObject(Obj);
}
- uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
+ TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
if (ExportedSymbolsOnly)
return RTDyld->getExportedSymbolLoadAddress(Name);
return RTDyld->getSymbolLoadAddress(Name);
@@ -65,10 +67,10 @@ protected:
State = Finalized;
}
- void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) {
+ void mapSectionAddress(const void *LocalAddress, TargetAddress TargetAddr) {
assert((State != Finalized) &&
"Attempting to remap sections for finalized objects.");
- RTDyld->mapSectionAddress(LocalAddress, TargetAddress);
+ RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
}
void takeOwnershipOfBuffer(std::unique_ptr<MemoryBuffer> B) {
@@ -178,8 +180,8 @@ public:
/// @brief Map section addresses for the objects associated with the handle H.
void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
- uint64_t TargetAddress) {
- H->mapSectionAddress(LocalAddress, TargetAddress);
+ TargetAddress TargetAddr) {
+ H->mapSectionAddress(LocalAddress, TargetAddr);
}
/// @brief Remove the set of objects associated with handle H.
@@ -195,42 +197,40 @@ public:
LinkedObjSetList.erase(H);
}
- /// @brief Get the address of a loaded symbol.
- ///
- /// @return The address in the target process's address space of the named
- /// symbol. Null if no such symbol is known.
- ///
- /// This method will trigger the finalization of the linked object set
- /// containing the definition of the given symbol, if it is found.
- uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
++I)
- if (uint64_t Addr = lookupSymbolAddressIn(I, Name, ExportedSymbolsOnly))
- return Addr;
+ if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
+ return Symbol;
- return 0;
+ return nullptr;
}
- /// @brief Search for a given symbol in the context of the set of loaded
- /// objects represented by the handle H.
- ///
- /// @return The address in the target process's address space of the named
- /// symbol. Null if the given object set does not contain a definition
- /// of this symbol.
- ///
- /// This method will trigger the finalization of the linked object set
- /// represented by the handle H if that set contains the requested symbol.
- uint64_t lookupSymbolAddressIn(ObjSetHandleT H, StringRef Name,
- bool ExportedSymbolsOnly) {
- if (uint64_t Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
- if (H->NeedsFinalization()) {
- H->Finalize();
- if (NotifyFinalized)
- NotifyFinalized(H);
- }
- return Addr;
- }
- return 0;
+ /// @brief Search for the given named symbol in the context of the set of
+ /// loaded objects represented by the handle H.
+ /// @param H The handle for the object set to search in.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it is found in the
+ /// given object set.
+ JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
+ bool ExportedSymbolsOnly) {
+ if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly))
+ return JITSymbol(
+ [this, Addr, H](){
+ if (H->NeedsFinalization()) {
+ H->Finalize();
+ if (NotifyFinalized)
+ NotifyFinalized(H);
+ }
+ return Addr;
+ });
+
+ return nullptr;
}
private:
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
index ddbc73251c7..f09d13e87bd 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
+++ b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
@@ -213,7 +213,7 @@ public:
private:
uint64_t getSymbolAddressWithoutMangling(StringRef Name) {
- if (uint64_t Addr = LazyEmitLayer.getSymbolAddress(Name, false))
+ if (uint64_t Addr = LazyEmitLayer.findSymbol(Name, false).getAddress())
return Addr;
if (uint64_t Addr = MM->getSymbolAddress(Name))
return Addr;
@@ -241,7 +241,7 @@ private:
static_cast<object::ObjectFile *>(ChildBin.release())));
ObjectLayer.addObjectSet(
std::move(ObjSet), llvm::make_unique<ForwardingRTDyldMM>(*this));
- if (uint64_t Addr = ObjectLayer.getSymbolAddress(Name, true))
+ if (uint64_t Addr = ObjectLayer.findSymbol(Name, true).getAddress())
return Addr;
}
}
OpenPOWER on IntegriCloud