diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/ExecutionEngine/Orc/Core.h | 67 | ||||
| -rw-r--r-- | llvm/include/llvm/ExecutionEngine/Orc/Legacy.h | 4 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Core.cpp | 171 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h | 4 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h | 8 | ||||
| -rw-r--r-- | llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp | 95 | ||||
| -rw-r--r-- | llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp | 2 |
7 files changed, 214 insertions, 137 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h index 774084e841d..f47d13c96fb 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h @@ -118,7 +118,7 @@ public: /// notify-finalized callback is called with the given error. /// /// It is illegal to call setFailed after both callbacks have been made. - void notifyFailed(Error Err); + void notifyMaterializationFailed(Error Err); /// @brief Set the resolved symbol information for the given symbol name. /// @@ -206,6 +206,25 @@ createSymbolResolver(LookupFlagsFn &&LookupFlags, LookupFn &&Lookup) { std::forward<LookupFlagsFn>(LookupFlags), std::forward<LookupFn>(Lookup)); } +/// @brief Tracks responsibility for materialization. +class MaterializationResponsibility { +public: + MaterializationResponsibility(VSO &V, SymbolFlagsMap SymbolFlags); + MaterializationResponsibility(MaterializationResponsibility &&) = default; + MaterializationResponsibility & + operator=(MaterializationResponsibility &&) = default; + ~MaterializationResponsibility(); + MaterializationResponsibility takeResponsibility(SymbolNameSet Symbols); + const VSO &getTargetVSO() const { return V; } + void resolve(const SymbolMap &Symbols); + void finalize(); + void notifyMaterializationFailed(); + +private: + VSO &V; + SymbolFlagsMap SymbolFlags; +}; + /// @brief A MaterializationUnit represents a set of symbol definitions that can /// be materialized as a group, or individually discarded (when /// overriding definitions are encountered). @@ -224,13 +243,13 @@ public: /// @brief Implementations of this method should materialize all symbols /// in the materialzation unit, except for those that have been /// previously discarded. - virtual Error materialize(VSO &V) = 0; + virtual void materialize(MaterializationResponsibility R) = 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; + virtual void discard(const VSO &V, SymbolStringPtr Name) = 0; private: virtual void anchor(); @@ -254,11 +273,21 @@ public: using SetDefinitionsResult = std::map<SymbolStringPtr, RelativeLinkageStrength>; - using MaterializationUnitList = - std::vector<std::unique_ptr<MaterializationUnit>>; + struct Materializer { + public: + Materializer(std::unique_ptr<MaterializationUnit> MU, + MaterializationResponsibility R); + void operator()(); + + private: + std::unique_ptr<MaterializationUnit> MU; + MaterializationResponsibility R; + }; + + using MaterializerList = std::vector<Materializer>; struct LookupResult { - MaterializationUnitList MaterializationUnits; + MaterializerList Materializers; SymbolNameSet UnresolvedSymbols; }; @@ -321,11 +350,11 @@ public: private: class UnmaterializedInfo { public: - UnmaterializedInfo(size_t SymbolsRemaining, - std::unique_ptr<MaterializationUnit> MU); + UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU); + void discard(VSO &V, SymbolStringPtr Name); - uint64_t SymbolsRemaining; std::unique_ptr<MaterializationUnit> MU; + SymbolFlagsMap Symbols; }; using UnmaterializedInfoList = std::list<UnmaterializedInfo>; @@ -348,6 +377,7 @@ private: public: SymbolTableEntry(JITSymbolFlags SymbolFlags, UnmaterializedInfoIterator UnmaterializedInfoItr); + SymbolTableEntry(JITSymbolFlags SymbolFlags); SymbolTableEntry(JITEvaluatedSymbol Sym); SymbolTableEntry(SymbolTableEntry &&Other); SymbolTableEntry &operator=(SymbolTableEntry &&Other); @@ -360,8 +390,8 @@ private: void replaceWith(VSO &V, SymbolStringPtr Name, JITSymbolFlags Flags, UnmaterializedInfoIterator NewUMII); - // Move entry to materializing state, detach from UMII. - std::unique_ptr<MaterializationUnit> initMaterialize(VSO &V); + // Notify this entry that it is being materialized. + void notifyMaterializing(); // Move entry to resolved state. void resolve(VSO &V, JITEvaluatedSymbol Sym); @@ -380,8 +410,6 @@ private: void destroy(); }; - void detach(UnmaterializedInfoIterator UMII); - std::map<SymbolStringPtr, SymbolTableEntry> Symbols; UnmaterializedInfoList UnmaterializedInfos; MaterializingInfoMap MaterializingInfos; @@ -431,20 +459,11 @@ public: /// ExecutionSession. class MaterializeOnCurrentThread { public: - MaterializeOnCurrentThread(ExecutionSession &ES) : ES(ES) {} - - void operator()(VSO &V, std::unique_ptr<MaterializationUnit> MU) { - if (auto Err = MU->materialize(V)) - ES.reportError(std::move(Err)); - } - -private: - ExecutionSession &ES; + void operator()(VSO::Materializer M) { M(); } }; /// Materialization function object wrapper for the lookup method. -using MaterializationDispatcher = - std::function<void(VSO &V, std::unique_ptr<MaterializationUnit> S)>; +using MaterializationDispatcher = std::function<void(VSO::Materializer M)>; /// @brief Look up a set of symbols by searching a list of VSOs. /// diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h b/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h index 73debf3ad19..8ea3f7b7662 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h @@ -79,11 +79,11 @@ SymbolNameSet lookupWithLegacyFn(AsynchronousSymbolQuery &Query, Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); Query.finalizeSymbol(); } else { - Query.notifyFailed(Addr.takeError()); + Query.notifyMaterializationFailed(Addr.takeError()); return SymbolNameSet(); } } else if (auto Err = Sym.takeError()) { - Query.notifyFailed(std::move(Err)); + Query.notifyMaterializationFailed(std::move(Err)); return SymbolNameSet(); } else SymbolsNotFound.insert(S); diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index 3d7ef7d7c4e..da0c60455b9 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -123,7 +123,7 @@ AsynchronousSymbolQuery::AsynchronousSymbolQuery( OutstandingResolutions = OutstandingFinalizations = Symbols.size(); } -void AsynchronousSymbolQuery::notifyFailed(Error Err) { +void AsynchronousSymbolQuery::notifyMaterializationFailed(Error Err) { if (OutstandingResolutions != 0) NotifySymbolsResolved(std::move(Err)); else if (OutstandingFinalizations != 0) @@ -159,9 +159,76 @@ void AsynchronousSymbolQuery::finalizeSymbol() { NotifySymbolsReady(Error::success()); } +MaterializationResponsibility::MaterializationResponsibility( + VSO &V, SymbolFlagsMap SymbolFlags) + : V(V), SymbolFlags(std::move(SymbolFlags)) { + assert(!this->SymbolFlags.empty() && "Materializing nothing?"); +} + +MaterializationResponsibility::~MaterializationResponsibility() { + assert(SymbolFlags.empty() && + "All symbols should have been explicitly materialized or failed"); +} + +MaterializationResponsibility +MaterializationResponsibility::takeResponsibility(SymbolNameSet Symbols) { + SymbolFlagsMap ExtractedFlags; + + for (auto &S : Symbols) { + auto I = SymbolFlags.find(S); + ExtractedFlags.insert(*I); + SymbolFlags.erase(I); + } + + return MaterializationResponsibility(V, std::move(ExtractedFlags)); +} + +void MaterializationResponsibility::resolve(const SymbolMap &Symbols) { +#ifndef NDEBUG + for (auto &KV : Symbols) { + auto I = SymbolFlags.find(KV.first); + assert(I != SymbolFlags.end() && + "Resolving symbol outside this responsibility set"); + assert(KV.second.getFlags() == I->second && + "Resolving symbol with incorrect flags"); + } +#endif + V.resolve(Symbols); +} + +void MaterializationResponsibility::finalize() { + SymbolNameSet SymbolNames; + for (auto &KV : SymbolFlags) + SymbolNames.insert(KV.first); + SymbolFlags.clear(); + V.finalize(SymbolNames); +} + +void MaterializationResponsibility::notifyMaterializationFailed() { + SymbolNameSet SymbolNames; + for (auto &KV : SymbolFlags) + SymbolNames.insert(KV.first); + SymbolFlags.clear(); + V.notifyMaterializationFailed(SymbolNames); +} + +VSO::Materializer::Materializer(std::unique_ptr<MaterializationUnit> MU, + MaterializationResponsibility R) + : MU(std::move(MU)), R(std::move(R)) {} + +void VSO::Materializer::operator()() { MU->materialize(std::move(R)); } + VSO::UnmaterializedInfo::UnmaterializedInfo( - size_t SymbolsRemaining, std::unique_ptr<MaterializationUnit> MU) - : SymbolsRemaining(SymbolsRemaining), MU(std::move(MU)) {} + std::unique_ptr<MaterializationUnit> MU) + : MU(std::move(MU)), Symbols(this->MU->getSymbols()) {} + +void VSO::UnmaterializedInfo::discard(VSO &V, SymbolStringPtr Name) { + assert(MU && "No materializer attached"); + MU->discard(V, Name); + auto I = Symbols.find(Name); + assert(I != Symbols.end() && "Symbol not found in this MU"); + Symbols.erase(I); +} VSO::SymbolTableEntry::SymbolTableEntry(JITSymbolFlags Flags, UnmaterializedInfoIterator UMII) @@ -204,9 +271,9 @@ void VSO::SymbolTableEntry::replaceWith(VSO &V, SymbolStringPtr Name, assert(!Flags.isMaterializing() && "Attempting to replace definition during materialization?"); if (Flags.isLazy()) { - if (UMII->MU) - UMII->MU->discard(V, Name); - V.detach(UMII); + UMII->discard(V, Name); + if (UMII->Symbols.empty()) + V.UnmaterializedInfos.erase(UMII); } destroy(); Flags = Sym.getFlags(); @@ -219,39 +286,34 @@ void VSO::SymbolTableEntry::replaceWith(VSO &V, SymbolStringPtr Name, assert(!Flags.isMaterializing() && "Attempting to replace definition during materialization?"); if (Flags.isLazy()) { - if (UMII->MU) - UMII->MU->discard(V, Name); - V.detach(UMII); + UMII->discard(V, Name); + if (UMII->Symbols.empty()) + V.UnmaterializedInfos.erase(UMII); } destroy(); Flags = NewFlags; UMII = std::move(NewUMII); } -std::unique_ptr<MaterializationUnit> -VSO::SymbolTableEntry::initMaterialize(VSO &V) { - assert(Flags.isLazy() && "Can't materialize non-lazy symbol"); - auto TmpMU = std::move(UMII->MU); - V.detach(UMII); - destroy(); +void VSO::SymbolTableEntry::notifyMaterializing() { + assert(Flags.isLazy() && "Can only start materializing from lazy state"); + UMII.~UnmaterializedInfoIterator(); Flags &= ~JITSymbolFlags::Lazy; Flags |= JITSymbolFlags::Materializing; Address = 0; - return TmpMU; } void VSO::SymbolTableEntry::resolve(VSO &V, JITEvaluatedSymbol Sym) { - if (Flags.isLazy()) { - assert(!UMII->MU && "Resolving with MaterializationUnit still attached?"); - V.detach(UMII); - } - destroy(); + assert(!Flags.isLazy() && Flags.isMaterializing() && + "Can only resolve in materializing state"); Flags = Sym.getFlags(); Flags |= JITSymbolFlags::Materializing; Address = Sym.getAddress(); + assert(Address != 0 && "Can not resolve to null"); } void VSO::SymbolTableEntry::finalize() { + assert(Address != 0 && "Cannot finalize with null address"); assert(Flags.isMaterializing() && !Flags.isLazy() && "Symbol should be in materializing state"); Flags &= ~JITSymbolFlags::Materializing; @@ -262,14 +324,6 @@ void VSO::SymbolTableEntry::destroy() { UMII.~UnmaterializedInfoIterator(); } -void VSO::detach(UnmaterializedInfoIterator UMII) { - assert(UMII->SymbolsRemaining > 0 && - "Detaching from empty UnmaterializedInfo?"); - --UMII->SymbolsRemaining; - if (UMII->SymbolsRemaining == 0) - UnmaterializedInfos.erase(UMII); -} - VSO::RelativeLinkageStrength VSO::compareLinkage(Optional<JITSymbolFlags> Old, JITSymbolFlags New) { if (Old == None) @@ -325,14 +379,11 @@ Error VSO::define(SymbolMap NewSymbols) { Error VSO::defineLazy(std::unique_ptr<MaterializationUnit> MU) { - auto NewSymbols = MU->getSymbols(); - - auto UMII = UnmaterializedInfos.insert( - UnmaterializedInfos.end(), - UnmaterializedInfo(NewSymbols.size(), std::move(MU))); + auto UMII = UnmaterializedInfos.insert(UnmaterializedInfos.end(), + UnmaterializedInfo(std::move(MU))); Error Err = Error::success(); - for (auto &KV : NewSymbols) { + for (auto &KV : UMII->Symbols) { auto I = Symbols.find(KV.first); assert(I == Symbols.end() || @@ -345,8 +396,7 @@ Error VSO::defineLazy(std::unique_ptr<MaterializationUnit> MU) { // Discard weaker definitions. if (LinkageResult == ExistingDefinitionIsStronger) { - UMII->MU->discard(*this, KV.first); - detach(UMII); + UMII->discard(*this, KV.first); continue; } @@ -356,7 +406,7 @@ Error VSO::defineLazy(std::unique_ptr<MaterializationUnit> MU) { make_error<orc::DuplicateDefinition>(*KV.first)); // Duplicate definitions are discarded, so remove the duplicates from // materializer. - detach(UMII); + UMII->discard(*this, KV.first); continue; } @@ -368,6 +418,9 @@ Error VSO::defineLazy(std::unique_ptr<MaterializationUnit> MU) { std::make_pair(KV.first, SymbolTableEntry(KV.second, UMII))); } + if (UMII->Symbols.empty()) + UnmaterializedInfos.erase(UMII); + return Err; } @@ -417,10 +470,12 @@ void VSO::notifyMaterializationFailed(const SymbolNameSet &Names) { } for (auto &KV : ResolutionFailures) - KV.first->notifyFailed(make_error<FailedToResolve>(std::move(KV.second))); + KV.first->notifyMaterializationFailed( + make_error<FailedToResolve>(std::move(KV.second))); for (auto &KV : FinalizationFailures) - KV.first->notifyFailed(make_error<FailedToFinalize>(std::move(KV.second))); + KV.first->notifyMaterializationFailed( + make_error<FailedToFinalize>(std::move(KV.second))); } void VSO::finalize(const SymbolNameSet &SymbolsToFinalize) { @@ -461,7 +516,7 @@ SymbolNameSet VSO::lookupFlags(SymbolFlagsMap &Flags, SymbolNameSet Names) { VSO::LookupResult VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, SymbolNameSet Names) { - MaterializationUnitList MaterializationUnits; + MaterializerList Materializers; for (SymbolNameSet::iterator I = Names.begin(), E = Names.end(); I != E;) { auto Tmp = I++; @@ -474,11 +529,26 @@ VSO::LookupResult VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, // The symbol is in the VSO. Erase it from Names and proceed. Names.erase(Tmp); - // If this symbol has not been materialized yet, move it to materializing, - // then fall through to the materializing case below. + // If this symbol has not been materialized yet grab its materializer, + // move all of its sibling symbols to the materializing state, and + // delete its unmaterialized info. if (SymI->second.Flags.isLazy()) { - if (auto MU = SymI->second.initMaterialize(*this)) - MaterializationUnits.push_back(std::move(MU)); + assert(SymI->second.UMII->MU && + "Lazy symbol has no materializer attached"); + auto MU = std::move(SymI->second.UMII->MU); + auto SymbolFlags = std::move(SymI->second.UMII->Symbols); + UnmaterializedInfos.erase(SymI->second.UMII); + + for (auto &KV : SymbolFlags) { + auto SiblingI = Symbols.find(KV.first); + MaterializingInfos.insert( + std::make_pair(SiblingI->first, MaterializingInfo())); + SiblingI->second.notifyMaterializing(); + } + + Materializers.push_back(Materializer( + std::move(MU), + MaterializationResponsibility(*this, std::move(SymbolFlags)))); } // If this symbol already has a fully materialized value, just use it. @@ -492,10 +562,7 @@ VSO::LookupResult VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, // If this symbol is materializing, then get (or create) its // MaterializingInfo struct and appaend the query. auto J = MaterializingInfos.find(SymI->first); - if (J == MaterializingInfos.end()) - J = MaterializingInfos - .insert(std::make_pair(SymI->first, MaterializingInfo())) - .first; + assert(J != MaterializingInfos.end() && "Missing MaterializingInfo"); if (SymI->second.Address) { auto Sym = JITEvaluatedSymbol(SymI->second.Address, SymI->second.Flags); @@ -510,7 +577,7 @@ VSO::LookupResult VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, } } - return {std::move(MaterializationUnits), std::move(Names)}; + return {std::move(Materializers), std::move(Names)}; } Expected<SymbolMap> lookup(const std::vector<VSO *> &VSOs, SymbolNameSet Names, @@ -574,8 +641,8 @@ Expected<SymbolMap> lookup(const std::vector<VSO *> &VSOs, SymbolNameSet Names, auto LR = V->lookup(Query, UnresolvedSymbols); UnresolvedSymbols = std::move(LR.UnresolvedSymbols); - for (auto &MU : LR.MaterializationUnits) - DispatchMaterialization(*V, std::move(MU)); + for (auto &M : LR.Materializers) + DispatchMaterialization(std::move(M)); } #if LLVM_ENABLE_THREADS diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index ab0c9f07a14..268597cec66 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -155,11 +155,11 @@ private: if (auto Addr = Sym.getAddress()) Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); else { - Query->notifyFailed(Addr.takeError()); + Query->notifyMaterializationFailed(Addr.takeError()); return orc::SymbolNameSet(); } } else if (auto Err = Sym.takeError()) { - Query->notifyFailed(std::move(Err)); + Query->notifyMaterializationFailed(std::move(Err)); return orc::SymbolNameSet(); } else UnresolvedSymbols.insert(S); diff --git a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index 73af52055e8..67a270e6c45 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -177,22 +177,22 @@ class OrcMCJITReplacement : public ExecutionEngine { if (auto Addr = Sym.getAddress()) Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); else { - Query->notifyFailed(Addr.takeError()); + Query->notifyMaterializationFailed(Addr.takeError()); return SymbolNameSet(); } } else if (auto Err = Sym.takeError()) { - Query->notifyFailed(std::move(Err)); + Query->notifyMaterializationFailed(std::move(Err)); return SymbolNameSet(); } else { if (auto Sym2 = M.ClientResolver->findSymbol(*S)) { if (auto Addr = Sym2.getAddress()) Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym2.getFlags())); else { - Query->notifyFailed(Addr.takeError()); + Query->notifyMaterializationFailed(Addr.takeError()); return SymbolNameSet(); } } else if (auto Err = Sym2.takeError()) { - Query->notifyFailed(std::move(Err)); + Query->notifyMaterializationFailed(std::move(Err)); return SymbolNameSet(); } else UnresolvedSymbols.insert(S); diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index a2d815a53e3..ee2b36074b3 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -22,8 +22,9 @@ namespace { class SimpleMaterializationUnit : public MaterializationUnit { public: using GetSymbolsFunction = std::function<SymbolFlagsMap()>; - using MaterializeFunction = std::function<Error(VSO &)>; - using DiscardFunction = std::function<void(VSO &, SymbolStringPtr)>; + using MaterializeFunction = + std::function<void(MaterializationResponsibility)>; + using DiscardFunction = std::function<void(const VSO &, SymbolStringPtr)>; using DestructorFunction = std::function<void()>; SimpleMaterializationUnit( @@ -40,9 +41,11 @@ public: SymbolFlagsMap getSymbols() override { return GetSymbols(); } - Error materialize(VSO &V) override { return Materialize(V); } + void materialize(MaterializationResponsibility R) override { + Materialize(std::move(R)); + } - void discard(VSO &V, SymbolStringPtr Name) override { + void discard(const VSO &V, SymbolStringPtr Name) override { Discard(V, std::move(Name)); } @@ -103,7 +106,8 @@ TEST(CoreAPIsTest, AsynchronousSymbolQueryResolutionErrorOnly) { AsynchronousSymbolQuery Q(Names, OnResolution, OnReady); - Q.notifyFailed(make_error<StringError>("xyz", inconvertibleErrorCode())); + Q.notifyMaterializationFailed( + make_error<StringError>("xyz", inconvertibleErrorCode())); EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run"; EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run"; @@ -165,10 +169,10 @@ TEST(CoreAPIsTest, LookupFlagsTest) { [=]() { return SymbolFlagsMap({{Bar, BarFlags}}); }, - [](VSO &V) -> Error { + [](MaterializationResponsibility R) { llvm_unreachable("Symbol materialized on flags lookup"); }, - [](VSO &V, SymbolStringPtr Name) -> Error { + [](const VSO &V, SymbolStringPtr Name) { llvm_unreachable("Symbol finalized on flags lookup"); }); @@ -206,10 +210,10 @@ TEST(CoreAPIsTest, DropMaterializerWhenEmpty) { return SymbolFlagsMap( {{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}}); }, - [](VSO &V) -> Error { + [](MaterializationResponsibility R) { llvm_unreachable("Unexpected call to materialize"); }, - [&](VSO &V, SymbolStringPtr Name) { + [&](const VSO &V, SymbolStringPtr Name) { EXPECT_TRUE(Name == Foo || Name == Bar) << "Discard of unexpected symbol?"; }, @@ -253,19 +257,16 @@ TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) { {Bar, static_cast<JITSymbolFlags::FlagNames>( JITSymbolFlags::Exported | JITSymbolFlags::Weak)}}); }, - [&](VSO &V) { + [&](MaterializationResponsibility R) { assert(BarDiscarded && "Bar should have been discarded by this point"); SymbolMap SymbolsToResolve; SymbolsToResolve[Foo] = JITEvaluatedSymbol(FakeFooAddr, JITSymbolFlags::Exported); - V.resolve(std::move(SymbolsToResolve)); - SymbolNameSet SymbolsToFinalize; - SymbolsToFinalize.insert(Foo); - V.finalize(SymbolsToFinalize); + R.resolve(std::move(SymbolsToResolve)); + R.finalize(); FooMaterialized = true; - return Error::success(); }, - [&](VSO &V, SymbolStringPtr Name) { + [&](const VSO &V, SymbolStringPtr Name) { EXPECT_EQ(Name, Bar) << "Expected Name to be Bar"; BarDiscarded = true; }); @@ -300,8 +301,8 @@ TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) { auto LR = V.lookup(std::move(Q), Names); - for (auto &SWKV : LR.MaterializationUnits) - cantFail(SWKV->materialize(V)); + for (auto &M : LR.Materializers) + M(); EXPECT_TRUE(LR.UnresolvedSymbols.empty()) << "Could not find Foo in dylib"; EXPECT_TRUE(FooMaterialized) << "Foo was not materialized"; @@ -322,11 +323,8 @@ TEST(CoreAPIsTest, FailResolution) { return SymbolFlagsMap( {{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}}); }, - [&](VSO &V) -> Error { - V.notifyMaterializationFailed(Names); - return Error::success(); - }, - [&](VSO &V, SymbolStringPtr Name) { + [&](MaterializationResponsibility R) { R.notifyMaterializationFailed(); }, + [&](const VSO &V, SymbolStringPtr Name) { llvm_unreachable("Unexpected call to discard"); }); @@ -361,8 +359,8 @@ TEST(CoreAPIsTest, FailResolution) { std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady); auto LR = V.lookup(std::move(Q), Names); - for (auto &SWKV : LR.MaterializationUnits) - cantFail(SWKV->materialize(V)); + for (auto &M : LR.Materializers) + M(); } TEST(CoreAPIsTest, FailFinalization) { @@ -375,19 +373,18 @@ TEST(CoreAPIsTest, FailFinalization) { auto MU = llvm::make_unique<SimpleMaterializationUnit>( [=]() { return SymbolFlagsMap( - {{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}}); + {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}); }, - [&](VSO &V) -> Error { + [&](MaterializationResponsibility R) { constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef; constexpr JITTargetAddress FakeBarAddr = 0xcafef00d; auto FooSym = JITEvaluatedSymbol(FakeFooAddr, JITSymbolFlags::Exported); auto BarSym = JITEvaluatedSymbol(FakeBarAddr, JITSymbolFlags::Exported); - V.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})); - V.notifyMaterializationFailed(Names); - return Error::success(); + R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})); + R.notifyMaterializationFailed(); }, - [&](VSO &V, SymbolStringPtr Name) { + [&](const VSO &V, SymbolStringPtr Name) { llvm_unreachable("Unexpected call to discard"); }); @@ -421,8 +418,8 @@ TEST(CoreAPIsTest, FailFinalization) { std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady); auto LR = V.lookup(std::move(Q), Names); - for (auto &SWKV : LR.MaterializationUnits) - cantFail(SWKV->materialize(V)); + for (auto &M : LR.Materializers) + M(); } TEST(CoreAPIsTest, TestLambdaSymbolResolver) { @@ -443,7 +440,7 @@ TEST(CoreAPIsTest, TestLambdaSymbolResolver) { }, [&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) { auto LR = V.lookup(std::move(Q), Symbols); - assert(LR.MaterializationUnits.empty() && + assert(LR.Materializers.empty() && "Test generated unexpected materialization work?"); return std::move(LR.UnresolvedSymbols); }); @@ -503,12 +500,11 @@ TEST(CoreAPIsTest, TestLookupWithUnthreadedMaterialization) { [=]() { return SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}); }, - [&](VSO &V) -> Error { - V.resolve({{Foo, FooSym}}); - V.finalize({Foo}); - return Error::success(); + [&](MaterializationResponsibility R) { + R.resolve({{Foo, FooSym}}); + R.finalize(); }, - [](VSO &V, SymbolStringPtr Name) -> Error { + [](const VSO &V, SymbolStringPtr Name) { llvm_unreachable("Not expecting finalization"); }); @@ -517,7 +513,7 @@ TEST(CoreAPIsTest, TestLookupWithUnthreadedMaterialization) { cantFail(V.defineLazy(std::move(MU))); auto FooLookupResult = - cantFail(lookup({&V}, Foo, MaterializeOnCurrentThread(ES))); + cantFail(lookup({&V}, Foo, MaterializeOnCurrentThread())); EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress()) << "lookup returned an incorrect address"; @@ -537,12 +533,11 @@ TEST(CoreAPIsTest, TestLookupWithThreadedMaterialization) { [=]() { return SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}); }, - [&](VSO &V) -> Error { - V.resolve({{Foo, FooSym}}); - V.finalize({Foo}); - return Error::success(); + [&](MaterializationResponsibility R) { + R.resolve({{Foo, FooSym}}); + R.finalize(); }, - [](VSO &V, SymbolStringPtr Name) -> Error { + [](const VSO &V, SymbolStringPtr Name) { llvm_unreachable("Not expecting finalization"); }); @@ -551,14 +546,10 @@ TEST(CoreAPIsTest, TestLookupWithThreadedMaterialization) { cantFail(V.defineLazy(std::move(MU))); std::thread MaterializationThread; - auto MaterializeOnNewThread = [&](VSO &V, - std::unique_ptr<MaterializationUnit> MU) { + auto MaterializeOnNewThread = [&](VSO::Materializer M) { // FIXME: Use move capture once we move to C++14. - std::shared_ptr<MaterializationUnit> SharedMU = std::move(MU); - MaterializationThread = std::thread([&ES, &V, SharedMU]() { - if (auto Err = SharedMU->materialize(V)) - ES.reportError(std::move(Err)); - }); + auto SharedM = std::make_shared<VSO::Materializer>(std::move(M)); + MaterializationThread = std::thread([SharedM]() { (*SharedM)(); }); }; auto FooLookupResult = diff --git a/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp index db29024f470..514aafaff43 100644 --- a/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp @@ -35,7 +35,7 @@ TEST(LegacyAPIInteropTest, QueryAgainstVSO) { auto Lookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Query, SymbolNameSet Symbols) { auto R = V.lookup(std::move(Query), Symbols); - EXPECT_TRUE(R.MaterializationUnits.empty()) + EXPECT_TRUE(R.Materializers.empty()) << "Query resulted in unexpected materialization work"; return std::move(R.UnresolvedSymbols); }; |

