[llvm] r337595 - [ORC] Add new symbol lookup methods to ExecutionSessionBase in preparation for

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 20 11:31:54 PDT 2018


Author: lhames
Date: Fri Jul 20 11:31:53 2018
New Revision: 337595

URL: http://llvm.org/viewvc/llvm-project?rev=337595&view=rev
Log:
[ORC] Add new symbol lookup methods to ExecutionSessionBase in preparation for
deprecating SymbolResolver and AsynchronousSymbolQuery.

Both lookup overloads take a VSO search order to perform the lookup. The first
overload is non-blocking and takes OnResolved and OnReady callbacks. The second
is blocking, takes a boolean flag to indicate whether to wait until all symbols
are ready, and returns a SymbolMap. Both overloads take a RegisterDependencies
function to register symbol dependencies (if any) on the query.

Modified:
    llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h
    llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
    llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp
    llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
    llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
    llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp

Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h Fri Jul 20 11:31:53 2018
@@ -69,8 +69,23 @@ raw_ostream &operator<<(raw_ostream &OS,
 /// A list of VSO pointers.
 using VSOList = std::vector<VSO *>;
 
+/// Render a VSOList.
 raw_ostream &operator<<(raw_ostream &OS, const VSOList &VSOs);
 
+/// Callback to notify client that symbols have been resolved.
+using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
+
+/// Callback to notify client that symbols are ready for execution.
+using SymbolsReadyCallback = std::function<void(Error)>;
+
+/// Callback to register the dependencies for a given query.
+using RegisterDependenciesFunction =
+    std::function<void(const SymbolDependenceMap &)>;
+
+/// This can be used as the value for a RegisterDependenciesFunction if there
+/// are no dependants to register with.
+extern RegisterDependenciesFunction NoDependenciesToRegister;
+
 /// Used to notify a VSO that the given set of symbols failed to materialize.
 class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
 public:
@@ -122,6 +137,9 @@ public:
   ///        into.
   VSO &getTargetVSO() const { return V; }
 
+  /// Returns the symbol flags map for this responsibility instance.
+  SymbolFlagsMap getSymbols() { return SymbolFlags; }
+
   /// Returns the names of any symbols covered by this
   /// MaterializationResponsibility object that have queries pending. This
   /// information can be used to return responsibility for unrequested symbols
@@ -223,6 +241,9 @@ private:
   virtual void discard(const VSO &V, SymbolStringPtr Name) = 0;
 };
 
+using MaterializationUnitList =
+    std::vector<std::unique_ptr<MaterializationUnit>>;
+
 /// A MaterializationUnit implementation for pre-existing absolute symbols.
 ///
 /// All symbols will be resolved and marked ready as soon as the unit is
@@ -322,6 +343,9 @@ buildSimpleReexportsAliasMap(VSO &Source
 
 /// Base utilities for ExecutionSession.
 class ExecutionSessionBase {
+  // FIXME: Remove this when we remove the old ORC layers.
+  friend class VSO;
+
 public:
   /// For reporting errors.
   using ErrorReporter = std::function<void(Error)>;
@@ -372,11 +396,50 @@ public:
   void releaseVModule(VModuleKey Key) { /* FIXME: Recycle keys */
   }
 
-  /// Cause the given query to fail with the given Error.
-  ///
-  /// This should only be used by legacy APIs and will be deprecated in the
-  /// future.
-  void failQuery(AsynchronousSymbolQuery &Q, Error Err);
+  void legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err);
+
+  using LegacyAsyncLookupFunction = std::function<SymbolNameSet(
+      std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names)>;
+
+  /// A legacy lookup function for JITSymbolResolverAdapter.
+  /// Do not use -- this will be removed soon.
+  Expected<SymbolMap>
+  legacyLookup(ExecutionSessionBase &ES, LegacyAsyncLookupFunction AsyncLookup,
+               SymbolNameSet Names, bool WaiUntilReady,
+               RegisterDependenciesFunction RegisterDependencies);
+
+  /// Search the given VSO list for the given symbols.
+  ///
+  ///
+  /// The OnResolve callback will be called once all requested symbols are
+  /// resolved, or if an error occurs prior to resolution.
+  ///
+  /// The OnReady callback will be called once all requested symbols are ready,
+  /// or if an error occurs after resolution but before all symbols are ready.
+  ///
+  /// If all symbols are found, the RegisterDependencies function will be called
+  /// while the session lock is held. This gives clients a chance to register
+  /// dependencies for on the queried symbols for any symbols they are
+  /// materializing (if a MaterializationResponsibility instance is present,
+  /// this can be implemented by calling
+  /// MaterializationResponsibility::addDependencies). If there are no
+  /// dependenant symbols for this query (e.g. it is being made by a top level
+  /// client to get an address to call) then the value NoDependenciesToRegister
+  /// can be used.
+  void lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
+              SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
+              RegisterDependenciesFunction RegisterDependencies);
+
+  /// Blocking version of lookup above. Returns the resolved symbol map.
+  /// If WaitUntilReady is true (the default), will not return until all
+  /// requested symbols are ready (or an error occurs). If WaitUntilReady is
+  /// false, will return as soon as all requested symbols are resolved,
+  /// or an error occurs. If WaitUntilReady is false and an error occurs
+  /// after resolution, the function will return a success value, but the
+  /// error will be reported via reportErrors.
+  Expected<SymbolMap> lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
+                             RegisterDependenciesFunction RegisterDependencies,
+                             bool WaitUntilReady = true);
 
   /// Materialize the given unit.
   void dispatchMaterialization(VSO &V,
@@ -394,12 +457,20 @@ private:
     MU->doMaterialize(V);
   }
 
+  void runOutstandingMUs();
+
   mutable std::recursive_mutex SessionMutex;
   std::shared_ptr<SymbolStringPool> SSP;
   VModuleKey LastKey = 0;
   ErrorReporter ReportError = logErrorsToStdErr;
   DispatchMaterializationFunction DispatchMaterialization =
       materializeOnCurrentThread;
+
+  // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
+  //        with callbacks from asynchronous queries.
+  mutable std::recursive_mutex OutstandingMUsMutex;
+  std::vector<std::pair<VSO *, std::unique_ptr<MaterializationUnit>>>
+      OutstandingMUs;
 };
 
 /// A symbol query that returns results via a callback when results are
@@ -411,21 +482,6 @@ class AsynchronousSymbolQuery {
   friend class VSO;
 
 public:
-  class ResolutionResult {
-  public:
-    ResolutionResult(SymbolMap Symbols, const SymbolDependenceMap &Dependencies)
-        : Symbols(std::move(Symbols)), Dependencies(Dependencies) {}
-
-    SymbolMap Symbols;
-    const SymbolDependenceMap &Dependencies;
-  };
-
-  /// Callback to notify client that symbols have been resolved.
-  using SymbolsResolvedCallback =
-      std::function<void(Expected<ResolutionResult>)>;
-
-  /// Callback to notify client that symbols are ready for execution.
-  using SymbolsReadyCallback = std::function<void(Error)>;
 
   /// Create a query for the given symbols, notify-resolved and
   ///        notify-ready callbacks.
@@ -485,6 +541,7 @@ private:
 class VSO {
   friend class AsynchronousSymbolQuery;
   friend class ExecutionSession;
+  friend class ExecutionSessionBase;
   friend class MaterializationResponsibility;
 public:
   using FallbackDefinitionGeneratorFunction =
@@ -493,9 +550,6 @@ public:
   using AsynchronousSymbolQuerySet =
       std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
 
-  using MaterializationUnitList =
-      std::vector<std::unique_ptr<MaterializationUnit>>;
-
   VSO(const VSO &) = delete;
   VSO &operator=(const VSO &) = delete;
   VSO(VSO &&) = delete;
@@ -547,8 +601,10 @@ public:
   void removeFromSearchOrder(VSO &V);
 
   /// Do something with the search order (run under the session lock).
-  template <typename Func> void withSearchOrderDo(Func F) {
-    ES.runSessionLocked([&]() { F(SearchOrder); });
+  template <typename Func>
+  auto withSearchOrderDo(Func &&F)
+      -> decltype(F(std::declval<const VSOList &>())) {
+    return ES.runSessionLocked([&]() { return F(SearchOrder); });
   }
 
   /// Define all symbols provided by the materialization unit to be part
@@ -579,6 +635,10 @@ public:
   ///        the flags for each symbol in Flags. Returns any unresolved symbols.
   SymbolFlagsMap lookupFlags(const SymbolNameSet &Names);
 
+  /// Dump current VSO state to OS.
+  void dump(raw_ostream &OS);
+
+  /// FIXME: Remove this when we remove the old ORC layers.
   /// Search the given VSOs in order for the symbols in Symbols. Results
   ///        (once they become available) will be returned via the given Query.
   ///
@@ -586,11 +646,8 @@ public:
   /// and the query will not be applied. The Query is not failed and can be
   /// re-used in a subsequent lookup once the symbols have been added, or
   /// manually failed.
-  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
-                       SymbolNameSet Names);
-
-  /// Dump current VSO state to OS.
-  void dump(raw_ostream &OS);
+  SymbolNameSet legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
+                             SymbolNameSet Names);
 
 private:
   using AsynchronousSymbolQueryList =
@@ -629,6 +686,12 @@ private:
   SymbolNameSet lookupFlagsImpl(SymbolFlagsMap &Flags,
                                 const SymbolNameSet &Names);
 
+  void lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
+                  SymbolNameSet &Unresolved, MaterializationUnitList &MUs);
+
+  void lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
+                      SymbolNameSet &Unresolved, MaterializationUnitList &MUs);
+
   LookupImplActionFlags
   lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
              std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
