[llvm] r337593 - [ORC] Replace SymbolResolvers in the new ORC layers with search orders on VSOs.

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


Author: lhames
Date: Fri Jul 20 11:31:50 2018
New Revision: 337593

URL: http://llvm.org/viewvc/llvm-project?rev=337593&view=rev
Log:
[ORC] Replace SymbolResolvers in the new ORC layers with search orders on VSOs.

A search order is a list of VSOs to be searched linearly to find symbols. Each
VSO now has a search order that will be used when fixing up definitions in that
VSO. Each VSO's search order defaults to just that VSO itself.

This is a first step towards removing symbol resolvers from ORC altogether. In
practice symbol resolvers tended to be used to implement a search order anyway,
sometimes with additional programatic generation of symbols. Now that VSOs
support programmatic generation of definitions via fallback generators, search
orders provide a cleaner way to achieve the desired effect (while removing a lot
of boilerplate).

Modified:
    llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/NullResolver.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
    llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
    llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
    llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp
    llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp
    llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h

Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h Fri Jul 20 11:31:50 2018
@@ -23,6 +23,7 @@
 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
 #include "llvm/ExecutionEngine/Orc/Layer.h"
+#include "llvm/ExecutionEngine/Orc/Legacy.h"
 #include "llvm/ExecutionEngine/Orc/OrcError.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/IR/Attributes.h"
@@ -67,21 +68,11 @@ public:
   using IndirectStubsManagerBuilder =
       std::function<std::unique_ptr<IndirectStubsManager>()>;
 
-  /// Retrieve symbol resolver for the given VModuleKey.
-  using GetSymbolResolverFunction =
-      std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
-
-  /// Set the symbol resolver for the given VModuleKey.
-  using SetSymbolResolverFunction =
-      std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
-
   using GetAvailableContextFunction = std::function<LLVMContext &()>;
 
   CompileOnDemandLayer2(ExecutionSession &ES, IRLayer &BaseLayer,
                         JITCompileCallbackManager &CCMgr,
                         IndirectStubsManagerBuilder BuildIndirectStubsManager,
-                        GetSymbolResolverFunction GetSymbolResolver,
-                        SetSymbolResolverFunction SetSymbolResolver,
                         GetAvailableContextFunction GetAvailableContext);
 
   Error add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) override;
@@ -96,8 +87,7 @@ private:
   IndirectStubsManager &getStubsManager(const VSO &V);
 
   void emitExtractedFunctionsModule(MaterializationResponsibility R,
-                                    std::unique_ptr<Module> M,
-                                    std::shared_ptr<SymbolResolver> Resolver);
+                                    std::unique_ptr<Module> M);
 
   mutable std::mutex CODLayerMutex;
 
@@ -105,8 +95,6 @@ private:
   JITCompileCallbackManager &CCMgr;
   IndirectStubsManagerBuilder BuildIndirectStubsManager;
   StubManagersMap StubsMgrs;
-  GetSymbolResolverFunction GetSymbolResolver;
-  SetSymbolResolverFunction SetSymbolResolver;
   GetAvailableContextFunction GetAvailableContext;
 };
 

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=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h Fri Jul 20 11:31:50 2018
@@ -66,6 +66,11 @@ using SymbolDependenceMap = std::map<VSO
 /// Render a SymbolDependendeMap.
 raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
 
+/// A list of VSO pointers.
+using VSOList = std::vector<VSO *>;
+
+raw_ostream &operator<<(raw_ostream &OS, const VSOList &VSOs);
+
 /// Used to notify a VSO that the given set of symbols failed to materialize.
 class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
 public:
@@ -471,74 +476,6 @@ private:
   size_t NotYetReadyCount;
 };
 
-/// SymbolResolver is a composable interface for looking up symbol flags
-///        and addresses using the AsynchronousSymbolQuery type. It will
-///        eventually replace the LegacyJITSymbolResolver interface as the
-///        stardard ORC symbol resolver type.
-///
-/// FIXME: SymbolResolvers should go away and be replaced with VSOs with
-///        defenition generators.
-class SymbolResolver {
-public:
-  virtual ~SymbolResolver() = default;
-
-  /// Returns the flags for each symbol in Symbols that can be found,
-  ///        along with the set of symbol that could not be found.
-  virtual SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
-                                    const SymbolNameSet &Symbols) = 0;
-
-  /// For each symbol in Symbols that can be found, assigns that symbols
-  ///        value in Query. Returns the set of symbols that could not be found.
-  virtual SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
-                               SymbolNameSet Symbols) = 0;
-
-private:
-  virtual void anchor();
-};
-
-/// Implements SymbolResolver with a pair of supplied function objects
-///        for convenience. See createSymbolResolver.
-template <typename LookupFlagsFn, typename LookupFn>
-class LambdaSymbolResolver final : public SymbolResolver {
-public:
-  template <typename LookupFlagsFnRef, typename LookupFnRef>
-  LambdaSymbolResolver(LookupFlagsFnRef &&LookupFlags, LookupFnRef &&Lookup)
-      : LookupFlags(std::forward<LookupFlagsFnRef>(LookupFlags)),
-        Lookup(std::forward<LookupFnRef>(Lookup)) {}
-
-  SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
-                            const SymbolNameSet &Symbols) final {
-    return LookupFlags(Flags, Symbols);
-  }
-
-  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
-                       SymbolNameSet Symbols) final {
-    return Lookup(std::move(Query), std::move(Symbols));
-  }
-
-private:
-  LookupFlagsFn LookupFlags;
-  LookupFn Lookup;
-};
-
-/// Creates a SymbolResolver implementation from the pair of supplied
-///        function objects.
-template <typename LookupFlagsFn, typename LookupFn>
-std::unique_ptr<LambdaSymbolResolver<
-    typename std::remove_cv<
-        typename std::remove_reference<LookupFlagsFn>::type>::type,
-    typename std::remove_cv<
-        typename std::remove_reference<LookupFn>::type>::type>>
-createSymbolResolver(LookupFlagsFn &&LookupFlags, LookupFn &&Lookup) {
-  using LambdaSymbolResolverImpl = LambdaSymbolResolver<
-      typename std::remove_cv<
-          typename std::remove_reference<LookupFlagsFn>::type>::type,
-      typename std::remove_cv<
-          typename std::remove_reference<LookupFn>::type>::type>;
-  return llvm::make_unique<LambdaSymbolResolverImpl>(
-      std::forward<LookupFlagsFn>(LookupFlags), std::forward<LookupFn>(Lookup));
-}
-
 /// A symbol table that supports asynchoronous symbol queries.
 ///
 /// Represents a virtual shared object. Instances can not be copied or moved, so
