llvm.org GIT mirror llvm / 3642ab2
[Orc] Address the remaining move-capture FIXMEs This required spreading unique_function a bit more, which I think is a good thing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371843 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 30 days ago
15 changed file(s) with 69 addition(s) and 86 deletion(s). Raw diff Collapse all Expand all
113113 this->ES->setDispatchMaterialization(
114114
115115 [this](JITDylib &JD, std::unique_ptr MU) {
116 // FIXME: Switch to move capture once we have c 14.
117 auto SharedMU = std::shared_ptr(std::move(MU));
118 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
116 auto Work = [MU = std::move(MU), &JD] { MU->doMaterialize(JD); };
119117 CompileThreads.async(std::move(Work));
120118 });
121119 ExitOnErr(S.addSpeculationRuntime(this->ES->getMainJITDylib(), Mangle));
2222 #include
2323
2424 #include "llvm/ADT/BitmaskEnum.h"
25 #include "llvm/ADT/FunctionExtras.h"
2526 #include "llvm/ADT/StringRef.h"
2627 #include "llvm/Support/Error.h"
2728
216217 /// Represents a symbol in the JIT.
217218 class JITSymbol {
218219 public:
219 using GetAddressFtor = std::function()>;
220 using GetAddressFtor = unique_function()>;
220221
221222 /// Create a 'null' symbol, used to represent a "symbol not found"
222223 /// result from a successful (non-erroneous) lookup.
324325 public:
325326 using LookupSet = std::set;
326327 using LookupResult = std::map;
327 using OnResolvedFunction = std::function)>;
328 using OnResolvedFunction = unique_function)>;
328329
329330 virtual ~JITSymbolResolver() = default;
330331
1313 #define LLVM_EXECUTIONENGINE_ORC_CORE_H
1414
1515 #include "llvm/ADT/BitmaskEnum.h"
16 #include "llvm/ADT/FunctionExtras.h"
1617 #include "llvm/ExecutionEngine/JITSymbol.h"
1718 #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
1819 #include "llvm/ExecutionEngine/OrcV1Deprecation.h"
106107 raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
107108
108109 /// Callback to notify client that symbols have been resolved.
109 using SymbolsResolvedCallback = std::function)>;
110 using SymbolsResolvedCallback = unique_function)>;
110111
111112 /// Callback to register the dependencies for a given query.
112113 using RegisterDependenciesFunction =
4848 switch (EmitState) {
4949 case NotEmitted:
5050 if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
51 // Create a std::string version of Name to capture here - the argument
52 // (a StringRef) may go away before the lambda is executed.
53 // FIXME: Use capture-init when we move to C++14.
54 std::string PName = Name;
5551 JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV);
56 auto GetAddress =
57 [this, ExportedSymbolsOnly, PName, &B]() -> Expected {
58 if (this->EmitState == Emitting)
59 return 0;
60 else if (this->EmitState == NotEmitted) {
61 this->EmitState = Emitting;
62 if (auto Err = this->emitToBaseLayer(B))
63 return std::move(Err);
64 this->EmitState = Emitted;
65 }
66 if (auto Sym = B.findSymbolIn(K, PName, ExportedSymbolsOnly))
67 return Sym.getAddress();
68 else if (auto Err = Sym.takeError())
52 auto GetAddress = [this, ExportedSymbolsOnly, Name = Name.str(),
53 &B]() -> Expected {
54 if (this->EmitState == Emitting)
55 return 0;
56 else if (this->EmitState == NotEmitted) {
57 this->EmitState = Emitting;
58 if (auto Err = this->emitToBaseLayer(B))
6959 return std::move(Err);
70 else
71 llvm_unreachable("Successful symbol lookup should return "
72 "definition address here");
60 this->EmitState = Emitted;
61 }
62 if (auto Sym = B.findSymbolIn(K, Name, ExportedSymbolsOnly))
63 return Sym.getAddress();
64 else if (auto Err = Sym.takeError())
65 return std::move(Err);
66 else
67 llvm_unreachable("Successful symbol lookup should return "
68 "definition address here");
7369 };
7470 return JITSymbol(std::move(GetAddress), Flags);
7571 } else
358358 {
359359 assert(KeyName != nullptr && "No keyname pointer");
360360 std::lock_guard Lock(SerializersMutex);
361 // FIXME: Move capture Serialize once we have C++14.
362361 Serializers[ErrorInfoT::classID()] =
363 [KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error {
362 [KeyName, Serialize = std::move(Serialize)](
363 ChannelT &C, const ErrorInfoBase &EIB) -> Error {
364364 assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
365365 "Serializer called for wrong error type");
366366 if (auto Err = serializeSeq(C, *KeyName))
14121412 using ErrorReturn = typename RTraits::ErrorReturnType;
14131413 using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
14141414
1415 // FIXME: Stack allocate and move this into the handler once LLVM builds
1416 // with C++14.
1417 auto Promise = std::make_shared();
1418 auto FutureResult = Promise->get_future();
1415 ErrorReturnPromise Promise;
1416 auto FutureResult = Promise.get_future();
14191417
14201418 if (auto Err = this->template appendCallAsync(
1421 [Promise](ErrorReturn RetOrErr) {
1422 Promise->set_value(std::move(RetOrErr));
1419 [Promise = std::move(Promise)](ErrorReturn RetOrErr) {
1420 Promise.set_value(std::move(RetOrErr));
14231421 return Error::success();
14241422 },
14251423 Args...)) {
15971595 // outstanding calls count, then poke the condition variable.
15981596 using ArgType = typename detail::ResponseHandlerArg<
15991597 typename detail::HandlerTraits::Type>::ArgType;
1600 // FIXME: Move handler into wrapped handler once we have C++14.
1601 auto WrappedHandler = [this, Handler](ArgType Arg) {
1598 auto WrappedHandler = [this, Handler = std::move(Handler)](ArgType Arg) {
16021599 auto Err = Handler(std::move(Arg));
16031600 std::unique_lock Lock(M);
16041601 --NumOutstandingCalls;
136136 RemoteSymbolId Id)
137137 : C(C), Id(Id) {}
138138
139 RemoteSymbolMaterializer(const RemoteSymbolMaterializer &Other)
140 : C(Other.C), Id(Other.Id) {
141 // FIXME: This is a horrible, auto_ptr-style, copy-as-move operation.
142 // It should be removed as soon as LLVM has C++14's generalized
143 // lambda capture (at which point the materializer can be moved
144 // into the lambda in remoteToJITSymbol below).
145 const_cast(Other).Id = 0;
139 RemoteSymbolMaterializer(RemoteSymbolMaterializer &&Other)
140 : C(Other.C), Id(Other.Id) {
141 Other.Id = 0;
146142 }
147143
148 RemoteSymbolMaterializer&
149 operator=(const RemoteSymbolMaterializer&) = delete;
144 RemoteSymbolMaterializer &operator=(RemoteSymbolMaterializer &&) = delete;
150145
151146 /// Release the remote symbol.
152147 ~RemoteSymbolMaterializer() {
217212 return nullptr;
218213 // else...
219214 RemoteSymbolMaterializer RSM(*this, RemoteSym.first);
220 auto Sym =
221 JITSymbol([RSM]() mutable { return RSM.materialize(); },
222 RemoteSym.second);
215 auto Sym = JITSymbol(
216 [RSM = std::move(RSM)]() mutable { return RSM.materialize(); },
217 RemoteSym.second);
223218 return Sym;
224219 } else
225220 return RemoteSymOrErr.takeError();
1212 #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
1313 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
1414
15 #include "llvm/ADT/FunctionExtras.h"
1516 #include "llvm/ADT/STLExtras.h"
1617 #include "llvm/ADT/StringRef.h"
1718 #include "llvm/DebugInfo/DIContext.h"
270271 std::unique_ptr UnderlyingBuffer,
271272 RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
272273 bool ProcessAllSections,
273 std::function,
274 std::map)>
274 unique_function,
275 std::map)>
275276 OnLoaded,
276 std::function OnEmitted);
277 unique_function OnEmitted);
277278
278279 // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
279280 // interface.
290291 // but ORC's RTDyldObjectLinkingLayer2. Internally it constructs a RuntimeDyld
291292 // instance and uses continuation passing to perform the fix-up and finalize
292293 // steps asynchronously.
293 void jitLinkForORC(object::ObjectFile &Obj,
294 std::unique_ptr UnderlyingBuffer,
295 RuntimeDyld::MemoryManager &MemMgr,
296 JITSymbolResolver &Resolver, bool ProcessAllSections,
297 std::function,
298 std::map)>
299 OnLoaded,
300 std::function OnEmitted);
294 void jitLinkForORC(
295 object::ObjectFile &Obj, std::unique_ptr UnderlyingBuffer,
296 RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
297 bool ProcessAllSections,
298 unique_function,
299 std::map)>
300 OnLoaded,
301 unique_function OnEmitted);
301302
302303 } // end namespace llvm
303304
1212 #ifndef LLVM_SUPPORT_THREAD_POOL_H
1313 #define LLVM_SUPPORT_THREAD_POOL_H
1414
15 #include "llvm/ADT/FunctionExtras.h"
1516 #include "llvm/Config/llvm-config.h"
1617 #include "llvm/Support/thread.h"
1718
3435 /// for some work to become available.
3536 class ThreadPool {
3637 public:
37 using TaskTy = std::function;
38 using TaskTy = unique_function;
3839 using PackagedTaskTy = std::packaged_task;
3940
4041 /// Construct a pool with the number of threads found by
131131 CompileThreads = std::make_unique(S.NumCompileThreads);
132132 ES->setDispatchMaterialization(
133133 [this](JITDylib &JD, std::unique_ptr MU) {
134 // FIXME: Switch to move capture once we have c++14.
135 auto SharedMU = std::shared_ptr(std::move(MU));
136 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
134 auto Work = [MU = std::move(MU), &JD] { MU->doMaterialize(JD); };
137135 CompileThreads->async(std::move(Work));
138136 });
139137 }
2222 for (auto &S : Symbols)
2323 InternedSymbols.insert(ES.intern(S));
2424
25 auto OnResolvedWithUnwrap = [OnResolved](Expected InternedResult) {
25 auto OnResolvedWithUnwrap = [OnResolved = std::move(OnResolved)](
26 Expected InternedResult) mutable {
2627 if (!InternedResult) {
2728 OnResolved(InternedResult.takeError());
2829 return;
3536 };
3637
3738 auto Q = std::make_shared(
38 InternedSymbols, SymbolState::Resolved, OnResolvedWithUnwrap);
39 InternedSymbols, SymbolState::Resolved, std::move(OnResolvedWithUnwrap));
3940
4041 auto Unresolved = R.lookup(Q, InternedSymbols);
4142 if (Unresolved.empty()) {
2626
2727 // Build an OnResolve callback to unwrap the interned strings and pass them
2828 // to the OnResolved callback.
29 // FIXME: Switch to move capture of OnResolved once we have c++14.
3029 auto OnResolvedWithUnwrap =
31 [OnResolved](Expected InternedResult) {
30 [OnResolved = std::move(OnResolved)](
31 Expected InternedResult) mutable {
3232 if (!InternedResult) {
3333 OnResolved(InternedResult.takeError());
3434 return;
4949 MR.getTargetJITDylib().withSearchOrderDo(
5050 [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
5151 ES.lookup(SearchOrder, InternedSymbols, SymbolState::Resolved,
52 OnResolvedWithUnwrap, RegisterDependencies);
52 std::move(OnResolvedWithUnwrap), RegisterDependencies);
5353 }
5454
5555 Expected getResponsibilitySet(const LookupSet &Symbols) {
132132
133133 JITDylibSearchOrderResolver Resolver(*SharedR);
134134
135 // FIXME: Switch to move-capture for the 'O' buffer once we have c++14.
136 MemoryBuffer *UnownedObjBuffer = O.release();
137135 jitLinkForORC(
138136 **Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections,
139137 [this, K, SharedR, &Obj, InternalSymbols](
142140 return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo),
143141 ResolvedSymbols, *InternalSymbols);
144142 },
145 [this, K, SharedR, UnownedObjBuffer](Error Err) {
146 std::unique_ptr ObjBuffer(UnownedObjBuffer);
147 onObjEmit(K, std::move(ObjBuffer), *SharedR, std::move(Err));
143 [this, K, SharedR, O = std::move(O)](Error Err) mutable {
144 onObjEmit(K, std::move(O), *SharedR, std::move(Err));
148145 });
149146 }
150147
11791179 }
11801180
11811181 void RuntimeDyldImpl::finalizeAsync(
1182 std::unique_ptr This, std::function OnEmitted,
1182 std::unique_ptr This,
1183 unique_function OnEmitted,
11831184 std::unique_ptr UnderlyingBuffer) {
11841185
1185 // FIXME: Move-capture OnRelocsApplied and UnderlyingBuffer once we have
1186 // c++14.
1187 auto SharedUnderlyingBuffer =
1188 std::shared_ptr(std::move(UnderlyingBuffer));
11891186 auto SharedThis = std::shared_ptr(std::move(This));
11901187 auto PostResolveContinuation =
1191 [SharedThis, OnEmitted, SharedUnderlyingBuffer](
1192 Expected Result) {
1188 [SharedThis, OnEmitted = std::move(OnEmitted),
1189 UnderlyingBuffer = std::move(UnderlyingBuffer)](
1190 Expected Result) mutable {
11931191 if (!Result) {
11941192 OnEmitted(Result.takeError());
11951193 return;
12231221 }
12241222
12251223 if (!Symbols.empty()) {
1226 SharedThis->Resolver.lookup(Symbols, PostResolveContinuation);
1224 SharedThis->Resolver.lookup(Symbols, std::move(PostResolveContinuation));
12271225 } else
12281226 PostResolveContinuation(std::map());
12291227 }
13991397 std::unique_ptr UnderlyingBuffer,
14001398 RuntimeDyld::MemoryManager &MemMgr,
14011399 JITSymbolResolver &Resolver, bool ProcessAllSections,
1402 std::function
1400 unique_function
14031401 std::unique_ptr LoadedObj,
14041402 std::map)>
14051403 OnLoaded,
1406 std::function OnEmitted) {
1404 unique_function OnEmitted) {
14071405
14081406 RuntimeDyld RTDyld(MemMgr, Resolver);
14091407 RTDyld.setProcessAllSections(ProcessAllSections);
548548 void resolveLocalRelocations();
549549
550550 static void finalizeAsync(std::unique_ptr This,
551 std::function OnEmitted,
551 unique_function OnEmitted,
552552 std::unique_ptr UnderlyingBuffer);
553553
554554 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
11011101 std::thread MaterializationThread;
11021102 ES.setDispatchMaterialization(
11031103 [&](JITDylib &JD, std::unique_ptr MU) {
1104 auto SharedMU = std::shared_ptr(std::move(MU));
11051104 MaterializationThread =
1106 std::thread([SharedMU, &JD]() { SharedMU->doMaterialize(JD); });
1105 std::thread([MU = std::move(MU), &JD] { MU->doMaterialize(JD); });
11071106 });
11081107
11091108 cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));