@@ -647,8 +710,8 @@ private:
 
   SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags);
 
-  void addDependencies(const SymbolFlagsMap &Dependents,
-                       const SymbolDependenceMap &Dependencies);
+  void addDependencies(const SymbolStringPtr &Name,
+                       const SymbolDependenceMap &Dependants);
 
   void resolve(const SymbolMap &Resolved);
 
@@ -656,8 +719,6 @@ private:
 
   void notifyFailed(const SymbolNameSet &FailedSymbols);
 
-  void runOutstandingMUs();
-
   ExecutionSessionBase &ES;
   std::string VSOName;
   SymbolMap Symbols;
@@ -665,11 +726,6 @@ private:
   MaterializingInfosMap MaterializingInfos;
   FallbackDefinitionGeneratorFunction FallbackDefinitionGenerator;
   VSOList SearchOrder;
-
-  // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
-  //        with callbacks from asynchronous queries.
-  mutable std::recursive_mutex OutstandingMUsMutex;
-  std::vector<std::unique_ptr<MaterializationUnit>> OutstandingMUs;
 };
 
 /// An ExecutionSession represents a running JIT program.
@@ -693,15 +749,6 @@ private:
   std::vector<std::unique_ptr<VSO>> VSOs;
 };
 
-using AsynchronousLookupFunction = std::function<SymbolNameSet(
-    std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names)>;
-
-/// Perform a blocking lookup on the given symbols.
-Expected<SymbolMap> blockingLookup(ExecutionSessionBase &ES,
-                                   AsynchronousLookupFunction AsyncLookup,
-                                   SymbolNameSet Names, bool WaiUntilReady,
-                                   MaterializationResponsibility *MR = nullptr);
-
 /// Look up the given names in the given VSOs.
 /// VSOs will be searched in order and no VSO pointer may be null.
 /// All symbols must be found within the given VSOs or an error

Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h Fri Jul 20 11:31:53 2018
@@ -146,11 +146,11 @@ lookupWithLegacyFn(ExecutionSession &ES,
         Query.notifySymbolReady();
         NewSymbolsResolved = true;
       } else {
-        ES.failQuery(Query, Addr.takeError());
+        ES.legacyFailQuery(Query, Addr.takeError());
         return SymbolNameSet();
       }
     } else if (auto Err = Sym.takeError()) {
-      ES.failQuery(Query, std::move(Err));
+      ES.legacyFailQuery(Query, std::move(Err));
       return SymbolNameSet();
     } else
       SymbolsNotFound.insert(S);