@@ -578,6 +515,42 @@ public:
     this->FallbackDefinitionGenerator = std::move(FallbackDefinitionGenerator);
   }
 
+  /// Set the search order to be used when fixing up definitions in VSO.
+  /// This will replace the previous search order, and apply to any symbol
+  /// resolutions made for definitions in this VSO after the call to
+  /// setSearchOrder (even if the definition itself was added before the
+  /// call).
+  ///
+  /// If SearchThisVSOFirst is set, which by default it is, then this VSO will
+  /// add itself to the beginning of the SearchOrder (Clients should *not*
+  /// put this VSO in the list in this case, to avoid redundant lookups).
+  ///
+  /// If SearchThisVSOFirst is false then the search order will be used as
+  /// given. The main motivation for this feature is to support deliberate
+  /// shadowing of symbols in this VSO by a facade VSO. For example, the
+  /// facade may resolve function names to stubs, and the stubs may compile
+  /// lazily by looking up symbols in this dylib. Adding the facade dylib
+  /// as the first in the search order (instead of this dylib) ensures that
+  /// definitions within this dylib resolve to the lazy-compiling stubs,
+  /// rather than immediately materializing the definitions in this dylib.
+  void setSearchOrder(VSOList NewSearchOrder, bool SearchThisVSOFirst = true);
+
+  /// Add the given VSO to the search order for definitions in this VSO.
+  void addToSearchOrder(VSO &V);
+
+  /// Replace OldV with NewV in the search order if OldV is present. Otherwise
+  /// this operation is a no-op.
+  void replaceInSearchOrder(VSO &OldV, VSO &NewV);
+
+  /// Remove the given VSO from the search order for this VSO if it is
+  /// present. Otherwise this operation is a no-op.
+  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); });
+  }
+
   /// Define all symbols provided by the materialization unit to be part
   ///        of the given VSO.
   template <typename UniquePtrToMaterializationUnit>
@@ -649,8 +622,7 @@ private:
     LLVM_MARK_AS_BITMASK_ENUM(NotifyFullyReady)
   };
 
-  VSO(ExecutionSessionBase &ES, std::string Name)
-      : ES(ES), VSOName(std::move(Name)) {}
+  VSO(ExecutionSessionBase &ES, std::string Name);
 
   Error defineImpl(MaterializationUnit &MU);
 
@@ -692,6 +664,7 @@ private:
   UnmaterializedInfosMap UnmaterializedInfos;
   MaterializingInfosMap MaterializingInfos;
   FallbackDefinitionGeneratorFunction FallbackDefinitionGenerator;
+  VSOList SearchOrder;
 
   // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
   //        with callbacks from asynchronous queries.
@@ -729,8 +702,6 @@ Expected<SymbolMap> blockingLookup(Execu
                                    SymbolNameSet Names, bool WaiUntilReady,
                                    MaterializationResponsibility *MR = nullptr);
 
-using VSOList = std::vector<VSO *>;
-
 /// 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/LLJIT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h Fri Jul 20 11:31:50 2018
@@ -81,13 +81,10 @@ protected:
   LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
         DataLayout DL);
 
-  std::shared_ptr<SymbolResolver> takeSymbolResolver(VModuleKey K);
-  RTDyldObjectLinkingLayer2::Resources getRTDyldResources(VModuleKey K);
+  std::shared_ptr<RuntimeDyld::MemoryManager> getMemoryManager(VModuleKey K);
 
   std::string mangle(StringRef UnmangledName);
 
-  std::unique_ptr<SymbolResolver> createResolverFor(VSO &V);
-
   Error applyDataLayout(Module &M);
 
   void recordCtorDtors(Module &M);
@@ -98,12 +95,9 @@ protected:
   std::unique_ptr<TargetMachine> TM;
   DataLayout DL;
 
-  std::map<VSO *, VSOList> VSOLookupOrder;
-
   RTDyldObjectLinkingLayer2 ObjLinkingLayer;
   IRCompileLayer2 CompileLayer;
 
-  std::map<VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
   CtorDtorRunner2 CtorRunner, DtorRunner;
 };
 
@@ -136,10 +130,6 @@ private:
             std::unique_ptr<JITCompileCallbackManager> CCMgr,
             std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
 
