Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 9b3761c

Browse files
committed
[ORC] Re-apply r321838 - Addition of new ORC core APIs.
The original commit broke the builders due to a think-o in an assertion: AsynchronousSymbolQuery's constructor needs to check the callback member variables, not the constructor arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321853 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent bfdde98 commit 9b3761c

File tree

8 files changed

+832
-4
lines changed

8 files changed

+832
-4
lines changed

include/llvm/ExecutionEngine/JITSymbol.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ class JITSymbolFlags {
4848
Weak = 1U << 1,
4949
Common = 1U << 2,
5050
Absolute = 1U << 3,
51-
Exported = 1U << 4
51+
Exported = 1U << 4,
52+
NotMaterialized = 1U << 5,
53+
Materializing = 1U << 6
5254
};
5355

5456
/// @brief Default-construct a JITSymbolFlags instance.
@@ -67,6 +69,15 @@ class JITSymbolFlags {
6769
return (Flags & HasError) == HasError;
6870
}
6971

72+
/// @brief Returns true if this symbol has been fully materialized (i.e. is
73+
/// callable).
74+
bool isMaterialized() const { return !(Flags & NotMaterialized); }
75+
76+
/// @brief Returns true if this symbol is in the process of being
77+
/// materialized. This is generally only of interest as an
78+
/// implementation detail to JIT infrastructure.
79+
bool isMaterializing() const { return Flags & Materializing; }
80+
7081
/// @brief Returns true if the Weak flag is set.
7182
bool isWeak() const {
7283
return (Flags & Weak) == Weak;
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
//===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// Contains core ORC APIs.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_EXECUTIONENGINE_ORC_CORE_H
15+
#define LLVM_EXECUTIONENGINE_ORC_CORE_H
16+
17+
#include "llvm/ExecutionEngine/JITSymbol.h"
18+
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
19+
20+
#include <deque>
21+
#include <map>
22+
#include <memory>
23+
#include <set>
24+
#include <vector>
25+
26+
namespace llvm {
27+
namespace orc {
28+
29+
class VSO;
30+
31+
/// @brief A set of symbol names (represented by SymbolStringPtrs for
32+
// efficiency).
33+
using SymbolNameSet = std::set<SymbolStringPtr>;
34+
35+
/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbols
36+
/// (address/flags pairs).
37+
using SymbolMap = std::map<SymbolStringPtr, JITSymbol>;
38+
39+
/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
40+
using SymbolFlagsMap = std::map<SymbolStringPtr, JITSymbolFlags>;
41+
42+
/// @brief A symbol query that returns results via a callback when results are
43+
/// ready.
44+
///
45+
/// makes a callback when all symbols are available.
46+
class AsynchronousSymbolQuery {
47+
public:
48+
49+
/// @brief Callback to notify client that symbols have been resolved.
50+
using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
51+
52+
/// @brief Callback to notify client that symbols are ready for execution.
53+
using SymbolsReadyCallback = std::function<void(Error)>;
54+
55+
/// @brief Create a query for the given symbols, notify-resolved and
56+
/// notify-ready callbacks.
57+
AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
58+
SymbolsResolvedCallback NotifySymbolsResolved,
59+
SymbolsReadyCallback NotifySymbolsReady);
60+
61+
/// @brief Notify client that the query failed.
62+
///
63+
/// If the notify-resolved callback has not been made yet, then it is called
64+
/// with the given error, and the notify-finalized callback is never made.
65+
///
66+
/// If the notify-resolved callback has already been made then then the
67+
/// notify-finalized callback is called with the given error.
68+
///
69+
/// It is illegal to call setFailed after both callbacks have been made.
70+
void setFailed(Error Err);
71+
72+
/// @brief Set the resolved symbol information for the given symbol name.
73+
///
74+
/// If this symbol was the last one not resolved, this will trigger a call to
75+
/// the notify-finalized callback passing the completed sybol map.
76+
void setDefinition(SymbolStringPtr Name, JITSymbol Sym);
77+
78+
/// @brief Notify the query that a requested symbol is ready for execution.
79+
///
80+
/// This decrements the query's internal count of not-yet-ready symbols. If
81+
/// this call to notifySymbolFinalized sets the counter to zero, it will call
82+
/// the notify-finalized callback with Error::success as the value.
83+
void notifySymbolFinalized();
84+
private:
85+
SymbolMap Symbols;
86+
size_t OutstandingResolutions = 0;
87+
size_t OutstandingFinalizations = 0;
88+
SymbolsResolvedCallback NotifySymbolsResolved;
89+
SymbolsReadyCallback NotifySymbolsReady;
90+
};
91+
92+
/// @brief Represents a source of symbol definitions which may be materialized
93+
/// (turned into data / code through some materialization process) or
94+
/// discarded (if the definition is overridden by a stronger one).
95+
///
96+
/// SymbolSources are used when providing lazy definitions of symbols to VSOs.
97+
/// The VSO will call materialize when the address of a symbol is requested via
98+
/// the lookup method. The VSO will call discard if a stronger definition is
99+
/// added or already present.
100+
class SymbolSource {
101+
public:
102+
virtual ~SymbolSource() {}
103+
104+
/// @brief Implementations of this method should materialize the given
105+
/// symbols (plus any additional symbols required) by adding a
106+
/// Materializer to the ExecutionSession's MaterializationQueue.
107+
virtual Error materialize(VSO &V, SymbolNameSet Symbols) = 0;
108+
109+
/// @brief Implementations of this method should discard the given symbol
110+
/// from the source (e.g. if the source is an LLVM IR Module and the
111+
/// symbol is a function, delete the function body or mark it available
112+
/// externally).
113+
virtual void discard(VSO &V, SymbolStringPtr Name) = 0;
114+
private:
115+
virtual void anchor();
116+
};
117+
118+
/// @brief Represents a dynamic linkage unit in a JIT process.
119+
///
120+
/// VSO acts as a symbol table (symbol definitions can be set and the dylib
121+
/// queried to find symbol addresses) and as a key for tracking resources
122+
/// (since a VSO's address is fixed).
123+
class VSO {
124+
friend class ExecutionSession;
125+
public:
126+
127+
/// @brief
128+
enum RelativeLinkageStrength {
129+
NewDefinitionIsStronger,
130+
DuplicateDefinition,
131+
ExistingDefinitionIsStronger
132+
};
133+
134+
using SetDefinitionsResult =
135+
std::map<SymbolStringPtr, RelativeLinkageStrength>;
136+
using SourceWorkMap = std::map<SymbolSource*, SymbolNameSet>;
137+
138+
struct LookupResult {
139+
SourceWorkMap MaterializationWork;
140+
SymbolNameSet UnresolvedSymbols;
141+
};
142+
143+
VSO() = default;
144+
145+
VSO(const VSO&) = delete;
146+
VSO& operator=(const VSO&) = delete;
147+
VSO(VSO&&) = delete;
148+
VSO& operator=(VSO&&) = delete;
149+
150+
/// @brief Compare new linkage with existing linkage.
151+
static RelativeLinkageStrength
152+
compareLinkage(Optional<JITSymbolFlags> OldFlags,
153+
JITSymbolFlags NewFlags);
154+
155+
/// @brief Compare new linkage with an existing symbol's linkage.
156+
RelativeLinkageStrength compareLinkage(SymbolStringPtr Name,
157+
JITSymbolFlags NewFlags) const;
158+
159+
/// @brief Adds the given symbols to the mapping as resolved, finalized
160+
/// symbols.
161+
///
162+
/// FIXME: We can take this by const-ref once symbol-based laziness is
163+
/// removed.
164+
Error define(SymbolMap NewSymbols);
165+
166+
/// @brief Adds the given symbols to the mapping as lazy symbols.
167+
Error defineLazy(const SymbolFlagsMap &NewSymbols, SymbolSource &Source);
168+
169+
/// @brief Add the given symbol/address mappings to the dylib, but do not
170+
/// mark the symbols as finalized yet.
171+
void resolve(SymbolMap SymbolValues);
172+
173+
/// @brief Finalize the given symbols.
174+
void finalize(SymbolNameSet SymbolsToFinalize);
175+
176+
/// @brief Apply the given query to the given symbols in this VSO.
177+
///
178+
/// For symbols in this VSO that have already been materialized, their address
179+
/// will be set in the query immediately.
180+
///
181+
/// For symbols in this VSO that have not been materialized, the query will be
182+
/// recorded and the source for those symbols (plus the set of symbols to be
183+
/// materialized by that source) will be returned as the MaterializationWork
184+
/// field of the LookupResult.
185+
///
186+
/// Any symbols not found in this VSO will be returned in the
187+
/// UnresolvedSymbols field of the LookupResult.
188+
LookupResult lookup(AsynchronousSymbolQuery &Query, SymbolNameSet Symbols);
189+
190+
private:
191+
192+
class MaterializationInfo {
193+
public:
194+
MaterializationInfo(JITSymbolFlags Flags, AsynchronousSymbolQuery &Query);
195+
JITSymbolFlags getFlags() const;
196+
JITTargetAddress getAddress() const;
197+
void query(SymbolStringPtr Name, AsynchronousSymbolQuery &Query);
198+
void resolve(SymbolStringPtr Name, JITSymbol Sym);
199+
void finalize();
200+
private:
201+
JITSymbolFlags Flags;
202+
JITTargetAddress Address = 0;
203+
std::vector<AsynchronousSymbolQuery*> PendingResolution;
204+
std::vector<AsynchronousSymbolQuery*> PendingFinalization;
205+
};
206+
207+
class SymbolTableEntry {
208+
public:
209+
SymbolTableEntry(JITSymbolFlags Flags, SymbolSource &Source);
210+
SymbolTableEntry(JITSymbol Sym);
211+
SymbolTableEntry(SymbolTableEntry &&Other);
212+
~SymbolTableEntry();
213+
JITSymbolFlags getFlags() const;
214+
void replaceWithSource(VSO &V, SymbolStringPtr Name, JITSymbolFlags Flags,
215+
SymbolSource &NewSource);
216+
SymbolSource* query(SymbolStringPtr Name, AsynchronousSymbolQuery &Query);
217+
void resolve(VSO &V, SymbolStringPtr Name, JITSymbol Sym);
218+
void finalize();
219+
private:
220+
JITSymbolFlags Flags;
221+
union {
222+
JITTargetAddress Address;
223+
SymbolSource *Source;
224+
std::unique_ptr<MaterializationInfo> MatInfo;
225+
};
226+
};
227+
228+
std::map<SymbolStringPtr, SymbolTableEntry> Symbols;
229+
};
230+
231+
} // End namespace orc
232+
} // End namespace llvm
233+
234+
#endif // LLVM_EXECUTIONENGINE_ORC_CORE_H