Modified: llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp Fri Jul 20 11:31:53 2018
@@ -23,6 +23,9 @@ namespace orc {
 char FailedToMaterialize::ID = 0;
 char SymbolsNotFound::ID = 0;
 
+RegisterDependenciesFunction NoDependenciesToRegister =
+    RegisterDependenciesFunction();
+
 void MaterializationUnit::anchor() {}
 
 raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
@@ -138,20 +141,361 @@ void SymbolsNotFound::log(raw_ostream &O
   OS << "Symbols not found: " << Symbols;
 }
 
-void ExecutionSessionBase::failQuery(AsynchronousSymbolQuery &Q, Error Err) {
-  bool DeliveredError = true;
-  runSessionLocked([&]() -> void {
+void ExecutionSessionBase::legacyFailQuery(AsynchronousSymbolQuery &Q,
+                                           Error Err) {
+  assert(!!Err && "Error should be in failure state");
+
+  bool SendErrorToQuery;
+  runSessionLocked([&]() {
     Q.detach();
-    if (Q.canStillFail())
-      Q.handleFailed(std::move(Err));
-    else
-      DeliveredError = false;
+    SendErrorToQuery = Q.canStillFail();
   });
 
-  if (!DeliveredError)
+  if (SendErrorToQuery)
+    Q.handleFailed(std::move(Err));
+  else
     reportError(std::move(Err));
 }
 
+Expected<SymbolMap> ExecutionSessionBase::legacyLookup(
+    ExecutionSessionBase &ES, LegacyAsyncLookupFunction AsyncLookup,
+    SymbolNameSet Names, bool WaitUntilReady,
+    RegisterDependenciesFunction RegisterDependencies) {
+#if LLVM_ENABLE_THREADS
+  // In the threaded case we use promises to return the results.
+  std::promise<SymbolMap> PromisedResult;
+  std::mutex ErrMutex;
+  Error ResolutionError = Error::success();
+  std::promise<void> PromisedReady;
+  Error ReadyError = Error::success();
+  auto OnResolve = [&](Expected<SymbolMap> R) {
+    if (R)
+      PromisedResult.set_value(std::move(*R));
+    else {
+      {
+        ErrorAsOutParameter _(&ResolutionError);
+        std::lock_guard<std::mutex> Lock(ErrMutex);
+        ResolutionError = R.takeError();
+      }
+      PromisedResult.set_value(SymbolMap());
+    }
+  };
+
+  std::function<void(Error)> OnReady;
+  if (WaitUntilReady) {
+    OnReady = [&](Error Err) {
+      if (Err) {
+        ErrorAsOutParameter _(&ReadyError);
+        std::lock_guard<std::mutex> Lock(ErrMutex);
+        ReadyError = std::move(Err);
+      }
+      PromisedReady.set_value();
+    };
+  } else {
+    OnReady = [&](Error Err) {
+      if (Err)
+        ES.reportError(std::move(Err));
+    };
+  }
+
+#else
+  SymbolMap Result;
+  Error ResolutionError = Error::success();
+  Error ReadyError = Error::success();
+
+  auto OnResolve = [&](Expected<SymbolMap> R) {
+    ErrorAsOutParameter _(&ResolutionError);
+    if (R)
+      Result = std::move(*R);
+    else
+      ResolutionError = R.takeError();
+  };
+
+  std::function<void(Error)> OnReady;
+  if (WaitUntilReady) {
+    OnReady = [&](Error Err) {
+      ErrorAsOutParameter _(&ReadyError);
+      if (Err)
+        ReadyError = std::move(Err);
+    };
+  } else {
+    OnReady = [&](Error Err) {
+      if (Err)
+        ES.reportError(std::move(Err));
+    };
+  }
+#endif
+
+  auto Query = std::make_shared<AsynchronousSymbolQuery>(
+      Names, std::move(OnResolve), std::move(OnReady));
+  // FIXME: This should be run session locked along with the registration code
+  // and error reporting below.
+  SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
+
+  // If the query was lodged successfully then register the dependencies,
+  // otherwise fail it with an error.
+  if (UnresolvedSymbols.empty())
+    RegisterDependencies(Query->QueryRegistrations);
+  else {
+    bool DeliverError = runSessionLocked([&]() {
+      Query->detach();
+      return Query->canStillFail();
+    });
+    auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols));
+    if (DeliverError)
+      Query->handleFailed(std::move(Err));
+    else
+      ES.reportError(std::move(Err));
+  }
+
+#if LLVM_ENABLE_THREADS
+  auto ResultFuture = PromisedResult.get_future();
+  auto Result = ResultFuture.get();
+
+  {
+    std::lock_guard<std::mutex> Lock(ErrMutex);
+    if (ResolutionError) {
+      // ReadyError will never be assigned. Consume the success value.
+      cantFail(std::move(ReadyError));
+      return std::move(ResolutionError);
+    }
+  }
+
+  if (WaitUntilReady) {
+    auto ReadyFuture = PromisedReady.get_future();
+    ReadyFuture.get();
+
+    {
+      std::lock_guard<std::mutex> Lock(ErrMutex);
+      if (ReadyError)
+        return std::move(ReadyError);
+    }
+  } else
+    cantFail(std::move(ReadyError));
+
+  return std::move(Result);
+
+#else
+  if (ResolutionError) {
+    // ReadyError will never be assigned. Consume the success value.
+    cantFail(std::move(ReadyError));
+    return std::move(ResolutionError);
+  }
+
+  if (ReadyError)
+    return std::move(ReadyError);
+
+  return Result;
+#endif
+}
+
+void ExecutionSessionBase::lookup(
+    const VSOList &VSOs, const SymbolNameSet &Symbols,
+    SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
+    RegisterDependenciesFunction RegisterDependencies) {
+
+  // lookup can be re-entered recursively if running on a single thread. Run any
+  // outstanding MUs in case this query depends on them, otherwise the main
+  // thread will starve waiting for a result from an MU that it failed to run.
+  runOutstandingMUs();
+
+  auto Unresolved = std::move(Symbols);
+  std::map<VSO *, MaterializationUnitList> MUsMap;
+  auto Q = std::make_shared<AsynchronousSymbolQuery>(
+      Symbols, std::move(OnResolve), std::move(OnReady));
+  bool QueryIsFullyResolved = false;
+  bool QueryIsFullyReady = false;
+  bool QueryFailed = false;
+
+  runSessionLocked([&]() {
+    for (auto *V : VSOs) {
+      assert(V && "VSOList entries must not be null");
+      assert(!MUsMap.count(V) &&
+             "VSOList should not contain duplicate entries");
+      V->lodgeQuery(Q, Unresolved, MUsMap[V]);
+    }
+
+    if (Unresolved.empty()) {
+      // Query lodged successfully.
+
+      // Record whether this query is fully ready / resolved. We will use
+      // this to call handleFullyResolved/handleFullyReady outside the session
+      // lock.
+      QueryIsFullyResolved = Q->isFullyResolved();
+      QueryIsFullyReady = Q->isFullyReady();
+
+      // Call the register dependencies function.
+      if (RegisterDependencies && !Q->QueryRegistrations.empty())
+        RegisterDependencies(Q->QueryRegistrations);
+    } else {
+      // Query failed due to unresolved symbols.
+      QueryFailed = true;
+
+      // Disconnect the query from its dependencies.
+      Q->detach();
+
+      // Replace the MUs.
+      for (auto &KV : MUsMap)
+        for (auto &MU : KV.second)
+          KV.first->replace(std::move(MU));
+    }
+  });
+
+  if (QueryFailed) {
+    Q->handleFailed(make_error<SymbolsNotFound>(std::move(Unresolved)));
+    return;
+  } else {
+    if (QueryIsFullyResolved)
+      Q->handleFullyResolved();
+    if (QueryIsFullyReady)
+      Q->handleFullyReady();
+  }
+
+  // Move the MUs to the OutstandingMUs list, then materialize.
+  {
+    std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
+
+    for (auto &KV : MUsMap)
+      for (auto &MU : KV.second)
+        OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU)));
+  }
+
+  runOutstandingMUs();
+}
+
+Expected<SymbolMap>
+ExecutionSessionBase::lookup(const VSOList &VSOs, const SymbolNameSet &Symbols,
+                             RegisterDependenciesFunction RegisterDependencies,
+                             bool WaitUntilReady) {
+#if LLVM_ENABLE_THREADS
+  // In the threaded case we use promises to return the results.
+  std::promise<SymbolMap> PromisedResult;
+  std::mutex ErrMutex;
+  Error ResolutionError = Error::success();
+  std::promise<void> PromisedReady;
+  Error ReadyError = Error::success();
+  auto OnResolve = [&](Expected<SymbolMap> R) {
+    if (R)
+      PromisedResult.set_value(std::move(*R));
+    else {
+      {
+        ErrorAsOutParameter _(&ResolutionError);
+        std::lock_guard<std::mutex> Lock(ErrMutex);
+        ResolutionError = R.takeError();
+      }
+      PromisedResult.set_value(SymbolMap());
+    }
+  };
+
+  std::function<void(Error)> OnReady;
+  if (WaitUntilReady) {
+    OnReady = [&](Error Err) {
+      if (Err) {
+        ErrorAsOutParameter _(&ReadyError);
+        std::lock_guard<std::mutex> Lock(ErrMutex);
+        ReadyError = std::move(Err);
+      }
+      PromisedReady.set_value();
+    };
+  } else {
+    OnReady = [&](Error Err) {
+      if (Err)
+        reportError(std::move(Err));
+    };
+  }
+
+#else
+  SymbolMap Result;
+  Error ResolutionError = Error::success();
+  Error ReadyError = Error::success();
+
+  auto OnResolve = [&](Expected<SymbolMap> R) {
+    ErrorAsOutParameter _(&ResolutionError);
+    if (R)
+      Result = std::move(R->Symbols);
+    else
+      ResolutionError = R.takeError();
+  };
+
+  std::function<void(Error)> OnReady;
+  if (WaitUntilReady) {
+    OnReady = [&](Error Err) {
+      ErrorAsOutParameter _(&ReadyError);
+      if (Err)
+        ReadyError = std::move(Err);
+    };
+  } else {
+    OnReady = [&](Error Err) {
+      if (Err)
+        reportError(std::move(Err));
+    };
+  }
+#endif
+
+  // Perform the asynchronous lookup.
+  lookup(VSOs, Symbols, OnResolve, OnReady, RegisterDependencies);
+
+#if LLVM_ENABLE_THREADS
+  auto ResultFuture = PromisedResult.get_future();
+  auto Result = ResultFuture.get();
+
+  {
+    std::lock_guard<std::mutex> Lock(ErrMutex);
+    if (ResolutionError) {
+      // ReadyError will never be assigned. Consume the success value.
+      cantFail(std::move(ReadyError));
+      return std::move(ResolutionError);
+    }
+  }
+
+  if (WaitUntilReady) {
+    auto ReadyFuture = PromisedReady.get_future();
+    ReadyFuture.get();
+
+    {
+      std::lock_guard<std::mutex> Lock(ErrMutex);
+      if (ReadyError)
+        return std::move(ReadyError);
+    }
+  } else
+    cantFail(std::move(ReadyError));
+
+  return std::move(Result);
+
+#else
+  if (ResolutionError) {
+    // ReadyError will never be assigned. Consume the success value.
+    cantFail(std::move(ReadyError));
+    return std::move(ResolutionError);
+  }
+
+  if (ReadyError)
+    return std::move(ReadyError);
+
+  return Result;
+#endif
+}
+
+void ExecutionSessionBase::runOutstandingMUs() {
+  while (1) {
+    std::pair<VSO *, std::unique_ptr<MaterializationUnit>> VSOAndMU;
+
+    {
+      std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
+      if (!OutstandingMUs.empty()) {
+        VSOAndMU = std::move(OutstandingMUs.back());
+        OutstandingMUs.pop_back();
+      }
+    }
+
+    if (VSOAndMU.first) {
+      assert(VSOAndMU.second && "VSO, but no MU?");
+      dispatchMaterialization(*VSOAndMU.first, std::move(VSOAndMU.second));
+    } else
+      break;
+  }
+}
+
 AsynchronousSymbolQuery::AsynchronousSymbolQuery(
     const SymbolNameSet &Symbols, SymbolsResolvedCallback NotifySymbolsResolved,
     SymbolsReadyCallback NotifySymbolsReady)
