summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/ExecutionEngine/JITSymbol.h13
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/Core.h234
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/OrcError.h15
3 files changed, 260 insertions, 2 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/JITSymbol.h b/llvm/include/llvm/ExecutionEngine/JITSymbol.h
index 933b3ea8e13..daf8c0ac4c7 100644
--- a/llvm/include/llvm/ExecutionEngine/JITSymbol.h
+++ b/llvm/include/llvm/ExecutionEngine/JITSymbol.h
@@ -48,7 +48,9 @@ public:
Weak = 1U << 1,
Common = 1U << 2,
Absolute = 1U << 3,
- Exported = 1U << 4
+ Exported = 1U << 4,
+ NotMaterialized = 1U << 5,
+ Materializing = 1U << 6
};
/// @brief Default-construct a JITSymbolFlags instance.
@@ -67,6 +69,15 @@ public:
return (Flags & HasError) == HasError;
}
+ /// @brief Returns true if this symbol has been fully materialized (i.e. is
+ /// callable).
+ bool isMaterialized() const { return !(Flags & NotMaterialized); }
+
+ /// @brief Returns true if this symbol is in the process of being
+ /// materialized. This is generally only of interest as an
+ /// implementation detail to JIT infrastructure.
+ bool isMaterializing() const { return Flags & Materializing; }
+
/// @brief Returns true if the Weak flag is set.
bool isWeak() const {
return (Flags & Weak) == Weak;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
new file mode 100644
index 00000000000..546ccc54a6d
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -0,0 +1,234 @@
+//===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains core ORC APIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_CORE_H
+#define LLVM_EXECUTIONENGINE_ORC_CORE_H
+
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
+
+#include <deque>
+#include <map>
+#include <memory>
+#include <set>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+class VSO;
+
+/// @brief A set of symbol names (represented by SymbolStringPtrs for
+// efficiency).
+using SymbolNameSet = std::set<SymbolStringPtr>;
+
+/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbols
+/// (address/flags pairs).
+using SymbolMap = std::map<SymbolStringPtr, JITSymbol>;
+
+/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
+using SymbolFlagsMap = std::map<SymbolStringPtr, JITSymbolFlags>;
+
+/// @brief A symbol query that returns results via a callback when results are
+/// ready.
+///
+/// makes a callback when all symbols are available.
+class AsynchronousSymbolQuery {
+public:
+
+ /// @brief Callback to notify client that symbols have been resolved.
+ using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
+
+ /// @brief Callback to notify client that symbols are ready for execution.
+ using SymbolsReadyCallback = std::function<void(Error)>;
+
+ /// @brief Create a query for the given symbols, notify-resolved and
+ /// notify-ready callbacks.
+ AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
+ SymbolsResolvedCallback NotifySymbolsResolved,
+ SymbolsReadyCallback NotifySymbolsReady);
+
+ /// @brief Notify client that the query failed.
+ ///
+ /// If the notify-resolved callback has not been made yet, then it is called
+ /// with the given error, and the notify-finalized callback is never made.
+ ///
+ /// If the notify-resolved callback has already been made then then the
+ /// notify-finalized callback is called with the given error.
+ ///
+ /// It is illegal to call setFailed after both callbacks have been made.
+ void setFailed(Error Err);
+
+ /// @brief Set the resolved symbol information for the given symbol name.
+ ///
+ /// If this symbol was the last one not resolved, this will trigger a call to
+ /// the notify-finalized callback passing the completed sybol map.
+ void setDefinition(SymbolStringPtr Name, JITSymbol Sym);
+
+ /// @brief Notify the query that a requested symbol is ready for execution.
+ ///
+ /// This decrements the query's internal count of not-yet-ready symbols. If
+ /// this call to notifySymbolFinalized sets the counter to zero, it will call
+ /// the notify-finalized callback with Error::success as the value.
+ void notifySymbolFinalized();
+private:
+ SymbolMap Symbols;
+ size_t OutstandingResolutions = 0;
+ size_t OutstandingFinalizations = 0;
+ SymbolsResolvedCallback NotifySymbolsResolved;
+ SymbolsReadyCallback NotifySymbolsReady;
+};
+
+/// @brief Represents a source of symbol definitions which may be materialized
+/// (turned into data / code through some materialization process) or
+/// discarded (if the definition is overridden by a stronger one).
+///
+/// SymbolSources are used when providing lazy definitions of symbols to VSOs.
+/// The VSO will call materialize when the address of a symbol is requested via
+/// the lookup method. The VSO will call discard if a stronger definition is
+/// added or already present.
+class SymbolSource {
+public:
+ virtual ~SymbolSource() {}
+
+ /// @brief Implementations of this method should materialize the given
+ /// symbols (plus any additional symbols required) by adding a
+ /// Materializer to the ExecutionSession's MaterializationQueue.
+ virtual Error materialize(VSO &V, SymbolNameSet Symbols) = 0;
+
+ /// @brief Implementations of this method should discard the given symbol
+ /// from the source (e.g. if the source is an LLVM IR Module and the
+ /// symbol is a function, delete the function body or mark it available
+ /// externally).
+ virtual void discard(VSO &V, SymbolStringPtr Name) = 0;
+private:
+ virtual void anchor();
+};
+
+/// @brief Represents a dynamic linkage unit in a JIT process.
+///
+/// VSO acts as a symbol table (symbol definitions can be set and the dylib
+/// queried to find symbol addresses) and as a key for tracking resources
+/// (since a VSO's address is fixed).
+class VSO {
+ friend class ExecutionSession;
+public:
+
+ /// @brief
+ enum RelativeLinkageStrength {
+ NewDefinitionIsStronger,
+ DuplicateDefinition,
+ ExistingDefinitionIsStronger
+ };
+
+ using SetDefinitionsResult =
+ std::map<SymbolStringPtr, RelativeLinkageStrength>;
+ using SourceWorkMap = std::map<SymbolSource*, SymbolNameSet>;
+
+ struct LookupResult {
+ SourceWorkMap MaterializationWork;
+ SymbolNameSet UnresolvedSymbols;
+ };
+
+ VSO() = default;
+
+ VSO(const VSO&) = delete;
+ VSO& operator=(const VSO&) = delete;
+ VSO(VSO&&) = delete;
+ VSO& operator=(VSO&&) = delete;
+
+ /// @brief Compare new linkage with existing linkage.
+ static RelativeLinkageStrength
+ compareLinkage(Optional<JITSymbolFlags> OldFlags,
+ JITSymbolFlags NewFlags);
+
+ /// @brief Compare new linkage with an existing symbol's linkage.
+ RelativeLinkageStrength compareLinkage(SymbolStringPtr Name,
+ JITSymbolFlags NewFlags) const;
+
+ /// @brief Adds the given symbols to the mapping as resolved, finalized
+ /// symbols.
+ ///
+ /// FIXME: We can take this by const-ref once symbol-based laziness is
+ /// removed.
+ Error define(SymbolMap NewSymbols);
+
+ /// @brief Adds the given symbols to the mapping as lazy symbols.
+ Error defineLazy(const SymbolFlagsMap &NewSymbols, SymbolSource &Source);
+
+ /// @brief Add the given symbol/address mappings to the dylib, but do not
+ /// mark the symbols as finalized yet.
+ void resolve(SymbolMap SymbolValues);
+
+ /// @brief Finalize the given symbols.
+ void finalize(SymbolNameSet SymbolsToFinalize);
+
+ /// @brief Apply the given query to the given symbols in this VSO.
+ ///
+ /// For symbols in this VSO that have already been materialized, their address
+ /// will be set in the query immediately.
+ ///
+ /// For symbols in this VSO that have not been materialized, the query will be
+ /// recorded and the source for those symbols (plus the set of symbols to be
+ /// materialized by that source) will be returned as the MaterializationWork
+ /// field of the LookupResult.
+ ///
+ /// Any symbols not found in this VSO will be returned in the
+ /// UnresolvedSymbols field of the LookupResult.
+ LookupResult lookup(AsynchronousSymbolQuery &Query, SymbolNameSet Symbols);
+
+private:
+
+ class MaterializationInfo {
+ public:
+ MaterializationInfo(JITSymbolFlags Flags, AsynchronousSymbolQuery &Query);
+ JITSymbolFlags getFlags() const;
+ JITTargetAddress getAddress() const;
+ void query(SymbolStringPtr Name, AsynchronousSymbolQuery &Query);
+ void resolve(SymbolStringPtr Name, JITSymbol Sym);
+ void finalize();
+ private:
+ JITSymbolFlags Flags;
+ JITTargetAddress Address = 0;
+ std::vector<AsynchronousSymbolQuery*> PendingResolution;
+ std::vector<AsynchronousSymbolQuery*> PendingFinalization;
+ };
+
+ class SymbolTableEntry {
+ public:
+ SymbolTableEntry(JITSymbolFlags Flags, SymbolSource &Source);
+ SymbolTableEntry(JITSymbol Sym);
+ SymbolTableEntry(SymbolTableEntry &&Other);
+ ~SymbolTableEntry();
+ JITSymbolFlags getFlags() const;
+ void replaceWithSource(VSO &V, SymbolStringPtr Name, JITSymbolFlags Flags,
+ SymbolSource &NewSource);
+ SymbolSource* query(SymbolStringPtr Name, AsynchronousSymbolQuery &Query);
+ void resolve(VSO &V, SymbolStringPtr Name, JITSymbol Sym);
+ void finalize();
+ private:
+ JITSymbolFlags Flags;
+ union {
+ JITTargetAddress Address;
+ SymbolSource *Source;
+ std::unique_ptr<MaterializationInfo> MatInfo;
+ };
+ };
+
+ std::map<SymbolStringPtr, SymbolTableEntry> Symbols;
+};
+
+} // End namespace orc
+} // End namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_CORE_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
index e1ac87075ac..c2ff41e421e 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
@@ -22,7 +22,8 @@ namespace orc {
enum class OrcErrorCode : int {
// RPC Errors
- JITSymbolNotFound = 1,
+ DuplicateDefinition = 1,
+ JITSymbolNotFound,
RemoteAllocatorDoesNotExist,
RemoteAllocatorIdAlreadyInUse,
RemoteMProtectAddrUnrecognized,
@@ -39,6 +40,18 @@ enum class OrcErrorCode : int {
std::error_code orcError(OrcErrorCode ErrCode);
+class DuplicateDefinition : public ErrorInfo<DuplicateDefinition> {
+public:
+ static char ID;
+
+ DuplicateDefinition(std::string SymbolName);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getSymbolName() const;
+private:
+ std::string SymbolName;
+};
+
class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
public:
static char ID;
OpenPOWER on IntegriCloud