-  std::shared_ptr<SymbolResolver> getSymbolResolver(VModuleKey K);
-
-  void setSymbolResolver(VModuleKey K, std::shared_ptr<SymbolResolver> R);
-
   std::unique_ptr<JITCompileCallbackManager> CCMgr;
   std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;
 

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=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Legacy.h Fri Jul 20 11:31:50 2018
@@ -20,6 +20,74 @@
 namespace llvm {
 namespace orc {
 
+/// SymbolResolver is a composable interface for looking up symbol flags
+///        and addresses using the AsynchronousSymbolQuery type. It will
+///        eventually replace the LegacyJITSymbolResolver interface as the
+///        stardard ORC symbol resolver type.
+///
+/// FIXME: SymbolResolvers should go away and be replaced with VSOs with
+///        defenition generators.
+class SymbolResolver {
+public:
+  virtual ~SymbolResolver() = default;
+
+  /// Returns the flags for each symbol in Symbols that can be found,
+  ///        along with the set of symbol that could not be found.
+  virtual SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
+                                    const SymbolNameSet &Symbols) = 0;
+
+  /// For each symbol in Symbols that can be found, assigns that symbols
+  ///        value in Query. Returns the set of symbols that could not be found.
+  virtual SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
+                               SymbolNameSet Symbols) = 0;
+
+private:
+  virtual void anchor();
+};
+
+/// Implements SymbolResolver with a pair of supplied function objects
+///        for convenience. See createSymbolResolver.
+template <typename LookupFlagsFn, typename LookupFn>
+class LambdaSymbolResolver final : public SymbolResolver {
+public:
+  template <typename LookupFlagsFnRef, typename LookupFnRef>
+  LambdaSymbolResolver(LookupFlagsFnRef &&LookupFlags, LookupFnRef &&Lookup)
+      : LookupFlags(std::forward<LookupFlagsFnRef>(LookupFlags)),
+        Lookup(std::forward<LookupFnRef>(Lookup)) {}
+
+  SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
+                            const SymbolNameSet &Symbols) final {
+    return LookupFlags(Flags, Symbols);
+  }
+
+  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
+                       SymbolNameSet Symbols) final {
+    return Lookup(std::move(Query), std::move(Symbols));
+  }
+
+private:
+  LookupFlagsFn LookupFlags;
+  LookupFn Lookup;
+};
+
+/// Creates a SymbolResolver implementation from the pair of supplied
+///        function objects.
+template <typename LookupFlagsFn, typename LookupFn>
+std::unique_ptr<LambdaSymbolResolver<
+    typename std::remove_cv<
+        typename std::remove_reference<LookupFlagsFn>::type>::type,
+    typename std::remove_cv<
+        typename std::remove_reference<LookupFn>::type>::type>>
+createSymbolResolver(LookupFlagsFn &&LookupFlags, LookupFn &&Lookup) {
+  using LambdaSymbolResolverImpl = LambdaSymbolResolver<
+      typename std::remove_cv<
+          typename std::remove_reference<LookupFlagsFn>::type>::type,
+      typename std::remove_cv<
+          typename std::remove_reference<LookupFn>::type>::type>;
+  return llvm::make_unique<LambdaSymbolResolverImpl>(
+      std::forward<LookupFlagsFn>(LookupFlags), std::forward<LookupFn>(Lookup));
+}
+
 class JITSymbolResolverAdapter : public JITSymbolResolver {
 public:
   JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R,

Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/NullResolver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/NullResolver.h?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/NullResolver.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/NullResolver.h Fri Jul 20 11:31:50 2018
@@ -15,7 +15,7 @@
 #ifndef LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
 #define LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
 
-#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Legacy.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 
 namespace llvm {

Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h Fri Jul 20 11:31:50 2018
@@ -46,17 +46,13 @@ public:
   /// Functor for receiving finalization notifications.
   using NotifyFinalizedFunction = std::function<void(VModuleKey)>;
 
-  struct Resources {
-    std::shared_ptr<RuntimeDyld::MemoryManager> MemMgr;
-    std::shared_ptr<SymbolResolver> Resolver;
-  };
-
-  using ResourcesGetterFunction = std::function<Resources(VModuleKey)>;
+  using GetMemoryManagerFunction =
+      std::function<std::shared_ptr<RuntimeDyld::MemoryManager>(VModuleKey)>;
 
   /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
   ///        and NotifyFinalized functors.
   RTDyldObjectLinkingLayer2(
-      ExecutionSession &ES, ResourcesGetterFunction GetResources,
+      ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
       NotifyLoadedFunction NotifyLoaded = NotifyLoadedFunction(),
       NotifyFinalizedFunction NotifyFinalized = NotifyFinalizedFunction());
 
@@ -81,7 +77,7 @@ public:
 
 private:
   mutable std::mutex RTDyldLayerMutex;
-  ResourcesGetterFunction GetResources;
+  GetMemoryManagerFunction GetMemoryManager;
   NotifyLoadedFunction NotifyLoaded;
   NotifyFinalizedFunction NotifyFinalized;
   bool ProcessAllSections;

Modified: llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp Fri Jul 20 11:31:50 2018
@@ -130,21 +130,18 @@ namespace orc {
 
 class ExtractingIRMaterializationUnit : public IRMaterializationUnit {
 public:
-  ExtractingIRMaterializationUnit(
-      ExecutionSession &ES, CompileOnDemandLayer2 &Parent,
-      std::unique_ptr<Module> M,
-      std::shared_ptr<SymbolResolver> BackingResolver)
-      : IRMaterializationUnit(ES, std::move(M)), Parent(Parent),
-        BackingResolver(std::move(BackingResolver)) {}
-
-  ExtractingIRMaterializationUnit(
-      std::unique_ptr<Module> M, SymbolFlagsMap SymbolFlags,
-      SymbolNameToDefinitionMap SymbolToDefinition,
-      CompileOnDemandLayer2 &Parent,
-      std::shared_ptr<SymbolResolver> BackingResolver)
+  ExtractingIRMaterializationUnit(ExecutionSession &ES,
+                                  CompileOnDemandLayer2 &Parent,
+                                  std::unique_ptr<Module> M)
+      : IRMaterializationUnit(ES, std::move(M)), Parent(Parent) {}
+
+  ExtractingIRMaterializationUnit(std::unique_ptr<Module> M,
+                                  SymbolFlagsMap SymbolFlags,
+                                  SymbolNameToDefinitionMap SymbolToDefinition,
+                                  CompileOnDemandLayer2 &Parent)
       : IRMaterializationUnit(std::move(M), std::move(SymbolFlags),
                               std::move(SymbolToDefinition)),
-        Parent(Parent), BackingResolver(std::move(BackingResolver)) {}
+        Parent(Parent) {}
 
 private:
   void materialize(MaterializationResponsibility R) override {
@@ -153,10 +150,6 @@ private:
     //        together. This could be used, for example, to provide a specific
     //        memory manager instance to the linking layer.
 
-    // FIXME: The derived constructor should *only* look for the names of
-    //        original function definitions in the target VSO. All other
-    //        symbols should be looked up in the backing resolver.
-
     auto RequestedSymbols = R.getRequestedSymbols();
 
     // Extract the requested functions into a new module.
@@ -201,12 +194,12 @@ private:
              "of entries");
       R.replace(llvm::make_unique<ExtractingIRMaterializationUnit>(
           std::move(M), std::move(DelegatedSymbolFlags),
-          std::move(DelegatedSymbolToDefinition), Parent, BackingResolver));
+          std::move(DelegatedSymbolToDefinition), Parent));
     }
 
     if (ExtractedFunctionsModule)
-      Parent.emitExtractedFunctionsModule(
-          std::move(R), std::move(ExtractedFunctionsModule), BackingResolver);
+      Parent.emitExtractedFunctionsModule(std::move(R),
+                                          std::move(ExtractedFunctionsModule));
   }
 
   void discard(const VSO &V, SymbolStringPtr Name) override {
@@ -218,19 +211,14 @@ private:
 
   mutable std::mutex SourceModuleMutex;
   CompileOnDemandLayer2 &Parent;
-  std::shared_ptr<SymbolResolver> BackingResolver;
 };
 
 CompileOnDemandLayer2::CompileOnDemandLayer2(
     ExecutionSession &ES, IRLayer &BaseLayer, JITCompileCallbackManager &CCMgr,
     IndirectStubsManagerBuilder BuildIndirectStubsManager,
-    GetSymbolResolverFunction GetSymbolResolver,
-    SetSymbolResolverFunction SetSymbolResolver,
     GetAvailableContextFunction GetAvailableContext)
     : IRLayer(ES), BaseLayer(BaseLayer), CCMgr(CCMgr),
       BuildIndirectStubsManager(std::move(BuildIndirectStubsManager)),