@@ -161,12 +505,6 @@ AsynchronousSymbolQuery::AsynchronousSym
 
   for (auto &S : Symbols)
     ResolvedSymbols[S] = nullptr;
-
-  // If the query is empty it is trivially resolved/ready.
-  if (Symbols.empty()) {
-    handleFullyResolved();
-    handleFullyReady();
-  }
 }
 
 void AsynchronousSymbolQuery::resolve(const SymbolStringPtr &Name,
@@ -183,8 +521,7 @@ void AsynchronousSymbolQuery::handleFull
   assert(NotYetResolvedCount == 0 && "Not fully resolved?");
   assert(NotifySymbolsResolved &&
          "NotifySymbolsResolved already called or error occurred");
-  NotifySymbolsResolved(
-      ResolutionResult(std::move(ResolvedSymbols), QueryRegistrations));
+  NotifySymbolsResolved(std::move(ResolvedSymbols));
   NotifySymbolsResolved = SymbolsResolvedCallback();
 }
 
@@ -349,7 +686,8 @@ MaterializationResponsibility::delegate(
 
 void MaterializationResponsibility::addDependencies(
     const SymbolDependenceMap &Dependencies) {
-  V.addDependencies(SymbolFlags, Dependencies);
+  for (auto &KV : SymbolFlags)
+    V.addDependencies(KV.first, Dependencies);
 }
 
 AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
@@ -384,8 +722,9 @@ ReExportsMaterializationUnit::ReExportsM
 void ReExportsMaterializationUnit::materialize(
     MaterializationResponsibility R) {
 
-  VSO &SrcV = SourceVSO ? *SourceVSO : R.getTargetVSO();
-  auto &ES = SrcV.getExecutionSession();
+  auto &ES = R.getTargetVSO().getExecutionSession();
+  VSO &TgtV = R.getTargetVSO();
+  VSO &SrcV = SourceVSO ? *SourceVSO : TgtV;
 
   // Find the set of requested aliases and aliasees. Return any unrequested
   // aliases back to the VSO so as to not prematurely materialize any aliasees.
@@ -434,9 +773,8 @@ void ReExportsMaterializationUnit::mater
       auto Tmp = I++;
 
       // Chain detected. Skip this symbol for this round.
-      if (&SrcV == &R.getTargetVSO() &&
-          (QueryAliases.count(Tmp->second.Aliasee) ||
-           RequestedAliases.count(Tmp->second.Aliasee)))
+      if (&SrcV == &TgtV && (QueryAliases.count(Tmp->second.Aliasee) ||
+                             RequestedAliases.count(Tmp->second.Aliasee)))
         continue;
 
       ResponsibilitySymbols.insert(Tmp->first);
@@ -459,49 +797,32 @@ void ReExportsMaterializationUnit::mater
 
     QueryInfos.pop_back();
 
-    auto OnResolve =
-        [QueryInfo,
-         &SrcV](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
-          if (RR) {
-            SymbolMap ResolutionMap;
-            SymbolNameSet Resolved;
-            for (auto &KV : QueryInfo->Aliases) {
-              assert(RR->Symbols.count(KV.second.Aliasee) &&
-                     "Result map missing entry?");
-              ResolutionMap[KV.first] = JITEvaluatedSymbol(
-                  RR->Symbols[KV.second.Aliasee].getAddress(),
-                  KV.second.AliasFlags);
-
-              // FIXME: We're creating a SymbolFlagsMap and a std::map of
-              // std::sets just to add one dependency here. This needs a
-              // re-think.
-              Resolved.insert(KV.first);
-            }
-            QueryInfo->R.resolve(ResolutionMap);
+    auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
+      R.addDependencies(Deps);
+    };
 
-            SymbolDependenceMap Deps;
-            Deps[&SrcV] = std::move(Resolved);
-            QueryInfo->R.addDependencies(Deps);
-
-            QueryInfo->R.finalize();
-          } else {
-            auto &ES = QueryInfo->R.getTargetVSO().getExecutionSession();
-            ES.reportError(RR.takeError());
-            QueryInfo->R.failMaterialization();
-          }
-        };
+    auto OnResolve = [QueryInfo](Expected<SymbolMap> Result) {
+      if (Result) {
+        SymbolMap ResolutionMap;
+        for (auto &KV : QueryInfo->Aliases) {
+          assert(Result->count(KV.second.Aliasee) &&
+                 "Result map missing entry?");
+          ResolutionMap[KV.first] = JITEvaluatedSymbol(
+              (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
+        }
+        QueryInfo->R.resolve(ResolutionMap);
+        QueryInfo->R.finalize();
+      } else {
+        auto &ES = QueryInfo->R.getTargetVSO().getExecutionSession();
+        ES.reportError(Result.takeError());
+        QueryInfo->R.failMaterialization();
+      }
+    };
 
     auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
 
-    auto Q = std::make_shared<AsynchronousSymbolQuery>(
-        QuerySymbols, std::move(OnResolve), std::move(OnReady));
-
-    auto Unresolved = SrcV.lookup(Q, std::move(QuerySymbols));
-
-    if (!Unresolved.empty()) {
-      ES.failQuery(*Q, make_error<SymbolsNotFound>(std::move(Unresolved)));
-      return;
-    }
+    ES.lookup({&SrcV}, QuerySymbols, std::move(OnResolve), std::move(OnReady),
+              std::move(RegisterDependencies));
   }
 }
 
@@ -642,40 +963,35 @@ SymbolNameSet VSO::getRequestedSymbols(c
   });
 }
 
