[ORC] Add orc::SymbolResolver, a Orc/Legacy API interop header, and an
orc::SymbolResolver to JITSymbolResolver adapter.

The new orc::SymbolResolver interface uses asynchronous queries for better
performance. (Asynchronous queries with bulk lookup minimize RPC/IPC overhead,
support parallel incoming queries, and expose more available work for
distribution). Existing ORC layers will soon be updated to use the
orc::SymbolResolver API rather than the legacy llvm::JITSymbolResolver API.

Because RuntimeDyld still uses JITSymbolResolver, this patch also includes an
adapter that wraps an orc::SymbolResolver with a JITSymbolResolver API.

llvm-svn: 323073
diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
index ee64990..ca1b9ee 100644
--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
@@ -2,6 +2,7 @@
   Core.cpp
   ExecutionUtils.cpp
   IndirectionUtils.cpp
+  Legacy.cpp
   NullResolver.cpp
   OrcABISupport.cpp
   OrcCBindings.cpp
diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp
index 232c880..ff78ba1 100644
--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp
@@ -13,6 +13,7 @@
 namespace llvm {
 namespace orc {
 
+void SymbolResolver::anchor() {}
 void SymbolSource::anchor() {}
 
 AsynchronousSymbolQuery::AsynchronousSymbolQuery(
@@ -287,7 +288,7 @@
   }
 }
 
-VSO::LookupFlagsResult VSO::lookupFlags(SymbolNameSet Names) {
+LookupFlagsResult VSO::lookupFlags(SymbolNameSet Names) {
   SymbolFlagsMap FlagsFound;
 
   for (SymbolNameSet::iterator I = Names.begin(), E = Names.end(); I != E;) {
@@ -332,6 +333,8 @@
   return {std::move(MaterializationWork), std::move(Names)};
 }
 
+ExecutionSession::ExecutionSession(SymbolStringPool &SSP) : SSP(SSP) {}
+
 VModuleKey ExecutionSession::allocateVModule() { return ++LastKey; }
 
 void ExecutionSession::releaseVModule(VModuleKey VMod) {
diff --git a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp
new file mode 100644
index 0000000..e4eba8bd
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp
@@ -0,0 +1,75 @@
+//===------- Legacy.cpp - Adapters for ExecutionEngine API interop --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/Legacy.h"
+
+namespace llvm {
+namespace orc {
+
+JITSymbolResolverAdapter::JITSymbolResolverAdapter(ExecutionSession &ES,
+                                                   SymbolResolver &R)
+    : ES(ES), R(R) {}
+
+Expected<JITSymbolResolverAdapter::LookupResult>
+JITSymbolResolverAdapter::lookup(const LookupSet &Symbols) {
+  Error Err = Error::success();
+  JITSymbolResolver::LookupResult Result;
+
+  SymbolNameSet InternedSymbols;
+  for (auto &S : Symbols)
+    InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
+
+  auto OnResolve = [&](Expected<SymbolMap> R) {
+    if (R) {
+      for (auto &KV : *R) {
+        ResolvedStrings.insert(KV.first);
+        Result[*KV.first] = KV.second;
+      }
+    } else
+      Err = joinErrors(std::move(Err), R.takeError());
+  };
+
+  auto OnReady = [](Error Err) {
+    // FIXME: Report error to ExecutionSession.
+    logAllUnhandledErrors(std::move(Err), errs(),
+                          "legacy resolver received on-ready error:\n");
+  };
+
+  AsynchronousSymbolQuery Query(InternedSymbols, OnResolve, OnReady);
+
+  auto UnresolvedSymbols = R.lookup(Query, InternedSymbols);
+
+  if (!UnresolvedSymbols.empty())
+    Err = joinErrors(std::move(Err),
+                     make_error<StringError>("Unresolved symbols",
+                                             inconvertibleErrorCode()));
+
+  if (Err)
+    return std::move(Err);
+
+  return Result;
+}
+
+Expected<JITSymbolResolverAdapter::LookupFlagsResult>
+JITSymbolResolverAdapter::lookupFlags(const LookupSet &Symbols) {
+  SymbolNameSet InternedSymbols;
+  for (auto &S : Symbols)
+    InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
+
+  LookupFlagsResult Result;
+  for (auto &KV : R.lookupFlags(InternedSymbols).SymbolFlags) {
+    ResolvedStrings.insert(KV.first);
+    Result[*KV.first] = KV.second;
+  }
+
+  return Result;
+}
+
+} // End namespace orc.
+} // End namespace llvm.
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
index 670c6d2..2b3c00f 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
@@ -52,7 +52,7 @@
 ///        findSymbolInLogicalDylib and if that fails calling
 ///        findSymbol.
 Expected<JITSymbolResolver::LookupResult>
-LegacyJITSymbolResolver::lookup(const SymbolNameSet &Symbols) {
+LegacyJITSymbolResolver::lookup(const LookupSet &Symbols) {
   JITSymbolResolver::LookupResult Result;
   for (auto &Symbol : Symbols) {
     std::string SymName = Symbol.str();
@@ -84,7 +84,7 @@
 /// @brief Performs flags lookup by calling findSymbolInLogicalDylib and
 ///        returning the flags value for that symbol.
 Expected<JITSymbolResolver::LookupFlagsResult>
-LegacyJITSymbolResolver::lookupFlags(const SymbolNameSet &Symbols) {
+LegacyJITSymbolResolver::lookupFlags(const LookupSet &Symbols) {
   JITSymbolResolver::LookupFlagsResult Result;
 
   for (auto &Symbol : Symbols) {
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 9741a48..5c4b8c1 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -211,7 +211,7 @@
   // definitions occur elsewhere.
   JITSymbolResolver::LookupFlagsResult SymbolFlags;
   {
-    JITSymbolResolver::SymbolNameSet Symbols;
+    JITSymbolResolver::LookupSet Symbols;
     for (auto &Sym : Obj.symbols()) {
       uint32_t Flags = Sym.getFlags();
       if ((Flags & SymbolRef::SF_Common) || (Flags & SymbolRef::SF_Weak)) {
@@ -1000,10 +1000,10 @@
   // Resolution can trigger emission of more symbols, so iterate until
   // we've resolved *everything*.
   {
-    JITSymbolResolver::SymbolNameSet ResolvedSymbols;
+    JITSymbolResolver::LookupSet ResolvedSymbols;
 
     while (true) {
-      JITSymbolResolver::SymbolNameSet NewSymbols;
+      JITSymbolResolver::LookupSet NewSymbols;
 
       for (auto &RelocKV : ExternalSymbolRelocations) {
         StringRef Name = RelocKV.first();
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 0f4534f..3d944bf 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -731,7 +731,7 @@
 bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
   if (getRTDyld().getSymbol(Symbol))
     return true;
-  JITSymbolResolver::SymbolNameSet Symbols({Symbol});
+  JITSymbolResolver::LookupSet Symbols({Symbol});
   auto Result = getRTDyld().Resolver.lookup(Symbols);
   if (!Result) {
     logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
@@ -750,7 +750,7 @@
   if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
     return InternalSymbol.getAddress();
 
-  JITSymbolResolver::SymbolNameSet Symbols({Symbol});
+  JITSymbolResolver::LookupSet Symbols({Symbol});
   auto Result = getRTDyld().Resolver.lookup(Symbols);
   if (!Result) {
     logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");