-      GetSymbolResolver(std::move(GetSymbolResolver)),
-      SetSymbolResolver(std::move(SetSymbolResolver)),
       GetAvailableContext(std::move(GetAvailableContext)) {}
 
 Error CompileOnDemandLayer2::add(VSO &V, VModuleKey K,
@@ -306,19 +294,14 @@ void CompileOnDemandLayer2::emit(Materia
     StubInits[*KV.first] = KV.second;
 
   // Build the function-body-extracting materialization unit.
-  auto SR = GetSymbolResolver(K);
   if (auto Err = R.getTargetVSO().define(
-          llvm::make_unique<ExtractingIRMaterializationUnit>(
-              ES, *this, std::move(M), SR))) {
+          llvm::make_unique<ExtractingIRMaterializationUnit>(ES, *this,
+                                                             std::move(M)))) {
     ES.reportError(std::move(Err));
     R.failMaterialization();
     return;
   }
 
-  // Replace the fallback symbol resolver: We will re-use M's VModuleKey for
-  // the GlobalsModule.
-  SetSymbolResolver(K, SR);
-
   // Build the stubs.
   // FIXME: Remove function bodies materialization unit if stub creation fails.
   auto &StubsMgr = getStubsManager(TargetVSO);
@@ -351,22 +334,8 @@ IndirectStubsManager &CompileOnDemandLay
 }
 
 void CompileOnDemandLayer2::emitExtractedFunctionsModule(
-    MaterializationResponsibility R, std::unique_ptr<Module> M,
-    std::shared_ptr<SymbolResolver> Resolver) {
-  auto &TargetVSO = R.getTargetVSO();
+    MaterializationResponsibility R, std::unique_ptr<Module> M) {
   auto K = getExecutionSession().allocateVModule();
-
-  auto ExtractedFunctionsResolver = createSymbolResolver(
-      [=](SymbolFlagsMap &Flags, const SymbolNameSet &Symbols) {
-        return Resolver->lookupFlags(Flags, Symbols);
-      },
-      [=, &TargetVSO](std::shared_ptr<AsynchronousSymbolQuery> Query,
-                      SymbolNameSet Symbols) {
-        auto RemainingSymbols = TargetVSO.lookup(Query, std::move(Symbols));
-        return Resolver->lookup(std::move(Query), std::move(RemainingSymbols));
-      });
-
-  SetSymbolResolver(K, std::move(ExtractedFunctionsResolver));
   BaseLayer.emit(std::move(R), std::move(K), std::move(M));
 }
 