-void VSO::addDependencies(const SymbolFlagsMap &Dependants,
+void VSO::addDependencies(const SymbolStringPtr &Name,
                           const SymbolDependenceMap &Dependencies) {
-  ES.runSessionLocked([&, this]() {
-    for (auto &KV : Dependants) {
-      const auto &Name = KV.first;
-      assert(Symbols.count(Name) && "Name not in symbol table");
-      assert((Symbols[Name].getFlags().isLazy() ||
-              Symbols[Name].getFlags().isMaterializing()) &&
-             "Symbol is not lazy or materializing");
-
-      auto &MI = MaterializingInfos[Name];
-      assert(!MI.IsFinalized && "Can not add dependencies to finalized symbol");
-
-      for (auto &KV : Dependencies) {
-        assert(KV.first && "Null VSO in dependency?");
-        auto &OtherVSO = *KV.first;
-        auto &DepsOnOtherVSO = MI.UnfinalizedDependencies[&OtherVSO];
-
-        for (auto &OtherSymbol : KV.second) {
-          auto &OtherMI = OtherVSO.MaterializingInfos[OtherSymbol];
-
-          if (OtherMI.IsFinalized)
-            transferFinalizedNodeDependencies(MI, Name, OtherMI);
-          else if (&OtherVSO != this || OtherSymbol != Name) {
-            OtherMI.Dependants[this].insert(Name);
-            DepsOnOtherVSO.insert(OtherSymbol);
-          }
-        }
-
-        if (DepsOnOtherVSO.empty())
-          MI.UnfinalizedDependencies.erase(&OtherVSO);
+  assert(Symbols.count(Name) && "Name not in symbol table");
+  assert((Symbols[Name].getFlags().isLazy() ||
+          Symbols[Name].getFlags().isMaterializing()) &&
+         "Symbol is not lazy or materializing");
+
+  auto &MI = MaterializingInfos[Name];
+  assert(!MI.IsFinalized && "Can not add dependencies to finalized symbol");
+
+  for (auto &KV : Dependencies) {
+    assert(KV.first && "Null VSO in dependency?");
+    auto &OtherVSO = *KV.first;
+    auto &DepsOnOtherVSO = MI.UnfinalizedDependencies[&OtherVSO];
+
+    for (auto &OtherSymbol : KV.second) {
+      auto &OtherMI = OtherVSO.MaterializingInfos[OtherSymbol];
+
+      if (OtherMI.IsFinalized)
+        transferFinalizedNodeDependencies(MI, Name, OtherMI);
+      else if (&OtherVSO != this || OtherSymbol != Name) {
+        OtherMI.Dependants[this].insert(Name);
+        DepsOnOtherVSO.insert(OtherSymbol);
       }
     }
-  });
+
+    if (DepsOnOtherVSO.empty())
+      MI.UnfinalizedDependencies.erase(&OtherVSO);
+  }
 }
 
 void VSO::resolve(const SymbolMap &Resolved) {
@@ -856,25 +1172,6 @@ void VSO::notifyFailed(const SymbolNameS
     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
 }
 
-void VSO::runOutstandingMUs() {
-  while (1) {
-    std::unique_ptr<MaterializationUnit> MU;
-
-    {
-      std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
-      if (!OutstandingMUs.empty()) {
-        MU = std::move(OutstandingMUs.back());
-        OutstandingMUs.pop_back();
-      }
-    }
-
-    if (MU)
-      ES.dispatchMaterialization(*this, std::move(MU));
-    else
-      break;
-  }
-}
-
 void VSO::setSearchOrder(VSOList NewSearchOrder, bool SearchThisVSOFirst) {
   if (SearchThisVSOFirst && NewSearchOrder.front() != this)
     NewSearchOrder.insert(NewSearchOrder.begin(), this);
@@ -939,11 +1236,89 @@ SymbolNameSet VSO::lookupFlagsImpl(Symbo
   return Unresolved;
 }
 
-SymbolNameSet VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
-                          SymbolNameSet Names) {
+void VSO::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
+                     SymbolNameSet &Unresolved, MaterializationUnitList &MUs) {
   assert(Q && "Query can not be null");
 
-  runOutstandingMUs();
+  lodgeQueryImpl(Q, Unresolved, MUs);
+  if (FallbackDefinitionGenerator && !Unresolved.empty()) {
+    auto FallbackDefs = FallbackDefinitionGenerator(*this, Unresolved);
+    if (!FallbackDefs.empty()) {
+      for (auto &D : FallbackDefs)
+        Unresolved.erase(D);
+      lodgeQueryImpl(Q, FallbackDefs, MUs);
+      assert(FallbackDefs.empty() &&
+             "All fallback defs should have been found by lookupImpl");
+    }
+  }
+}
+
+void VSO::lodgeQueryImpl(
+    std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved,
+    std::vector<std::unique_ptr<MaterializationUnit>> &MUs) {
+  for (auto I = Unresolved.begin(), E = Unresolved.end(); I != E;) {
+    auto TmpI = I++;
+    auto Name = *TmpI;
+
+    // Search for the name in Symbols. Skip it if not found.
+    auto SymI = Symbols.find(Name);
+    if (SymI == Symbols.end())
+      continue;
+
+    // If we found Name in V, remove it frome the Unresolved set and add it
+    // to the added set.
+    Unresolved.erase(TmpI);
+
+    // If the symbol has an address then resolve it.
+    if (SymI->second.getAddress() != 0)
+      Q->resolve(Name, SymI->second);
+
+    // If the symbol is lazy, get the MaterialiaztionUnit for it.
+    if (SymI->second.getFlags().isLazy()) {
+      assert(SymI->second.getAddress() == 0 &&
+             "Lazy symbol should not have a resolved address");
+      assert(!SymI->second.getFlags().isMaterializing() &&
+             "Materializing and lazy should not both be set");
+      auto UMII = UnmaterializedInfos.find(Name);
+      assert(UMII != UnmaterializedInfos.end() &&
+             "Lazy symbol should have UnmaterializedInfo");
+      auto MU = std::move(UMII->second->MU);
+      assert(MU != nullptr && "Materializer should not be null");
+
+      // Move all symbols associated with this MaterializationUnit into
+      // materializing state.
+      for (auto &KV : MU->getSymbols()) {
+        auto SymK = Symbols.find(KV.first);
+        auto Flags = SymK->second.getFlags();
+        Flags &= ~JITSymbolFlags::Lazy;
+        Flags |= JITSymbolFlags::Materializing;
+        SymK->second.setFlags(Flags);
+        UnmaterializedInfos.erase(KV.first);
+      }
+
+      // Add MU to the list of MaterializationUnits to be materialized.
+      MUs.push_back(std::move(MU));
+    } else if (!SymI->second.getFlags().isMaterializing()) {
+      // The symbol is neither lazy nor materializing. Finalize it and
+      // continue.
+      Q->notifySymbolReady();
+      continue;
+    }
+
+    // Add the query to the PendingQueries list.
+    assert(SymI->second.getFlags().isMaterializing() &&
+           "By this line the symbol should be materializing");
+    auto &MI = MaterializingInfos[Name];
+    MI.PendingQueries.push_back(Q);
+    Q->addQueryDependence(*this, Name);
+  }
+}
+
+SymbolNameSet VSO::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
+                                SymbolNameSet Names) {
+  assert(Q && "Query can not be null");
+
+  ES.runOutstandingMUs();
 
   LookupImplActionFlags ActionFlags = None;
   std::vector<std::unique_ptr<MaterializationUnit>> MUs;
@@ -978,11 +1353,11 @@ SymbolNameSet VSO::lookup(std::shared_pt
   //        callbacks from asynchronous queries.
   // Add MUs to the OutstandingMUs list.
   {
-    std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
+    std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex);
     for (auto &MU : MUs)
-      OutstandingMUs.push_back(std::move(MU));
+      ES.OutstandingMUs.push_back(make_pair(this, std::move(MU)));
   }
-  runOutstandingMUs();
+  ES.runOutstandingMUs();
 
   // Dispatch any required MaterializationUnits for materialization.
   // for (auto &MU : MUs)
@@ -1243,133 +1618,6 @@ VSO &ExecutionSession::createVSO(std::st
   });
 }
 
-Expected<SymbolMap> blockingLookup(ExecutionSessionBase &ES,
-                                   AsynchronousLookupFunction AsyncLookup,
-                                   SymbolNameSet Names, bool WaitUntilReady,
-                                   MaterializationResponsibility *MR) {
-
-#if LLVM_ENABLE_THREADS
-  // In the threaded case we use promises to return the results.
-  std::promise<SymbolMap> PromisedResult;
-  std::mutex ErrMutex;
-  Error ResolutionError = Error::success();
-  std::promise<void> PromisedReady;
-  Error ReadyError = Error::success();
-  auto OnResolve =
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
-        if (Result) {
-          if (MR)
-            MR->addDependencies(Result->Dependencies);
-          PromisedResult.set_value(std::move(Result->Symbols));
-        } else {
-          {
-            ErrorAsOutParameter _(&ResolutionError);
-            std::lock_guard<std::mutex> Lock(ErrMutex);
-            ResolutionError = Result.takeError();
-          }
-          PromisedResult.set_value(SymbolMap());
-        }
-      };
-
-  std::function<void(Error)> OnReady;
-  if (WaitUntilReady) {
-    OnReady = [&](Error Err) {
-      if (Err) {
-        ErrorAsOutParameter _(&ReadyError);
-        std::lock_guard<std::mutex> Lock(ErrMutex);
-        ReadyError = std::move(Err);
-      }
-      PromisedReady.set_value();
-    };
-  } else {
-    OnReady = [&](Error Err) {
-      if (Err)
-        ES.reportError(std::move(Err));
-    };
-  }
-
-#else
-  SymbolMap Result;
-  Error ResolutionError = Error::success();
-  Error ReadyError = Error::success();
-
-  auto OnResolve = [&](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
-    ErrorAsOutParameter _(&ResolutionError);
-    if (R) {
-      if (MR)
-        MR->addDependencies(R->Dependencies);
-      Result = std::move(R->Symbols);
-    } else
-      ResolutionError = R.takeError();
-  };
-
-  std::function<void(Error)> OnReady;
-  if (WaitUntilReady) {
-    OnReady = [&](Error Err) {
-      ErrorAsOutParameter _(&ReadyError);
-      if (Err)
-        ReadyError = std::move(Err);
-    };
-  } else {
-    OnReady = [&](Error Err) {
-      if (Err)
-        ES.reportError(std::move(Err));
-    };
-  }
-#endif
-
-  auto Query = std::make_shared<AsynchronousSymbolQuery>(
-      Names, std::move(OnResolve), std::move(OnReady));
-
-  SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
-
-  // If there are unresolved symbols then the query will never return.
-  // Fail it with ES.failQuery.
-  if (!UnresolvedSymbols.empty())
-    ES.failQuery(*Query,
-                 make_error<SymbolsNotFound>(std::move(UnresolvedSymbols)));
-
-#if LLVM_ENABLE_THREADS
-  auto ResultFuture = PromisedResult.get_future();
-  auto Result = ResultFuture.get();
-
-  {
-    std::lock_guard<std::mutex> Lock(ErrMutex);
-    if (ResolutionError) {
-      // ReadyError will never be assigned. Consume the success value.
-      cantFail(std::move(ReadyError));
-      return std::move(ResolutionError);
-    }
-  }
-
-  if (WaitUntilReady) {
-    auto ReadyFuture = PromisedReady.get_future();
-    ReadyFuture.get();
-
-    {
-      std::lock_guard<std::mutex> Lock(ErrMutex);
-      if (ReadyError)
-        return std::move(ReadyError);
-    }
-  } else
-    cantFail(std::move(ReadyError));
-
-  return std::move(Result);
-
-#else
-  if (ResolutionError) {
-    // ReadyError will never be assigned. Consume the success value.
-    cantFail(std::move(ReadyError));
-    return std::move(ResolutionError);
-  }
-
-  if (ReadyError)
-    return std::move(ReadyError);
-
-  return Result;
-#endif
-}
-
 Expected<SymbolMap> lookup(const VSOList &VSOs, SymbolNameSet Names) {
 
   if (VSOs.empty())
@@ -1377,18 +1625,7 @@ Expected<SymbolMap> lookup(const VSOList
 
   auto &ES = (*VSOs.begin())->getExecutionSession();
 
-  auto LookupFn = [&](std::shared_ptr<AsynchronousSymbolQuery> Q,
-                      SymbolNameSet Unresolved) {
-    for (auto *V : VSOs) {
-      assert(V && "VSOs entries must not be null");
-      if (Unresolved.empty())
-        break;
-      Unresolved = V->lookup(Q, std::move(Unresolved));
-    }
-    return Unresolved;
-  };
-
-  return blockingLookup(ES, std::move(LookupFn), Names, true);
+  return ES.lookup(VSOs, Names, NoDependenciesToRegister, true);
 }
 
 /// Look up a symbol by searching a list of VSOs.

Modified: llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp Fri Jul 20 11:31:53 2018
@@ -29,8 +29,14 @@ JITSymbolResolverAdapter::lookup(const L
     return R.lookup(std::move(Q), std::move(Unresolved));
   };
 
-  auto InternedResult = blockingLookup(ES, std::move(LookupFn),
-                                       std::move(InternedSymbols), false, MR);
+  auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
+    if (MR)
+      MR->addDependencies(Deps);
+  };
+
+  auto InternedResult =
+      ES.legacyLookup(ES, std::move(LookupFn), std::move(InternedSymbols),
+                      false, RegisterDependencies);
 
   if (!InternedResult)
     return InternedResult.takeError();

Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcCBindingsStack.h Fri Jul 20 11:31:53 2018
@@ -156,11 +156,11 @@ private:
             Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
             Query->notifySymbolReady();
           } else {
-            Stack.ES.failQuery(*Query, Addr.takeError());
+            Stack.ES.legacyFailQuery(*Query, Addr.takeError());
             return orc::SymbolNameSet();
           }
         } else if (auto Err = Sym.takeError()) {
-          Stack.ES.failQuery(*Query, std::move(Err));
+          Stack.ES.legacyFailQuery(*Query, std::move(Err));
           return orc::SymbolNameSet();
         } else
           UnresolvedSymbols.insert(S);

Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h Fri Jul 20 11:31:53 2018
@@ -178,11 +178,11 @@ class OrcMCJITReplacement : public Execu
             Query->notifySymbolReady();
             NewSymbolsResolved = true;
           } else {
-            M.ES.failQuery(*Query, Addr.takeError());
+            M.ES.legacyFailQuery(*Query, Addr.takeError());
             return SymbolNameSet();
           }
         } else if (auto Err = Sym.takeError()) {
-          M.ES.failQuery(*Query, std::move(Err));
+          M.ES.legacyFailQuery(*Query, std::move(Err));
           return SymbolNameSet();
         } else {
           if (auto Sym2 = M.ClientResolver->findSymbol(*S)) {
@@ -191,11 +191,11 @@ class OrcMCJITReplacement : public Execu
               Query->notifySymbolReady();
               NewSymbolsResolved = true;
             } else {
-              M.ES.failQuery(*Query, Addr.takeError());
+              M.ES.legacyFailQuery(*Query, Addr.takeError());
               return SymbolNameSet();
             }
           } else if (auto Err = Sym2.takeError()) {
-            M.ES.failQuery(*Query, std::move(Err));
+            M.ES.legacyFailQuery(*Query, std::move(Err));
             return SymbolNameSet();
           } else
             UnresolvedSymbols.insert(S);

