[llvm] r321910 - [ORC] Re-apply just the AsynchronousSymbolLookup class from r321838 while I

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 5 14:50:43 PST 2018


Author: lhames
Date: Fri Jan  5 14:50:43 2018
New Revision: 321910

URL: http://llvm.org/viewvc/llvm-project?rev=321910&view=rev
Log:
[ORC] Re-apply just the AsynchronousSymbolLookup class from r321838 while I
investigate builder / test failures.

Added:
    llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
    llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
Modified:
    llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h
    llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h
    llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt
    llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp
    llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt

Modified: llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h?rev=321910&r1=321909&r2=321910&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h Fri Jan  5 14:50:43 2018
@@ -48,7 +48,9 @@ public:
     Weak = 1U << 1,
     Common = 1U << 2,
     Absolute = 1U << 3,
-    Exported = 1U << 4
+    Exported = 1U << 4,
+    NotMaterialized = 1U << 5,
+    Materializing = 1U << 6
   };
 
   /// @brief Default-construct a JITSymbolFlags instance.
@@ -67,6 +69,15 @@ public:
     return (Flags & HasError) == HasError;
   }
 
+  /// @brief Returns true if this symbol has been fully materialized (i.e. is
+  ///        callable).
+  bool isMaterialized() const { return !(Flags & NotMaterialized); }
+
+  /// @brief Returns true if this symbol is in the process of being
+  ///        materialized. This is generally only of interest as an
+  ///        implementation detail to JIT infrastructure.
+  bool isMaterializing() const { return Flags & Materializing; }
+
   /// @brief Returns true if the Weak flag is set.
   bool isWeak() const {
     return (Flags & Weak) == Weak;

Added: llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h?rev=321910&view=auto
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h (added)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h Fri Jan  5 14:50:43 2018
@@ -0,0 +1,88 @@
+//===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains core ORC APIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_CORE_H
+#define LLVM_EXECUTIONENGINE_ORC_CORE_H
+
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
+
+#include <functional>
+#include <map>
+#include <set>
+
+namespace llvm {
+namespace orc {
+
+/// @brief A set of symbol names (represented by SymbolStringPtrs for
+//         efficiency).
+using SymbolNameSet = std::set<SymbolStringPtr>;
+
+/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbols
+///        (address/flags pairs).
+using SymbolMap = std::map<SymbolStringPtr, JITSymbol>;
+
+/// @brief A symbol query that returns results via a callback when results are
+///        ready.
+///
+/// makes a callback when all symbols are available.
+class AsynchronousSymbolQuery {
+public:
+
+  /// @brief Callback to notify client that symbols have been resolved.
+  using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
+
+  /// @brief Callback to notify client that symbols are ready for execution.
+  using SymbolsReadyCallback = std::function<void(Error)>;
+
+  /// @brief Create a query for the given symbols, notify-resolved and
+  ///        notify-ready callbacks.
+  AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
+                          SymbolsResolvedCallback NotifySymbolsResolved,
+                          SymbolsReadyCallback NotifySymbolsReady);
+
+  /// @brief Notify client that the query failed.
+  ///
+  /// If the notify-resolved callback has not been made yet, then it is called
+  /// with the given error, and the notify-finalized callback is never made.
+  ///
+  /// If the notify-resolved callback has already been made then then the
+  /// notify-finalized callback is called with the given error.
+  ///
+  /// It is illegal to call setFailed after both callbacks have been made.
+  void setFailed(Error Err);
+
+  /// @brief Set the resolved symbol information for the given symbol name.
+  ///
+  /// If this symbol was the last one not resolved, this will trigger a call to
+  /// the notify-finalized callback passing the completed sybol map.
+  void setDefinition(SymbolStringPtr Name, JITSymbol Sym);
+
+  /// @brief Notify the query that a requested symbol is ready for execution.
+  ///
+  /// This decrements the query's internal count of not-yet-ready symbols. If
+  /// this call to notifySymbolFinalized sets the counter to zero, it will call
+  /// the notify-finalized callback with Error::success as the value.
+  void notifySymbolFinalized();
+private:
+  SymbolMap Symbols;
+  size_t OutstandingResolutions = 0;
+  size_t OutstandingFinalizations = 0;
+  SymbolsResolvedCallback NotifySymbolsResolved;
+  SymbolsReadyCallback NotifySymbolsReady;
+};
+
+} // End namespace orc
+} // End namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_CORE_H

Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h?rev=321910&r1=321909&r2=321910&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h Fri Jan  5 14:50:43 2018
@@ -22,7 +22,8 @@ namespace orc {
 
 enum class OrcErrorCode : int {
   // RPC Errors
-  JITSymbolNotFound = 1,
+  DuplicateDefinition = 1,
+  JITSymbolNotFound,
   RemoteAllocatorDoesNotExist,
   RemoteAllocatorIdAlreadyInUse,
   RemoteMProtectAddrUnrecognized,
@@ -39,6 +40,18 @@ enum class OrcErrorCode : int {
 
 std::error_code orcError(OrcErrorCode ErrCode);
 
+class DuplicateDefinition : public ErrorInfo<DuplicateDefinition> {
+public:
+  static char ID;
+
+  DuplicateDefinition(std::string SymbolName);
+  std::error_code convertToErrorCode() const override;
+  void log(raw_ostream &OS) const override;
+  const std::string &getSymbolName() const;
+private:
+  std::string SymbolName;
+};
+
 class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
 public:
   static char ID;

Modified: llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt?rev=321910&r1=321909&r2=321910&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt Fri Jan  5 14:50:43 2018
@@ -1,4 +1,5 @@
 add_llvm_library(LLVMOrcJIT
+  Core.cpp
   ExecutionUtils.cpp
   IndirectionUtils.cpp
   NullResolver.cpp

Added: llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp?rev=321910&view=auto
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp (added)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp Fri Jan  5 14:50:43 2018
@@ -0,0 +1,67 @@
+//===--------- Core.cpp - Core ORC APIs (SymbolSource, VSO, etc.) ---------===//
+//
+//                     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/Core.h"
+#include "llvm/ExecutionEngine/Orc/OrcError.h"
+
+namespace llvm {
+namespace orc {
+
+AsynchronousSymbolQuery::AsynchronousSymbolQuery(
+                                  const SymbolNameSet &Symbols,
+                                  SymbolsResolvedCallback NotifySymbolsResolved,
+                                  SymbolsReadyCallback NotifySymbolsReady)
+    : NotifySymbolsResolved(std::move(NotifySymbolsResolved)),
+      NotifySymbolsReady(std::move(NotifySymbolsReady)) {
+  assert(this->NotifySymbolsResolved &&
+         "Symbols resolved callback must be set");
+  assert(this->NotifySymbolsReady && "Symbols ready callback must be set");
+  OutstandingResolutions = OutstandingFinalizations = Symbols.size();
+}
+
+void AsynchronousSymbolQuery::setFailed(Error Err) {
+  OutstandingResolutions = OutstandingFinalizations = 0;
+  if (NotifySymbolsResolved)
+    NotifySymbolsResolved(std::move(Err));
+  else
+    NotifySymbolsReady(std::move(Err));
+}
+
+void AsynchronousSymbolQuery::setDefinition(SymbolStringPtr Name,
+                                            JITSymbol Sym) {
+  // If OutstandingResolutions is zero we must have errored out already. Just
+  // ignore this.
+  if (OutstandingResolutions == 0)
+    return;
+
+  assert(!Symbols.count(Name) &&
+         "Symbol has already been assigned an address");
+  Symbols.insert(std::make_pair(std::move(Name), std::move(Sym)));
+  --OutstandingResolutions;
+  if (OutstandingResolutions == 0) {
+    NotifySymbolsResolved(std::move(Symbols));
+    // Null out NotifySymbolsResolved to indicate that we've already called it.
+    NotifySymbolsResolved = {};
+  }
+}
+
+void AsynchronousSymbolQuery::notifySymbolFinalized() {
+  // If OutstandingFinalizations is zero we must have errored out already. Just
+  // ignore this.
+  if (OutstandingFinalizations == 0)
+    return;
+
+  assert(OutstandingFinalizations > 0 && "All symbols already finalized");
+  --OutstandingFinalizations;
+  if (OutstandingFinalizations == 0)
+    NotifySymbolsReady(Error::success());
+}
+
+} // End namespace orc.
+} // End namespace llvm.

Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp?rev=321910&r1=321909&r2=321910&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp Fri Jan  5 14:50:43 2018
@@ -29,6 +29,10 @@ public:
 
   std::string message(int condition) const override {
     switch (static_cast<OrcErrorCode>(condition)) {
+    case OrcErrorCode::DuplicateDefinition:
+      return "Duplicate symbol definition";
+    case OrcErrorCode::JITSymbolNotFound:
+      return "JIT symbol not found";
     case OrcErrorCode::RemoteAllocatorDoesNotExist:
       return "Remote allocator does not exist";
     case OrcErrorCode::RemoteAllocatorIdAlreadyInUse:
@@ -45,8 +49,6 @@ public:
       return "Could not negotiate RPC function";
     case OrcErrorCode::RPCResponseAbandoned:
       return "RPC response abandoned";
-    case OrcErrorCode::JITSymbolNotFound:
-      return "JIT symbol not found";
     case OrcErrorCode::UnexpectedRPCCall:
       return "Unexpected RPC call";
     case OrcErrorCode::UnexpectedRPCResponse:
@@ -67,6 +69,7 @@ static ManagedStatic<OrcErrorCategory> O
 namespace llvm {
 namespace orc {
 
+char DuplicateDefinition::ID = 0;
 char JITSymbolNotFound::ID = 0;
 
 std::error_code orcError(OrcErrorCode ErrCode) {
@@ -74,6 +77,22 @@ std::error_code orcError(OrcErrorCode Er
   return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat);
 }
 
+
+DuplicateDefinition::DuplicateDefinition(std::string SymbolName)
+  : SymbolName(std::move(SymbolName)) {}
+
+std::error_code DuplicateDefinition::convertToErrorCode() const {
+  return orcError(OrcErrorCode::DuplicateDefinition);
+}
+
+void DuplicateDefinition::log(raw_ostream &OS) const {
+  OS << "Duplicate definition of symbol '" << SymbolName << "'";
+}
+
+const std::string &DuplicateDefinition::getSymbolName() const {
+  return SymbolName;
+}
+
 JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName)
   : SymbolName(std::move(SymbolName)) {}
 

Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt?rev=321910&r1=321909&r2=321910&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt Fri Jan  5 14:50:43 2018
@@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_unittest(OrcJITTests
   CompileOnDemandLayerTest.cpp
+  CoreAPIsTest.cpp
   IndirectionUtilsTest.cpp
   GlobalMappingLayerTest.cpp
   LazyEmittingLayerTest.cpp

Added: llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp?rev=321910&view=auto
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp (added)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp Fri Jan  5 14:50:43 2018
@@ -0,0 +1,50 @@
+//===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
+//
+//                     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/Core.h"
+#include "OrcTestCommon.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::orc;
+
+namespace {
+
+TEST(CoreAPIsTest, AsynchronousSymbolQuerySuccessfulResolutionOnly) {
+  SymbolStringPool SP;
+  auto Foo = SP.intern("foo");
+  constexpr JITTargetAddress FakeAddr = 0xdeadbeef;
+  SymbolNameSet Names({Foo});
+
+  bool OnResolutionRun = false;
+  bool OnReadyRun = false;
+  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(cantFail(I->second.getAddress()), FakeAddr)
+        << "Resolution returned incorrect result";
+      OnResolutionRun = true;
+    };
+  auto OnReady = 
+    [&](Error Err) {
+      cantFail(std::move(Err));
+      OnResolutionRun = true;
+    };
+
+  AsynchronousSymbolQuery Q(Names, OnResolution, OnReady);
+
+  Q.setDefinition(Foo, JITSymbol(FakeAddr, JITSymbolFlags::Exported));
+
+  EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
+  EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
+}
+
+}




More information about the llvm-commits mailing list