Modified: llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp Fri Jul 20 11:31:50 2018
@@ -24,7 +24,6 @@ char FailedToMaterialize::ID = 0;
 char SymbolsNotFound::ID = 0;
 
 void MaterializationUnit::anchor() {}
-void SymbolResolver::anchor() {}
 
 raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
   if (Flags.isWeak())
@@ -99,6 +98,20 @@ raw_ostream &operator<<(raw_ostream &OS,
   return OS;
 }
 
+raw_ostream &operator<<(raw_ostream &OS, const VSOList &VSOs) {
+  OS << "[";
+  if (!VSOs.empty()) {
+    assert(VSOs.front() && "VSOList entries must not be null");
+    OS << " " << VSOs.front()->getName();
+    for (auto *V : make_range(std::next(VSOs.begin()), VSOs.end())) {
+      assert(V && "VSOList entries must not be null");
+      OS << ", " << V->getName();
+    }
+  }
+  OS << " ]";
+  return OS;
+}
+
 FailedToMaterialize::FailedToMaterialize(SymbolNameSet Symbols)
     : Symbols(std::move(Symbols)) {
   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
@@ -859,6 +872,34 @@ void VSO::runOutstandingMUs() {
   }
 }
 
+void VSO::setSearchOrder(VSOList NewSearchOrder, bool SearchThisVSOFirst) {
+  if (SearchThisVSOFirst && NewSearchOrder.front() != this)
+    NewSearchOrder.insert(NewSearchOrder.begin(), this);
+
+  ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); });
+}
+
+void VSO::addToSearchOrder(VSO &V) {
+  ES.runSessionLocked([&]() { SearchOrder.push_back(&V); });
+}
+
+void VSO::replaceInSearchOrder(VSO &OldV, VSO &NewV) {
+  ES.runSessionLocked([&]() {
+    auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &OldV);
+
+    if (I != SearchOrder.end())
+      *I = &NewV;
+  });
+}
+
+void VSO::removeFromSearchOrder(VSO &V) {
+  ES.runSessionLocked([&]() {
+    auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &V);
+    if (I != SearchOrder.end())
+      SearchOrder.erase(I);
+  });
+}
+
 SymbolNameSet VSO::lookupFlags(SymbolFlagsMap &Flags,
                                const SymbolNameSet &Names) {
   return ES.runSessionLocked([&, this]() {
@@ -1066,6 +1107,11 @@ void VSO::dump(raw_ostream &OS) {
   });
 }
 
+VSO::VSO(ExecutionSessionBase &ES, std::string Name)
+    : ES(ES), VSOName(std::move(Name)) {
+  SearchOrder.push_back(this);
+}
+
 Error VSO::defineImpl(MaterializationUnit &MU) {
   SymbolNameSet Duplicates;
   SymbolNameSet MUDefsOverridden;

Modified: llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp Fri Jul 20 11:31:50 2018
@@ -35,7 +35,6 @@ Error LLJIT::addIRModule(VSO &V, std::un
     return Err;
 
   auto K = ES->allocateVModule();
-  Resolvers[K] = createResolverFor(V);
   return CompileLayer.add(V, K, std::move(M));
 }
 
@@ -49,23 +48,13 @@ LLJIT::LLJIT(std::unique_ptr<ExecutionSe
     : ES(std::move(ES)), Main(this->ES->createVSO("main")), TM(std::move(TM)),
       DL(std::move(DL)),
       ObjLinkingLayer(*this->ES,
-                      [this](VModuleKey K) { return getRTDyldResources(K); }),
+                      [this](VModuleKey K) { return getMemoryManager(K); }),
       CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),
-      CtorRunner(Main), DtorRunner(Main) {
-  VSOLookupOrder[&Main] = VSOList({&Main});
-}
-
-std::shared_ptr<SymbolResolver> LLJIT::takeSymbolResolver(VModuleKey K) {
-  auto ResolverI = Resolvers.find(K);
-  assert(ResolverI != Resolvers.end() && "Missing resolver");
-  auto Resolver = std::move(ResolverI->second);
-  Resolvers.erase(ResolverI);
-  return Resolver;
-}
+      CtorRunner(Main), DtorRunner(Main) {}
 
-RTDyldObjectLinkingLayer2::Resources LLJIT::getRTDyldResources(VModuleKey K) {
-  return orc::RTDyldObjectLinkingLayer2::Resources(
-      {llvm::make_unique<SectionMemoryManager>(), takeSymbolResolver(K)});
+std::shared_ptr<RuntimeDyld::MemoryManager>
+LLJIT::getMemoryManager(VModuleKey K) {
+  return llvm::make_unique<SectionMemoryManager>();
 }
 
 std::string LLJIT::mangle(StringRef UnmangledName) {
@@ -77,21 +66,6 @@ std::string LLJIT::mangle(StringRef Unma
   return MangledName;
 }
 
-std::unique_ptr<SymbolResolver> LLJIT::createResolverFor(VSO &V) {
-  return createSymbolResolver(
-      [&](SymbolFlagsMap &Flags, const SymbolNameSet &Symbols) {
-        return V.lookupFlags(Flags, Symbols);
-      },
-      [&, this](std::shared_ptr<AsynchronousSymbolQuery> Q,
-                SymbolNameSet Symbols) {
-        assert(VSOLookupOrder.count(&V) && "No VSO lookup order for V");
-        SymbolNameSet Unresolved = std::move(Symbols);
-        for (auto *LV : VSOLookupOrder[&V])
-          Unresolved = LV->lookup(Q, std::move(Unresolved));
-        return Unresolved;
-      });
-}
-
 Error LLJIT::applyDataLayout(Module &M) {
   if (M.getDataLayout().isDefault())
     M.setDataLayout(DL);
@@ -143,7 +117,6 @@ Error LLLazyJIT::addLazyIRModule(VSO &V,
   recordCtorDtors(*M);
 
   auto K = ES->allocateVModule();
-  setSymbolResolver(K, createResolverFor(V));
   return CODLayer.add(V, K, std::move(M));
 }
 
@@ -155,17 +128,7 @@ LLLazyJIT::LLLazyJIT(
     : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
       CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),
       CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder),
-               [this](VModuleKey K) { return takeSymbolResolver(K); },
-               [this](VModuleKey K, std::shared_ptr<SymbolResolver> R) {
-                 setSymbolResolver(K, std::move(R));
-               },
                [&]() -> LLVMContext & { return Ctx; }) {}
 
-void LLLazyJIT::setSymbolResolver(VModuleKey K,
-                                  std::shared_ptr<SymbolResolver> R) {
-  assert(!Resolvers.count(K) && "Resolver already present for VModule K");
-  Resolvers[K] = std::move(R);
-}
-
 } // End namespace orc.
 } // End namespace llvm.