Modified: llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp Fri Jul 20 11:31:53 2018
@@ -16,30 +16,23 @@ using namespace llvm::orc;
 
 class VSOSearchOrderResolver : public JITSymbolResolver {
 public:
-  VSOSearchOrderResolver(ExecutionSession &ES,
-                         MaterializationResponsibility &MR)
-      : ES(ES), MR(MR) {}
+  VSOSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
 
   Expected<LookupResult> lookup(const LookupSet &Symbols) {
+    auto &ES = MR.getTargetVSO().getExecutionSession();
     SymbolNameSet InternedSymbols;
 
     for (auto &S : Symbols)
       InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
 
-    auto AsyncLookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Q,
-                           SymbolNameSet Names) {
-      SymbolNameSet Unresolved = std::move(Names);
-      MR.getTargetVSO().withSearchOrderDo([&](const VSOList &SearchOrder) {
-        for (auto *V : SearchOrder) {
-          assert(V && "VSOList entry can not be null");
-          Unresolved = V->lookup(Q, std::move(Unresolved));
-        }
-      });
-      return Unresolved;
+    auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
+      MR.addDependencies(Deps);
     };
 
-    auto InternedResult = blockingLookup(
-        ES, std::move(AsyncLookup), std::move(InternedSymbols), false, &MR);
+    auto InternedResult =
+        MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
+          return ES.lookup(VSOs, InternedSymbols, RegisterDependencies, false);
+        });
 
     if (!InternedResult)
       return InternedResult.takeError();
@@ -52,6 +45,8 @@ public:
   }
 
   Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
+    auto &ES = MR.getTargetVSO().getExecutionSession();
+
     SymbolNameSet InternedSymbols;
 
     for (auto &S : Symbols)
@@ -75,7 +70,6 @@ public:
   }
 
 private:
-  ExecutionSession &ES;
   MaterializationResponsibility &MR;
 };
 
@@ -106,7 +100,7 @@ void RTDyldObjectLinkingLayer2::emit(Mat
 
   auto MemoryManager = GetMemoryManager(K);
 
-  VSOSearchOrderResolver Resolver(ES, R);
+  VSOSearchOrderResolver Resolver(R);
   auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
   RTDyld->setProcessAllSections(ProcessAllSections);
 

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp Fri Jul 20 11:31:53 2018
@@ -59,51 +59,57 @@ private:
   DestructorFunction Destructor;
 };
 