include/llvm/ExecutionEngine/Orc/OrcError.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ namespace orc {
2222

2323
enum class OrcErrorCode : int {
2424
// RPC Errors
25-
JITSymbolNotFound = 1,
25+
DuplicateDefinition = 1,
26+
JITSymbolNotFound,
2627
RemoteAllocatorDoesNotExist,
2728
RemoteAllocatorIdAlreadyInUse,
2829
RemoteMProtectAddrUnrecognized,
@@ -39,6 +40,18 @@ enum class OrcErrorCode : int {
3940

4041
std::error_code orcError(OrcErrorCode ErrCode);
4142

43+
class DuplicateDefinition : public ErrorInfo<DuplicateDefinition> {
44+
public:
45+
static char ID;
46+
47+
DuplicateDefinition(std::string SymbolName);
48+
std::error_code convertToErrorCode() const override;
49+
void log(raw_ostream &OS) const override;
50+
const std::string &getSymbolName() const;
51+
private:
52+
std::string SymbolName;
53+
};
54+
4255
class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
4356
public:
4457
static char ID;

lib/ExecutionEngine/Orc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_llvm_library(LLVMOrcJIT
2+
Core.cpp
23
ExecutionUtils.cpp
34
IndirectionUtils.cpp
45
NullResolver.cpp

0 commit comments

Comments
 (0)