Modified: llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Legacy.cpp Fri Jul 20 11:31:50 2018
@@ -12,6 +12,8 @@
 namespace llvm {
 namespace orc {
 
+void SymbolResolver::anchor() {}
+
 JITSymbolResolverAdapter::JITSymbolResolverAdapter(
     ExecutionSession &ES, SymbolResolver &R, MaterializationResponsibility *MR)
     : ES(ES), R(R), MR(MR) {}

Modified: llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp Fri Jul 20 11:31:50 2018
@@ -9,13 +9,85 @@
 
 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
 
+namespace {
+
+using namespace llvm;
+using namespace llvm::orc;
+
+class VSOSearchOrderResolver : public JITSymbolResolver {
+public:
+  VSOSearchOrderResolver(ExecutionSession &ES,
+                         MaterializationResponsibility &MR)
+      : ES(ES), MR(MR) {}
+
+  Expected<LookupResult> lookup(const LookupSet &Symbols) {
+    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 InternedResult = blockingLookup(
+        ES, std::move(AsyncLookup), std::move(InternedSymbols), false, &MR);
+
+    if (!InternedResult)
+      return InternedResult.takeError();
+
+    LookupResult Result;
+    for (auto &KV : *InternedResult)
+      Result[*KV.first] = std::move(KV.second);
+
+    return Result;
+  }
+
+  Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
+    SymbolNameSet InternedSymbols;
+
+    for (auto &S : Symbols)
+      InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
+
+    SymbolFlagsMap InternedResult;
+    MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
+      // An empty search order is pathalogical, but allowed.
+      if (VSOs.empty())
+        return;
+
+      assert(VSOs.front() && "VSOList entry can not be null");
+      VSOs.front()->lookupFlags(InternedResult, InternedSymbols);
+    });
+
+    LookupFlagsResult Result;
+    for (auto &KV : InternedResult)
+      Result[*KV.first] = std::move(KV.second);
+
+    return Result;
+  }
+
+private:
+  ExecutionSession &ES;
+  MaterializationResponsibility &MR;
+};
+
+} // end anonymous namespace
+
 namespace llvm {
 namespace orc {
 
 RTDyldObjectLinkingLayer2::RTDyldObjectLinkingLayer2(
-    ExecutionSession &ES, ResourcesGetterFunction GetResources,
+    ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
     NotifyLoadedFunction NotifyLoaded, NotifyFinalizedFunction NotifyFinalized)
-    : ObjectLayer(ES), GetResources(std::move(GetResources)),
+    : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
       NotifyLoaded(std::move(NotifyLoaded)),
       NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) {}
 
@@ -32,11 +104,10 @@ void RTDyldObjectLinkingLayer2::emit(Mat
     R.failMaterialization();
   }
 
-  auto Resources = GetResources(K);
+  auto MemoryManager = GetMemoryManager(K);
 
-  JITSymbolResolverAdapter ResolverAdapter(ES, *Resources.Resolver, &R);
-  auto RTDyld =
-      llvm::make_unique<RuntimeDyld>(*Resources.MemMgr, ResolverAdapter);
+  VSOSearchOrderResolver Resolver(ES, R);
+  auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
   RTDyld->setProcessAllSections(ProcessAllSections);
 
   {
@@ -48,7 +119,7 @@ void RTDyldObjectLinkingLayer2::emit(Mat
 
     assert(!MemMgrs.count(K) &&
            "A memory manager already exists for this key?");
-    MemMgrs[K] = Resources.MemMgr;
+    MemMgrs[K] = std::move(MemoryManager);
   }
 
   auto Info = RTDyld->loadObject(**ObjFile);

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp Fri Jul 20 11:31:50 2018
@@ -11,7 +11,6 @@
 #include "llvm/Config/llvm-config.h"
 #include "llvm/ExecutionEngine/Orc/Core.h"
 #include "llvm/ExecutionEngine/Orc/OrcError.h"
-#include "gtest/gtest.h"
 
 #include <set>
 #include <thread>
@@ -19,6 +18,8 @@
 using namespace llvm;
 using namespace llvm::orc;
 
+class CoreAPIsStandardTest : public CoreAPIsBasedStandardTest {};
+
 namespace {
 
 class SimpleMaterializationUnit : public MaterializationUnit {
@@ -58,45 +59,6 @@ private:
   DestructorFunction Destructor;
 };
 
-// CoreAPIsStandardTest that saves a bunch of boilerplate by providing the
-// following:
-//
-// (1) ES -- An ExecutionSession
-// (2) Foo, Bar, Baz, Qux -- SymbolStringPtrs for strings "foo", "bar", "baz",
-//     and "qux" respectively.
-// (3) FooAddr, BarAddr, BazAddr, QuxAddr -- Dummy addresses. Guaranteed
-//     distinct and non-null.
-// (4) FooSym, BarSym, BazSym, QuxSym -- JITEvaluatedSymbols with FooAddr,
-//     BarAddr, BazAddr, and QuxAddr respectively. All with default strong,
-//     linkage and non-hidden visibility.
-// (5) V -- A VSO associated with ES.
-class CoreAPIsStandardTest : public testing::Test {
-public:
-protected:
-  ExecutionSession ES;
-  VSO &V = ES.createVSO("V");
-  SymbolStringPtr Foo = ES.getSymbolStringPool().intern("foo");
-  SymbolStringPtr Bar = ES.getSymbolStringPool().intern("bar");
-  SymbolStringPtr Baz = ES.getSymbolStringPool().intern("baz");
-  SymbolStringPtr Qux = ES.getSymbolStringPool().intern("qux");
-  static const JITTargetAddress FooAddr = 1U;
-  static const JITTargetAddress BarAddr = 2U;
-  static const JITTargetAddress BazAddr = 3U;
-  static const JITTargetAddress QuxAddr = 4U;
-  JITEvaluatedSymbol FooSym =
-      JITEvaluatedSymbol(FooAddr, JITSymbolFlags::Exported);
-  JITEvaluatedSymbol BarSym =
-      JITEvaluatedSymbol(BarAddr, JITSymbolFlags::Exported);
-  JITEvaluatedSymbol BazSym =
-      JITEvaluatedSymbol(BazAddr, JITSymbolFlags::Exported);
-  JITEvaluatedSymbol QuxSym =
-      JITEvaluatedSymbol(QuxAddr, JITSymbolFlags::Exported);
-};
-
-const JITTargetAddress CoreAPIsStandardTest::FooAddr;
-const JITTargetAddress CoreAPIsStandardTest::BarAddr;
-const JITTargetAddress CoreAPIsStandardTest::BazAddr;
-const JITTargetAddress CoreAPIsStandardTest::QuxAddr;
 
 TEST_F(CoreAPIsStandardTest, AsynchronousSymbolQuerySuccessfulResolutionOnly) {
   bool OnResolutionRun = false;
@@ -623,65 +585,6 @@ TEST_F(CoreAPIsStandardTest, FailResolut
   }
 }
 
-TEST_F(CoreAPIsStandardTest, TestLambdaSymbolResolver) {
-  cantFail(V.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
-
-  auto Resolver = createSymbolResolver(
-      [&](SymbolFlagsMap &SymbolFlags, const SymbolNameSet &Symbols) {
-        return V.lookupFlags(SymbolFlags, Symbols);
-      },
-      [&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
-        return V.lookup(std::move(Q), Symbols);
-      });
-
-  SymbolNameSet Symbols({Foo, Bar, Baz});
-
-  SymbolFlagsMap SymbolFlags;
-  SymbolNameSet SymbolsNotFound = Resolver->lookupFlags(SymbolFlags, Symbols);
-
-  EXPECT_EQ(SymbolFlags.size(), 2U)
-      << "lookupFlags returned the wrong number of results";
-  EXPECT_EQ(SymbolFlags.count(Foo), 1U) << "Missing lookupFlags result for foo";
-  EXPECT_EQ(SymbolFlags.count(Bar), 1U) << "Missing lookupFlags result for bar";
-  EXPECT_EQ(SymbolFlags[Foo], FooSym.getFlags())
-      << "Incorrect lookupFlags result for Foo";
-  EXPECT_EQ(SymbolFlags[Bar], BarSym.getFlags())
-      << "Incorrect lookupFlags result for Bar";
-  EXPECT_EQ(SymbolsNotFound.size(), 1U)
-      << "Expected one symbol not found in lookupFlags";
-  EXPECT_EQ(SymbolsNotFound.count(Baz), 1U)
-      << "Expected baz not to be found in lookupFlags";
-
-  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 OnReady = [&](Error Err) {
-    EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
-  };
-
-  auto Q = std::make_shared<AsynchronousSymbolQuery>(SymbolNameSet({Foo, Bar}),
-                                                     OnResolved, OnReady);
-  auto Unresolved = Resolver->lookup(std::move(Q), Symbols);
-
-  EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
-  EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to not be resolved";
-  EXPECT_TRUE(OnResolvedRun) << "OnResolved was never run";
-}
-
 TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
   auto MU = 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=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp Fri Jul 20 11:31:50 2018
@@ -14,8 +14,69 @@
 using namespace llvm;
 using namespace llvm::orc;
 
+class LegacyAPIsStandardTest : public CoreAPIsBasedStandardTest {};
+
 namespace {
 
+TEST_F(LegacyAPIsStandardTest, TestLambdaSymbolResolver) {
+  cantFail(V.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
+
+  auto Resolver = createSymbolResolver(
+      [&](SymbolFlagsMap &SymbolFlags, const SymbolNameSet &Symbols) {
+        return V.lookupFlags(SymbolFlags, Symbols);
+      },
+      [&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
+        return V.lookup(std::move(Q), Symbols);
+      });
+
+  SymbolNameSet Symbols({Foo, Bar, Baz});
+
+  SymbolFlagsMap SymbolFlags;
+  SymbolNameSet SymbolsNotFound = Resolver->lookupFlags(SymbolFlags, Symbols);
+
+  EXPECT_EQ(SymbolFlags.size(), 2U)
+      << "lookupFlags returned the wrong number of results";
+  EXPECT_EQ(SymbolFlags.count(Foo), 1U) << "Missing lookupFlags result for foo";
+  EXPECT_EQ(SymbolFlags.count(Bar), 1U) << "Missing lookupFlags result for bar";
+  EXPECT_EQ(SymbolFlags[Foo], FooSym.getFlags())
+      << "Incorrect lookupFlags result for Foo";
+  EXPECT_EQ(SymbolFlags[Bar], BarSym.getFlags())
+      << "Incorrect lookupFlags result for Bar";
+  EXPECT_EQ(SymbolsNotFound.size(), 1U)
+      << "Expected one symbol not found in lookupFlags";
+  EXPECT_EQ(SymbolsNotFound.count(Baz), 1U)
+      << "Expected baz not to be found in lookupFlags";
+
+  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 OnReady = [&](Error Err) {
+    EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
+  };
+
+  auto Q = std::make_shared<AsynchronousSymbolQuery>(SymbolNameSet({Foo, Bar}),
+                                                     OnResolved, OnReady);
+  auto Unresolved = Resolver->lookup(std::move(Q), Symbols);
+
+  EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
+  EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to not be resolved";
+  EXPECT_TRUE(OnResolvedRun) << "OnResolved was never run";
+}
+
 TEST(LegacyAPIInteropTest, QueryAgainstVSO) {
 
   ExecutionSession ES(std::make_shared<SymbolStringPool>());

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp Fri Jul 20 11:31:50 2018
@@ -15,6 +15,11 @@
 
 using namespace llvm;
 
+const JITTargetAddress llvm::orc::CoreAPIsBasedStandardTest::FooAddr;
+const JITTargetAddress llvm::orc::CoreAPIsBasedStandardTest::BarAddr;
+const JITTargetAddress llvm::orc::CoreAPIsBasedStandardTest::BazAddr;
+const JITTargetAddress llvm::orc::CoreAPIsBasedStandardTest::QuxAddr;
+
 bool OrcNativeTarget::NativeTargetInitialized = false;
 
 ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h?rev=337593&r1=337592&r2=337593&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/OrcTestCommon.h Fri Jul 20 11:31:50 2018
@@ -24,12 +24,52 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/TypeBuilder.h"
 #include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gtest/gtest.h"
+
 #include <memory>
 
 namespace llvm {
 
+namespace orc {
+// CoreAPIsStandardTest that saves a bunch of boilerplate by providing the
+// following:
+//
+// (1) ES -- An ExecutionSession
+// (2) Foo, Bar, Baz, Qux -- SymbolStringPtrs for strings "foo", "bar", "baz",
+//     and "qux" respectively.
+// (3) FooAddr, BarAddr, BazAddr, QuxAddr -- Dummy addresses. Guaranteed
+//     distinct and non-null.
+// (4) FooSym, BarSym, BazSym, QuxSym -- JITEvaluatedSymbols with FooAddr,
+//     BarAddr, BazAddr, and QuxAddr respectively. All with default strong,
+//     linkage and non-hidden visibility.
+// (5) V -- A VSO associated with ES.
+class CoreAPIsBasedStandardTest : public testing::Test {
+public:
+protected:
+  ExecutionSession ES;
+  VSO &V = ES.createVSO("V");
+  SymbolStringPtr Foo = ES.getSymbolStringPool().intern("foo");
+  SymbolStringPtr Bar = ES.getSymbolStringPool().intern("bar");
+  SymbolStringPtr Baz = ES.getSymbolStringPool().intern("baz");
+  SymbolStringPtr Qux = ES.getSymbolStringPool().intern("qux");
+  static const JITTargetAddress FooAddr = 1U;
+  static const JITTargetAddress BarAddr = 2U;
+  static const JITTargetAddress BazAddr = 3U;
+  static const JITTargetAddress QuxAddr = 4U;
+  JITEvaluatedSymbol FooSym =
+      JITEvaluatedSymbol(FooAddr, JITSymbolFlags::Exported);
+  JITEvaluatedSymbol BarSym =
+      JITEvaluatedSymbol(BarAddr, JITSymbolFlags::Exported);
+  JITEvaluatedSymbol BazSym =
+      JITEvaluatedSymbol(BazAddr, JITSymbolFlags::Exported);
+  JITEvaluatedSymbol QuxSym =
+      JITEvaluatedSymbol(QuxAddr, JITSymbolFlags::Exported);
+};
+
+} // end namespace orc
+
 class OrcNativeTarget {
 public:
   static void initialize() {




More information about the llvm-commits mailing list