-
-TEST_F(CoreAPIsStandardTest, AsynchronousSymbolQuerySuccessfulResolutionOnly) {
+TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
   bool OnResolutionRun = false;
   bool OnReadyRun = false;
-  auto OnResolution =
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
-        EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
-        auto &Resolved = Result->Symbols;
-        auto I = Resolved.find(Foo);
-        EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
-        EXPECT_EQ(I->second.getAddress(), FooAddr)
-            << "Resolution returned incorrect result";
-        OnResolutionRun = true;
-      };
+
+  auto OnResolution = [&](Expected<SymbolMap> Result) {
+    EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
+    auto &Resolved = *Result;
+    auto I = Resolved.find(Foo);
+    EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
+    EXPECT_EQ(I->second.getAddress(), FooAddr)
+        << "Resolution returned incorrect result";
+    OnResolutionRun = true;
+  };
   auto OnReady = [&](Error Err) {
     cantFail(std::move(Err));
     OnReadyRun = true;
   };
 
-  AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
+  std::shared_ptr<MaterializationResponsibility> FooMR;
 
-  Q.resolve(Foo, FooSym);
+  cantFail(V.define(llvm::make_unique<SimpleMaterializationUnit>(
+      SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
+      [&](MaterializationResponsibility R) {
+        FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
+      })));
 
-  EXPECT_TRUE(Q.isFullyResolved()) << "Expected query to be fully resolved";
+  ES.lookup({&V}, {Foo}, OnResolution, OnReady, NoDependenciesToRegister);
 
-  if (!Q.isFullyResolved())
-    return;
+  EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
+  EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
 
-  Q.handleFullyResolved();
+  FooMR->resolve({{Foo, FooSym}});
 
-  EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
-  EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
+  EXPECT_TRUE(OnResolutionRun) << "Should have been resolved";
+  EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
+
+  FooMR->finalize();
+
+  EXPECT_TRUE(OnReadyRun) << "Should have been marked ready";
 }
 
 TEST_F(CoreAPIsStandardTest, ExecutionSessionFailQuery) {
   bool OnResolutionRun = false;
   bool OnReadyRun = false;
 
-  auto OnResolution =
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
-        EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
-        auto Msg = toString(Result.takeError());
-        EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
-        OnResolutionRun = true;
-      };
+  auto OnResolution = [&](Expected<SymbolMap> Result) {
+    EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
+    auto Msg = toString(Result.takeError());
+    EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
+    OnResolutionRun = true;
+  };
   auto OnReady = [&](Error Err) {
     cantFail(std::move(Err));
     OnReadyRun = true;
@@ -111,62 +117,28 @@ TEST_F(CoreAPIsStandardTest, ExecutionSe
 
   AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
 
-  ES.failQuery(Q, make_error<StringError>("xyz", inconvertibleErrorCode()));
+  ES.legacyFailQuery(Q,
+                     make_error<StringError>("xyz", inconvertibleErrorCode()));
 
   EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
   EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
 }
 
-TEST_F(CoreAPIsStandardTest, SimpleAsynchronousSymbolQueryAgainstVSO) {
-  bool OnResolutionRun = false;
+TEST_F(CoreAPIsStandardTest, EmptyLookup) {
+  bool OnResolvedRun = false;
   bool OnReadyRun = false;
 
-  auto OnResolution =
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
-        EXPECT_TRUE(!!Result) << "Query unexpectedly returned error";
-        auto &Resolved = Result->Symbols;
-        auto I = Resolved.find(Foo);
-        EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
-        EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
-            << "Resolution returned incorrect result";
-        OnResolutionRun = true;
-      };
+  auto OnResolution = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
+    OnResolvedRun = true;
+  };
 
   auto OnReady = [&](Error Err) {
     cantFail(std::move(Err));
     OnReadyRun = true;
   };
 
-  SymbolNameSet Names({Foo});
-
-  auto Q =
-      std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
-
-  auto Defs = absoluteSymbols({{Foo, FooSym}});
-  cantFail(V.define(Defs));
-  assert(Defs == nullptr && "Defs should have been accepted");
-  V.lookup(Q, Names);
-
-  EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
-  EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
-}
-
-TEST_F(CoreAPIsStandardTest, EmptyVSOAndQueryLookup) {
-  bool OnResolvedRun = false;
-  bool OnReadyRun = false;
-
-  auto Q = std::make_shared<AsynchronousSymbolQuery>(
-      SymbolNameSet(),
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
-        cantFail(std::move(RR));
-        OnResolvedRun = true;
-      },
-      [&](Error Err) {
-        cantFail(std::move(Err));
-        OnReadyRun = true;
-      });
-
-  V.lookup(std::move(Q), {});
+  ES.lookup({&V}, {}, OnResolution, OnReady, NoDependenciesToRegister);
 
   EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
   EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
@@ -182,8 +154,8 @@ TEST_F(CoreAPIsStandardTest, ChainedVSOL
 
   auto Q = std::make_shared<AsynchronousSymbolQuery>(
       SymbolNameSet({Foo}),
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
-        cantFail(std::move(RR));
+      [&](Expected<SymbolMap> Result) {
+        cantFail(std::move(Result));
         OnResolvedRun = true;
       },
       [&](Error Err) {
@@ -191,7 +163,7 @@ TEST_F(CoreAPIsStandardTest, ChainedVSOL
         OnReadyRun = true;
       });
 
-  V2.lookup(Q, V.lookup(Q, {Foo}));
+  V2.legacyLookup(Q, V.legacyLookup(Q, {Foo}));
 
   EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
   EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
@@ -268,20 +240,15 @@ TEST_F(CoreAPIsStandardTest, TestTrivial
   cantFail(V.define(FooMU));
 
   bool FooReady = false;
-  auto Q =
-    std::make_shared<AsynchronousSymbolQuery>(
-      SymbolNameSet({ Foo }),
-      [](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
-        cantFail(std::move(R));
-      },
-      [&](Error Err) {
-        cantFail(std::move(Err));
-        FooReady = true;
-      });
+  auto OnResolution = [](Expected<SymbolMap> R) { cantFail(std::move(R)); };
+  auto OnReady = [&](Error Err) {
+    cantFail(std::move(Err));
+    FooReady = true;
+  };
 
-  V.lookup(std::move(Q), { Foo });
+  ES.lookup({&V}, {Foo}, std::move(OnResolution), std::move(OnReady),
+            NoDependenciesToRegister);
 
-  FooR->addDependencies({{&V, {Foo}}});
   FooR->resolve({{Foo, FooSym}});
   FooR->finalize();
 
@@ -323,54 +290,52 @@ TEST_F(CoreAPIsStandardTest, TestCircula
   // Query each of the symbols to trigger materialization.
   bool FooResolved = false;
   bool FooReady = false;
-  auto FooQ = std::make_shared<AsynchronousSymbolQuery>(
-      SymbolNameSet({Foo}),
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
-        cantFail(std::move(RR));
-        FooResolved = true;
-      },
-      [&](Error Err) {
-        cantFail(std::move(Err));
-        FooReady = true;
-      });
-  {
-    auto Unresolved = V.lookup(FooQ, {Foo});
-    EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Foo\"";
-  }
+
+  auto OnFooResolution = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
+    FooResolved = true;
+  };
+
+  auto OnFooReady = [&](Error Err) {
+    cantFail(std::move(Err));
+    FooReady = true;
+  };
+
+  // Issue a lookup for Foo. Use NoDependenciesToRegister: We're going to add
+  // the dependencies manually below.
+  ES.lookup({&V}, {Foo}, std::move(OnFooResolution), std::move(OnFooReady),
+            NoDependenciesToRegister);
 
   bool BarResolved = false;
   bool BarReady = false;
-  auto BarQ = std::make_shared<AsynchronousSymbolQuery>(
-      SymbolNameSet({Bar}),
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
-        cantFail(std::move(RR));
-        BarResolved = true;
-      },
-      [&](Error Err) {
-        cantFail(std::move(Err));
-        BarReady = true;
-      });
-  {
-    auto Unresolved = V.lookup(BarQ, {Bar});
-    EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Bar\"";
-  }
+  auto OnBarResolution = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
+    BarResolved = true;
+  };
+
+  auto OnBarReady = [&](Error Err) {
+    cantFail(std::move(Err));
+    BarReady = true;
+  };
+
+  ES.lookup({&V}, {Bar}, std::move(OnBarResolution), std::move(OnBarReady),
+            NoDependenciesToRegister);
 
   bool BazResolved = false;
   bool BazReady = false;
-  auto BazQ = std::make_shared<AsynchronousSymbolQuery>(
-      SymbolNameSet({Baz}),
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
-        cantFail(std::move(RR));
-        BazResolved = true;
-      },
-      [&](Error Err) {
-        cantFail(std::move(Err));
-        BazReady = true;
-      });
-  {
-    auto Unresolved = V.lookup(BazQ, {Baz});
-    EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Baz\"";
-  }
+
+  auto OnBazResolution = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
+    BazResolved = true;
+  };
+
+  auto OnBazReady = [&](Error Err) {
+    cantFail(std::move(Err));
+    BazReady = true;
+  };
+
+  ES.lookup({&V}, {Baz}, std::move(OnBazResolution), std::move(OnBazReady),
+            NoDependenciesToRegister);
 
   // Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
   FooR->addDependencies({{&V, SymbolNameSet({Bar})}});
@@ -478,28 +443,23 @@ TEST_F(CoreAPIsStandardTest, AddAndMater
   bool OnResolutionRun = false;
   bool OnReadyRun = false;
 
-  auto OnResolution =
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
-        EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
-        auto I = Result->Symbols.find(Foo);
-        EXPECT_NE(I, Result->Symbols.end())
-            << "Could not find symbol definition";
-        EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
-            << "Resolution returned incorrect result";
-        OnResolutionRun = true;
-      };
+  auto OnResolution = [&](Expected<SymbolMap> Result) {
+    EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
+    auto I = Result->find(Foo);
+    EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
+    EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
+        << "Resolution returned incorrect result";
+    OnResolutionRun = true;
+  };
 
   auto OnReady = [&](Error Err) {
     cantFail(std::move(Err));
     OnReadyRun = true;
   };
 
-  auto Q =
-      std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
+  ES.lookup({&V}, Names, std::move(OnResolution), std::move(OnReady),
+            NoDependenciesToRegister);
 
-  auto Unresolved = V.lookup(std::move(Q), Names);
-
-  EXPECT_TRUE(Unresolved.empty()) << "Could not find Foo in dylib";
   EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
   EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
   EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
@@ -714,13 +674,14 @@ TEST_F(CoreAPIsStandardTest, TestMateria
       });
 
   cantFail(V.define(MU));
-  auto Q = std::make_shared<AsynchronousSymbolQuery>(
-      SymbolNameSet({Foo}),
-      [](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
-        cantFail(std::move(R));
-      },
-      [](Error Err) { cantFail(std::move(Err)); });
-  V.lookup(std::move(Q), SymbolNameSet({Foo}));
+  auto OnResolution = [](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
+  };
+
+  auto OnReady = [](Error Err) { cantFail(std::move(Err)); };
+
+  ES.lookup({&V}, {Foo}, std::move(OnResolution), std::move(OnReady),
+            NoDependenciesToRegister);
 
   auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp?rev=337595&r1=337594&r2=337595&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp Fri Jul 20 11:31:53 2018
@@ -24,7 +24,7 @@ TEST_F(LegacyAPIsStandardTest, TestLambd
   auto Resolver = createSymbolResolver(
       [&](const SymbolNameSet &Symbols) { return V.lookupFlags(Symbols); },
       [&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
-        return V.lookup(std::move(Q), Symbols);
+        return V.legacyLookup(std::move(Q), Symbols);
       });
 
   SymbolNameSet Symbols({Foo, Bar, Baz});
@@ -42,21 +42,17 @@ TEST_F(LegacyAPIsStandardTest, TestLambd
 
   bool OnResolvedRun = false;
 
-  auto OnResolved =
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
-        OnResolvedRun = true;
-        EXPECT_TRUE(!!Result) << "Unexpected error";
-        EXPECT_EQ(Result->Symbols.size(), 2U)
-            << "Unexpected number of resolved symbols";
-        EXPECT_EQ(Result->Symbols.count(Foo), 1U)
-            << "Missing lookup result for foo";
-        EXPECT_EQ(Result->Symbols.count(Bar), 1U)
-            << "Missing lookup result for bar";
-        EXPECT_EQ(Result->Symbols[Foo].getAddress(), FooSym.getAddress())
-            << "Incorrect address for foo";
-        EXPECT_EQ(Result->Symbols[Bar].getAddress(), BarSym.getAddress())
-            << "Incorrect address for bar";
-      };
+  auto OnResolved = [&](Expected<SymbolMap> Result) {
+    OnResolvedRun = true;
+    EXPECT_TRUE(!!Result) << "Unexpected error";
+    EXPECT_EQ(Result->size(), 2U) << "Unexpected number of resolved symbols";
+    EXPECT_EQ(Result->count(Foo), 1U) << "Missing lookup result for foo";
+    EXPECT_EQ(Result->count(Bar), 1U) << "Missing lookup result for bar";
+    EXPECT_EQ((*Result)[Foo].getAddress(), FooSym.getAddress())
+        << "Incorrect address for foo";
+    EXPECT_EQ((*Result)[Bar].getAddress(), BarSym.getAddress())
+        << "Incorrect address for bar";
+  };
   auto OnReady = [&](Error Err) {
     EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
   };
@@ -85,7 +81,7 @@ TEST(LegacyAPIInteropTest, QueryAgainstV
 
   auto Lookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
                     SymbolNameSet Symbols) {
-    return V.lookup(std::move(Query), Symbols);
+    return V.legacyLookup(std::move(Query), Symbols);
   };
 
   auto UnderlyingResolver =
@@ -158,22 +154,18 @@ TEST(LegacyAPIInteropTset, LegacyLookupH
 
   bool OnResolvedRun = false;
   bool OnReadyRun = false;
-  auto OnResolved =
-      [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
-        OnResolvedRun = true;
-        EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
-
-        auto &Resolved = Result->Symbols;
-        EXPECT_EQ(Resolved.size(), 2U) << "Wrong number of symbols resolved";
-        EXPECT_EQ(Resolved.count(Foo), 1U) << "Result for foo missing";
-        EXPECT_EQ(Resolved.count(Bar), 1U) << "Result for bar missing";
-        EXPECT_EQ(Resolved[Foo].getAddress(), FooAddr)
-            << "Wrong address for foo";
-        EXPECT_EQ(Resolved[Foo].getFlags(), FooFlags) << "Wrong flags for foo";
-        EXPECT_EQ(Resolved[Bar].getAddress(), BarAddr)
-            << "Wrong address for bar";
-        EXPECT_EQ(Resolved[Bar].getFlags(), BarFlags) << "Wrong flags for bar";
-      };
+  auto OnResolved = [&](Expected<SymbolMap> Result) {
+    OnResolvedRun = true;
+    EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
+
+    EXPECT_EQ(Result->size(), 2U) << "Wrong number of symbols resolved";
+    EXPECT_EQ(Result->count(Foo), 1U) << "Result for foo missing";
+    EXPECT_EQ(Result->count(Bar), 1U) << "Result for bar missing";
+    EXPECT_EQ((*Result)[Foo].getAddress(), FooAddr) << "Wrong address for foo";
+    EXPECT_EQ((*Result)[Foo].getFlags(), FooFlags) << "Wrong flags for foo";
+    EXPECT_EQ((*Result)[Bar].getAddress(), BarAddr) << "Wrong address for bar";
+    EXPECT_EQ((*Result)[Bar].getFlags(), BarFlags) << "Wrong flags for bar";
+  };
   auto OnReady = [&](Error Err) {
     EXPECT_FALSE(!!Err) << "Finalization unexpectedly failed";
     OnReadyRun = true;




More information about the llvm-commits mailing list