[llvm] c0825fa - Revert "[ORC] Make MaterializationResponsibility immovable, pass by unique_ptr."

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 01:39:23 PDT 2020


Author: Florian Hahn
Date: 2020-09-11T09:35:20+01:00
New Revision: c0825fa5fc367bb7dc04a4b9dd4cc62abde04521

URL: https://github.com/llvm/llvm-project/commit/c0825fa5fc367bb7dc04a4b9dd4cc62abde04521
DIFF: https://github.com/llvm/llvm-project/commit/c0825fa5fc367bb7dc04a4b9dd4cc62abde04521.diff

LOG: Revert "[ORC] Make MaterializationResponsibility immovable, pass by unique_ptr."

This reverts commit c74900ca67241bf963b7a4cfa1fae8eadf6bb8cd.

This appears to be breaking some builds on macOS and has been causing
build failures on Green Dragon (see below). I am reverting this for now,
to unblock testing on Green Dragon.

http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental/18144/console

[65/187] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  -DBUILD_EXAMPLES -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iexamples/ThinLtoJIT -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT -Iinclude -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -O3  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -mmacosx-version-min=10.9    -fno-exceptions -fno-rtti -UNDEBUG -std=c++14 -MD -MT examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -MF examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o.d -o examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -c /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoDiscoveryThread.cpp
FAILED: examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  -DBUILD_EXAMPLES -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iexamples/ThinLtoJIT -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT -Iinclude -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -O3  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -mmacosx-version-min=10.9    -fno-exceptions -fno-rtti -UNDEBUG -std=c++14 -MD -MT examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -MF examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o.d -o examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -c /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoDiscoveryThread.cpp
In file included from /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoDiscoveryThread.cpp:7:
/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h:37:68: error: non-virtual member function marked 'override' hides virtual member function
  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
                                                                   ^
/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h:103:16: note: hidden overloaded virtual function 'llvm::orc::IRLayer::emit' declared here: type mismatch at 1st parameter ('std::unique_ptr<MaterializationResponsibility>' vs 'llvm::orc::MaterializationResponsibility')
  virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
               ^
1 error generated.

Added: 
    

Modified: 
    llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp
    llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
    llvm/include/llvm/ExecutionEngine/Orc/Core.h
    llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
    llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
    llvm/include/llvm/ExecutionEngine/Orc/Layer.h
    llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
    llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
    llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
    llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
    llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
    llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
    llvm/lib/ExecutionEngine/Orc/Core.cpp
    llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
    llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp
    llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
    llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
    llvm/lib/ExecutionEngine/Orc/Layer.cpp
    llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
    llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
    llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
    llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
    llvm/lib/ExecutionEngine/Orc/Speculation.cpp
    llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
    llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
    llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h

Removed: 
    


################################################################################
diff  --git a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp
index 24cf0847558f..4de4897053c1 100644
--- a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp
+++ b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp
@@ -113,13 +113,14 @@ class SpeculativeJIT {
     this->CODLayer.setImplMap(&Imps);
     this->ES->setDispatchMaterialization(
         [this](std::unique_ptr<MaterializationUnit> MU,
-               std::unique_ptr<MaterializationResponsibility> MR) {
-          CompileThreads.async(
-              [UnownedMU = MU.release(), UnownedMR = MR.release()]() {
-                std::unique_ptr<MaterializationUnit> MU(UnownedMU);
-                std::unique_ptr<MaterializationResponsibility> MR(UnownedMR);
-                MU->materialize(std::move(MR));
-              });
+               MaterializationResponsibility MR) {
+          // FIXME: Switch to move capture once we have C++14.
+          auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
+          auto SharedMR =
+            std::make_shared<MaterializationResponsibility>(std::move(MR));
+          CompileThreads.async([SharedMU, SharedMR]() {
+            SharedMU->materialize(std::move(*SharedMR));
+          });
         });
     ExitOnErr(S.addSpeculationRuntime(MainJD, Mangle));
     LocalCXXRuntimeOverrides CXXRuntimeoverrides;

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 3a2f8b54ad22..9ecc0464dec1 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -96,8 +96,7 @@ class CompileOnDemandLayer : public IRLayer {
 
   /// Emits the given module. This should not be called by clients: it will be
   /// called by the JIT when a definition added via the add method is requested.
-  void emit(std::unique_ptr<MaterializationResponsibility> R,
-            ThreadSafeModule TSM) override;
+  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
 
 private:
   struct PerDylibResources {
@@ -121,8 +120,7 @@ class CompileOnDemandLayer : public IRLayer {
 
   void expandPartition(GlobalValueSet &Partition);
 
-  void emitPartition(std::unique_ptr<MaterializationResponsibility> R,
-                     ThreadSafeModule TSM,
+  void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
                      IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
 
   mutable std::mutex CODLayerMutex;

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
index 70bd983c40ce..6951df3f2d3f 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -410,7 +410,7 @@ class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions
 class MaterializationResponsibility {
   friend class MaterializationUnit;
 public:
-  MaterializationResponsibility(MaterializationResponsibility &&) = delete;
+  MaterializationResponsibility(MaterializationResponsibility &&) = default;
   MaterializationResponsibility &
   operator=(MaterializationResponsibility &&) = delete;
 
@@ -514,8 +514,8 @@ class MaterializationResponsibility {
   /// Delegates responsibility for the given symbols to the returned
   /// materialization responsibility. Useful for breaking up work between
   /// threads, or 
diff erent kinds of materialization processes.
-  std::unique_ptr<MaterializationResponsibility>
-  delegate(const SymbolNameSet &Symbols, VModuleKey NewKey = VModuleKey());
+  MaterializationResponsibility delegate(const SymbolNameSet &Symbols,
+                                         VModuleKey NewKey = VModuleKey());
 
   void addDependencies(const SymbolStringPtr &Name,
                        const SymbolDependenceMap &Dependencies);
@@ -577,8 +577,7 @@ class MaterializationUnit {
   /// Implementations of this method should materialize all symbols
   ///        in the materialzation unit, except for those that have been
   ///        previously discarded.
-  virtual void
-  materialize(std::unique_ptr<MaterializationResponsibility> R) = 0;
+  virtual void materialize(MaterializationResponsibility R) = 0;
 
   /// Called by JITDylibs to notify MaterializationUnits that the given symbol
   /// has been overridden.
@@ -595,11 +594,10 @@ class MaterializationUnit {
 private:
   virtual void anchor();
 
-  std::unique_ptr<MaterializationResponsibility>
+  MaterializationResponsibility
   createMaterializationResponsibility(std::shared_ptr<JITDylib> JD) {
-    return std::unique_ptr<MaterializationResponsibility>(
-        new MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
-                                          std::move(InitSymbol), K));
+    return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
+                                         std::move(InitSymbol), K);
   }
 
   /// Implementations of this method should discard the given symbol
@@ -623,7 +621,7 @@ class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit {
   StringRef getName() const override;
 
 private:
-  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+  void materialize(MaterializationResponsibility R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolMap &Symbols);
 
@@ -665,7 +663,7 @@ class ReExportsMaterializationUnit : public MaterializationUnit {
   StringRef getName() const override;
 
 private:
-  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+  void materialize(MaterializationResponsibility R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
 
@@ -1118,7 +1116,7 @@ class ExecutionSession {
   /// For dispatching MaterializationUnit::materialize calls.
   using DispatchMaterializationFunction =
       std::function<void(std::unique_ptr<MaterializationUnit> MU,
-                         std::unique_ptr<MaterializationResponsibility> MR)>;
+                         MaterializationResponsibility MR)>;
 
   /// Construct an ExecutionSession.
   ///
@@ -1270,11 +1268,10 @@ class ExecutionSession {
          SymbolState RequiredState = SymbolState::Ready);
 
   /// Materialize the given unit.
-  void
-  dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
-                          std::unique_ptr<MaterializationResponsibility> MR) {
+  void dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
+                               MaterializationResponsibility MR) {
     assert(MU && "MU must be non-null");
-    DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU));
+    DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR.getTargetJITDylib(), *MU));
     DispatchMaterialization(std::move(MU), std::move(MR));
   }
 
@@ -1286,9 +1283,9 @@ class ExecutionSession {
     logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
   }
 
-  static void materializeOnCurrentThread(
-      std::unique_ptr<MaterializationUnit> MU,
-      std::unique_ptr<MaterializationResponsibility> MR) {
+  static void
+  materializeOnCurrentThread(std::unique_ptr<MaterializationUnit> MU,
+                             MaterializationResponsibility MR) {
     MU->materialize(std::move(MR));
   }
 
@@ -1312,7 +1309,7 @@ class ExecutionSession {
   //        with callbacks from asynchronous queries.
   mutable std::recursive_mutex OutstandingMUsMutex;
   std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
-                        std::unique_ptr<MaterializationResponsibility>>>
+                        MaterializationResponsibility>>
       OutstandingMUs;
 };
 

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index 2c53e2f66e85..eb74d283f043 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -55,8 +55,7 @@ class IRCompileLayer : public IRLayer {
 
   void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled);
 
-  void emit(std::unique_ptr<MaterializationResponsibility> R,
-            ThreadSafeModule TSM) override;
+  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
 
 private:
   mutable std::mutex IRLayerMutex;

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
index ee4ee3437fa6..296d74ae6b86 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -37,8 +37,7 @@ class IRTransformLayer : public IRLayer {
     this->Transform = std::move(Transform);
   }
 
-  void emit(std::unique_ptr<MaterializationResponsibility> R,
-            ThreadSafeModule TSM) override;
+  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
 
   static ThreadSafeModule identityTransform(ThreadSafeModule TSM,
                                             MaterializationResponsibility &R) {

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
index c8a41199760d..e843d0f56245 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
@@ -100,8 +100,7 @@ class IRLayer {
                     VModuleKey K = VModuleKey());
 
   /// Emit should materialize the given IR.
-  virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
-                    ThreadSafeModule TSM) = 0;
+  virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0;
 
 private:
   bool CloneToNewContextOnEmit = false;
@@ -118,7 +117,8 @@ class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
                                   ThreadSafeModule TSM, VModuleKey K);
 
 private:
-  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+
+  void materialize(MaterializationResponsibility R) override;
 
   IRLayer &L;
   VModuleKey K;
@@ -139,7 +139,7 @@ class ObjectLayer {
                     VModuleKey K = VModuleKey());
 
   /// Emit should materialize the given IR.
-  virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
+  virtual void emit(MaterializationResponsibility R,
                     std::unique_ptr<MemoryBuffer> O) = 0;
 
 private:
@@ -162,7 +162,8 @@ class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
   StringRef getName() const override;
 
 private:
-  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+
+  void materialize(MaterializationResponsibility R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
 
   ObjectLayer &L;

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
index 63e3a80d87d8..9206e40fffb1 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
@@ -149,7 +149,7 @@ class LazyReexportsMaterializationUnit : public MaterializationUnit {
   StringRef getName() const override;
 
 private:
-  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
+  void materialize(MaterializationResponsibility R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
 

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index cbcf3928be3d..cb8ee130ab61 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -119,7 +119,7 @@ class ObjectLinkingLayer : public ObjectLayer {
   }
 
   /// Emit the object.
-  void emit(std::unique_ptr<MaterializationResponsibility> R,
+  void emit(MaterializationResponsibility R,
             std::unique_ptr<MemoryBuffer> O) override;
 
   /// Instructs this ObjectLinkingLayer instance to override the symbol flags

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
index c77649f19fc7..bf989cc8677c 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
@@ -31,7 +31,7 @@ class ObjectTransformLayer : public ObjectLayer {
   ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
                        TransformFunction Transform = TransformFunction());
 
-  void emit(std::unique_ptr<MaterializationResponsibility> R,
+  void emit(MaterializationResponsibility R,
             std::unique_ptr<MemoryBuffer> O) override;
 
   void setTransform(TransformFunction Transform) {

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index 9cd3c57a19c6..9ada0871cf0c 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -58,7 +58,7 @@ class RTDyldObjectLinkingLayer : public ObjectLayer {
   ~RTDyldObjectLinkingLayer();
 
   /// Emit the object.
-  void emit(std::unique_ptr<MaterializationResponsibility> R,
+  void emit(MaterializationResponsibility R,
             std::unique_ptr<MemoryBuffer> O) override;
 
   /// Set the NotifyLoaded callback.

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
index a138f60a7756..10f78c8bc6be 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
@@ -181,8 +181,7 @@ class IRSpeculationLayer : public IRLayer {
       : IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer),
         S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {}
 
-  void emit(std::unique_ptr<MaterializationResponsibility> R,
-            ThreadSafeModule TSM) override;
+  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
 
 private:
   TargetAndLikelies

diff  --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
index dfb0d06bdba3..9e38dc36faae 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
@@ -88,7 +88,7 @@ class PartitioningIRMaterializationUnit : public IRMaterializationUnit {
         Parent(Parent) {}
 
 private:
-  void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
+  void materialize(MaterializationResponsibility R) override {
     Parent.emitPartition(std::move(R), std::move(TSM),
                          std::move(SymbolToDefinition));
   }
@@ -128,15 +128,15 @@ void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) {
 void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) {
   this->AliaseeImpls = Imp;
 }
-void CompileOnDemandLayer::emit(
-    std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM) {
+void CompileOnDemandLayer::emit(MaterializationResponsibility R,
+                                ThreadSafeModule TSM) {
   assert(TSM && "Null module");
 
   auto &ES = getExecutionSession();
 
   // Sort the callables and non-callables, build re-exports and lodge the
   // actual module with the implementation dylib.
-  auto &PDR = getPerDylibResources(R->getTargetJITDylib());
+  auto &PDR = getPerDylibResources(R.getTargetJITDylib());
 
   SymbolAliasMap NonCallables;
   SymbolAliasMap Callables;
@@ -145,7 +145,7 @@ void CompileOnDemandLayer::emit(
     cleanUpModule(M);
   });
 
-  for (auto &KV : R->getSymbols()) {
+  for (auto &KV : R.getSymbols()) {
     auto &Name = KV.first;
     auto &Flags = KV.second;
     if (Flags.isCallable())
@@ -158,19 +158,19 @@ void CompileOnDemandLayer::emit(
   // implementation dylib.
   if (auto Err = PDR.getImplDylib().define(
           std::make_unique<PartitioningIRMaterializationUnit>(
-              ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(),
+              ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(),
               *this))) {
     ES.reportError(std::move(Err));
-    R->failMaterialization();
+    R.failMaterialization();
     return;
   }
 
   if (!NonCallables.empty())
-    R->replace(reexports(PDR.getImplDylib(), std::move(NonCallables),
-                         JITDylibLookupFlags::MatchAllSymbols));
+    R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables),
+                        JITDylibLookupFlags::MatchAllSymbols));
   if (!Callables.empty())
-    R->replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
-                             std::move(Callables), AliaseeImpls));
+    R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
+                            std::move(Callables), AliaseeImpls));
 }
 
 CompileOnDemandLayer::PerDylibResources &
@@ -247,7 +247,7 @@ void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) {
 }
 
 void CompileOnDemandLayer::emitPartition(
-    std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM,
+    MaterializationResponsibility R, ThreadSafeModule TSM,
     IRMaterializationUnit::SymbolNameToDefinitionMap Defs) {
 
   // FIXME: Need a 'notify lazy-extracting/emitting' callback to tie the
@@ -257,8 +257,8 @@ void CompileOnDemandLayer::emitPartition(
 
   auto &ES = getExecutionSession();
   GlobalValueSet RequestedGVs;
-  for (auto &Name : R->getRequestedSymbols()) {
-    if (Name == R->getInitializerSymbol())
+  for (auto &Name : R.getRequestedSymbols()) {
+    if (Name == R.getInitializerSymbol())
       TSM.withModuleDo([&](Module &M) {
         for (auto &GV : getStaticInitGVs(M))
           RequestedGVs.insert(&GV);
@@ -285,9 +285,9 @@ void CompileOnDemandLayer::emitPartition(
 
   // If the partition is empty, return the whole module to the symbol table.
   if (GVsToExtract->empty()) {
-    R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
-        std::move(TSM), R->getVModuleKey(), R->getSymbols(),
-        R->getInitializerSymbol(), std::move(Defs), *this));
+    R.replace(std::make_unique<PartitioningIRMaterializationUnit>(
+        std::move(TSM), R.getVModuleKey(), R.getSymbols(),
+        R.getInitializerSymbol(), std::move(Defs), *this));
     return;
   }
 
@@ -308,7 +308,7 @@ void CompileOnDemandLayer::emitPartition(
           IRSymbolMapper::add(ES, *getManglingOptions(),
                               PromotedGlobals, SymbolFlags);
 
-          if (auto Err = R->defineMaterializing(SymbolFlags))
+          if (auto Err = R.defineMaterializing(SymbolFlags))
             return std::move(Err);
         }
 
@@ -348,12 +348,12 @@ void CompileOnDemandLayer::emitPartition(
 
   if (!ExtractedTSM) {
     ES.reportError(ExtractedTSM.takeError());
-    R->failMaterialization();
+    R.failMaterialization();
     return;
   }
 
-  R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
-      ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), *this));
+  R.replace(std::make_unique<PartitioningIRMaterializationUnit>(
+      ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), *this));
   BaseLayer.emit(std::move(R), std::move(*ExtractedTSM));
 }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp
index 243bac79c012..18eced68f07b 100644
--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp
@@ -279,7 +279,7 @@ void MaterializationResponsibility::replace(
   JD->replace(std::move(MU));
 }
 
-std::unique_ptr<MaterializationResponsibility>
+MaterializationResponsibility
 MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
                                         VModuleKey NewKey) {
 
@@ -302,10 +302,9 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
     SymbolFlags.erase(I);
   }
 
-  return std::unique_ptr<MaterializationResponsibility>(
-      new MaterializationResponsibility(JD, std::move(DelegatedFlags),
-                                        std::move(DelegatedInitSymbol),
-                                        std::move(NewKey)));
+  return MaterializationResponsibility(JD, std::move(DelegatedFlags),
+                                       std::move(DelegatedInitSymbol),
+                                       std::move(NewKey));
 }
 
 void MaterializationResponsibility::addDependencies(
@@ -339,10 +338,10 @@ StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
 }
 
 void AbsoluteSymbolsMaterializationUnit::materialize(
-    std::unique_ptr<MaterializationResponsibility> R) {
+    MaterializationResponsibility R) {
   // No dependencies, so these calls can't fail.
-  cantFail(R->notifyResolved(Symbols));
-  cantFail(R->notifyEmitted());
+  cantFail(R.notifyResolved(Symbols));
+  cantFail(R.notifyEmitted());
 }
 
 void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
@@ -371,16 +370,16 @@ StringRef ReExportsMaterializationUnit::getName() const {
 }
 
 void ReExportsMaterializationUnit::materialize(
-    std::unique_ptr<MaterializationResponsibility> R) {
+    MaterializationResponsibility R) {
 
-  auto &ES = R->getTargetJITDylib().getExecutionSession();
-  JITDylib &TgtJD = R->getTargetJITDylib();
+  auto &ES = R.getTargetJITDylib().getExecutionSession();
+  JITDylib &TgtJD = R.getTargetJITDylib();
   JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
 
   // Find the set of requested aliases and aliasees. Return any unrequested
   // aliases back to the JITDylib so as to not prematurely materialize any
   // aliasees.
-  auto RequestedSymbols = R->getRequestedSymbols();
+  auto RequestedSymbols = R.getRequestedSymbols();
   SymbolAliasMap RequestedAliases;
 
   for (auto &Name : RequestedSymbols) {
@@ -400,19 +399,18 @@ void ReExportsMaterializationUnit::materialize(
 
   if (!Aliases.empty()) {
     if (SourceJD)
-      R->replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
+      R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
     else
-      R->replace(symbolAliases(std::move(Aliases)));
+      R.replace(symbolAliases(std::move(Aliases)));
   }
 
   // The OnResolveInfo struct will hold the aliases and responsibilty for each
   // query in the list.
   struct OnResolveInfo {
-    OnResolveInfo(std::unique_ptr<MaterializationResponsibility> R,
-                  SymbolAliasMap Aliases)
+    OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases)
         : R(std::move(R)), Aliases(std::move(Aliases)) {}
 
-    std::unique_ptr<MaterializationResponsibility> R;
+    MaterializationResponsibility R;
     SymbolAliasMap Aliases;
   };
 
@@ -453,7 +451,7 @@ void ReExportsMaterializationUnit::materialize(
     assert(!QuerySymbols.empty() && "Alias cycle detected!");
 
     auto QueryInfo = std::make_shared<OnResolveInfo>(
-        R->delegate(ResponsibilitySymbols), std::move(QueryAliases));
+        R.delegate(ResponsibilitySymbols), std::move(QueryAliases));
     QueryInfos.push_back(
         make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
   }
@@ -482,12 +480,12 @@ void ReExportsMaterializationUnit::materialize(
       for (auto &KV : QueryInfo->Aliases)
         if (SrcJDDeps.count(KV.second.Aliasee)) {
           PerAliasDeps = {KV.second.Aliasee};
-          QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap);
+          QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
         }
     };
 
     auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
-      auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession();
+      auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
       if (Result) {
         SymbolMap ResolutionMap;
         for (auto &KV : QueryInfo->Aliases) {
@@ -501,19 +499,19 @@ void ReExportsMaterializationUnit::materialize(
           ResolutionMap[KV.first] = JITEvaluatedSymbol(
               (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
         }
-        if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) {
+        if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) {
           ES.reportError(std::move(Err));
-          QueryInfo->R->failMaterialization();
+          QueryInfo->R.failMaterialization();
           return;
         }
-        if (auto Err = QueryInfo->R->notifyEmitted()) {
+        if (auto Err = QueryInfo->R.notifyEmitted()) {
           ES.reportError(std::move(Err));
-          QueryInfo->R->failMaterialization();
+          QueryInfo->R.failMaterialization();
           return;
         }
       } else {
         ES.reportError(Result.takeError());
-        QueryInfo->R->failMaterialization();
+        QueryInfo->R.failMaterialization();
       }
     };
 
@@ -2133,7 +2131,7 @@ void ExecutionSession::dump(raw_ostream &OS) {
 void ExecutionSession::runOutstandingMUs() {
   while (1) {
     Optional<std::pair<std::unique_ptr<MaterializationUnit>,
-                       std::unique_ptr<MaterializationResponsibility>>>
+                       MaterializationResponsibility>>
         JMU;
 
     {

diff  --git a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
index c6f687027972..023940dc8298 100644
--- a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
@@ -25,7 +25,7 @@ void IRCompileLayer::setNotifyCompiled(NotifyCompiledFunction NotifyCompiled) {
   this->NotifyCompiled = std::move(NotifyCompiled);
 }
 
-void IRCompileLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
+void IRCompileLayer::emit(MaterializationResponsibility R,
                           ThreadSafeModule TSM) {
   assert(TSM && "Module must not be null");
 
@@ -33,13 +33,13 @@ void IRCompileLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
     {
       std::lock_guard<std::mutex> Lock(IRLayerMutex);
       if (NotifyCompiled)
-        NotifyCompiled(R->getVModuleKey(), std::move(TSM));
+        NotifyCompiled(R.getVModuleKey(), std::move(TSM));
       else
         TSM = ThreadSafeModule();
     }
     BaseLayer.emit(std::move(R), std::move(*Obj));
   } else {
-    R->failMaterialization();
+    R.failMaterialization();
     getExecutionSession().reportError(Obj.takeError());
   }
 }

diff  --git a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp
index d5b11349277c..511248f83b25 100644
--- a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp
@@ -17,14 +17,14 @@ IRTransformLayer::IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer,
     : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer),
       Transform(std::move(Transform)) {}
 
-void IRTransformLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
+void IRTransformLayer::emit(MaterializationResponsibility R,
                             ThreadSafeModule TSM) {
   assert(TSM && "Module must not be null");
 
-  if (auto TransformedTSM = Transform(std::move(TSM), *R))
+  if (auto TransformedTSM = Transform(std::move(TSM), R))
     BaseLayer.emit(std::move(R), std::move(*TransformedTSM));
   else {
-    R->failMaterialization();
+    R.failMaterialization();
     getExecutionSession().reportError(TransformedTSM.takeError());
   }
 }

diff  --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index 7d57ed5a3a04..4f7f6089e68d 100644
--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -33,12 +33,12 @@ class CompileCallbackMaterializationUnit : public orc::MaterializationUnit {
   StringRef getName() const override { return "<Compile Callbacks>"; }
 
 private:
-  void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
+  void materialize(MaterializationResponsibility R) override {
     SymbolMap Result;
     Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported);
     // No dependencies, so these calls cannot fail.
-    cantFail(R->notifyResolved(Result));
-    cantFail(R->notifyEmitted());
+    cantFail(R.notifyResolved(Result));
+    cantFail(R.notifyEmitted());
   }
 
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {

diff  --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index 81f500d66bc2..373d86d92f8d 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -1085,17 +1085,15 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
         std::make_unique<ThreadPool>(hardware_concurrency(S.NumCompileThreads));
     ES->setDispatchMaterialization(
         [this](std::unique_ptr<MaterializationUnit> MU,
-               std::unique_ptr<MaterializationResponsibility> MR) {
-          // FIXME: We should be able to use move-capture here, but ThreadPool's
-          // AsyncTaskTys are std::functions rather than unique_functions
-          // (because MSVC's std::packaged_tasks don't support move-only types).
-          // Fix this when all the above gets sorted out.
-          CompileThreads->async(
-              [UnownedMU = MU.release(), UnownedMR = MR.release()]() mutable {
-                std::unique_ptr<MaterializationUnit> MU(UnownedMU);
-                std::unique_ptr<MaterializationResponsibility> MR(UnownedMR);
-                MU->materialize(std::move(MR));
-              });
+               MaterializationResponsibility MR) {
+          // FIXME: Switch to move capture once ThreadPool uses unique_function.
+          auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
+          auto SharedMR =
+              std::make_shared<MaterializationResponsibility>(std::move(MR));
+          auto Work = [SharedMU, SharedMR]() mutable {
+            SharedMU->materialize(std::move(*SharedMR));
+          };
+          CompileThreads->async(std::move(Work));
         });
   }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
index 8052e7b08a5a..0a5d5577e99e 100644
--- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
@@ -133,7 +133,7 @@ BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
       L(L), K(std::move(K)) {}
 
 void BasicIRLayerMaterializationUnit::materialize(
-    std::unique_ptr<MaterializationResponsibility> R) {
+    MaterializationResponsibility R) {
 
   // Throw away the SymbolToDefinition map: it's not usable after we hand
   // off the module.
@@ -144,8 +144,8 @@ void BasicIRLayerMaterializationUnit::materialize(
     TSM = cloneToNewContext(TSM);
 
 #ifndef NDEBUG
-  auto &ES = R->getTargetJITDylib().getExecutionSession();
-  auto &N = R->getTargetJITDylib().getName();
+  auto &ES = R.getTargetJITDylib().getExecutionSession();
+  auto &N = R.getTargetJITDylib().getName();
 #endif // NDEBUG
 
   LLVM_DEBUG(ES.runSessionLocked(
@@ -200,7 +200,7 @@ StringRef BasicObjectLayerMaterializationUnit::getName() const {
 }
 
 void BasicObjectLayerMaterializationUnit::materialize(
-    std::unique_ptr<MaterializationResponsibility> R) {
+    MaterializationResponsibility R) {
   L.emit(std::move(R), std::move(O));
 }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
index 695f6cc9c1cb..5e604130d6ea 100644
--- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
@@ -154,8 +154,8 @@ StringRef LazyReexportsMaterializationUnit::getName() const {
 }
 
 void LazyReexportsMaterializationUnit::materialize(
-    std::unique_ptr<MaterializationResponsibility> R) {
-  auto RequestedSymbols = R->getRequestedSymbols();
+    MaterializationResponsibility R) {
+  auto RequestedSymbols = R.getRequestedSymbols();
 
   SymbolAliasMap RequestedAliases;
   for (auto &RequestedSymbol : RequestedSymbols) {
@@ -166,8 +166,8 @@ void LazyReexportsMaterializationUnit::materialize(
   }
 
   if (!CallableAliases.empty())
-    R->replace(lazyReexports(LCTManager, ISManager, SourceJD,
-                             std::move(CallableAliases), AliaseeTable));
+    R.replace(lazyReexports(LCTManager, ISManager, SourceJD,
+                            std::move(CallableAliases), AliaseeTable));
 
   IndirectStubsManager::StubInitsMap StubInits;
   for (auto &Alias : RequestedAliases) {
@@ -182,7 +182,7 @@ void LazyReexportsMaterializationUnit::materialize(
     if (!CallThroughTrampoline) {
       SourceJD.getExecutionSession().reportError(
           CallThroughTrampoline.takeError());
-      R->failMaterialization();
+      R.failMaterialization();
       return;
     }
 
@@ -195,7 +195,7 @@ void LazyReexportsMaterializationUnit::materialize(
 
   if (auto Err = ISManager.createStubs(StubInits)) {
     SourceJD.getExecutionSession().reportError(std::move(Err));
-    R->failMaterialization();
+    R.failMaterialization();
     return;
   }
 
@@ -204,8 +204,8 @@ void LazyReexportsMaterializationUnit::materialize(
     Stubs[Alias.first] = ISManager.findStub(*Alias.first, false);
 
   // No registered dependencies, so these calls cannot fail.
-  cantFail(R->notifyResolved(Stubs));
-  cantFail(R->notifyEmitted());
+  cantFail(R.notifyResolved(Stubs));
+  cantFail(R.notifyEmitted());
 }
 
 void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,

diff  --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
index 9e3245d9cc99..d8283fa7e346 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -24,10 +24,9 @@ namespace orc {
 
 class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
 public:
-  ObjectLinkingLayerJITLinkContext(
-      ObjectLinkingLayer &Layer,
-      std::unique_ptr<MaterializationResponsibility> MR,
-      std::unique_ptr<MemoryBuffer> ObjBuffer)
+  ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer,
+                                   MaterializationResponsibility MR,
+                                   std::unique_ptr<MemoryBuffer> ObjBuffer)
       : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
 
   ~ObjectLinkingLayerJITLinkContext() {
@@ -45,14 +44,14 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
 
   void notifyFailed(Error Err) override {
     Layer.getExecutionSession().reportError(std::move(Err));
-    MR->failMaterialization();
+    MR.failMaterialization();
   }
 
   void lookup(const LookupMap &Symbols,
               std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
 
     JITDylibSearchOrder LinkOrder;
-    MR->getTargetJITDylib().withLinkOrderDo(
+    MR.getTargetJITDylib().withLinkOrderDo(
         [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; });
 
     auto &ES = Layer.getExecutionSession();
@@ -86,8 +85,8 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
 
     for (auto &KV : InternalNamedSymbolDeps) {
       SymbolDependenceMap InternalDeps;
-      InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second);
-      MR->addDependencies(KV.first, InternalDeps);
+      InternalDeps[&MR.getTargetJITDylib()] = std::move(KV.second);
+      MR.addDependencies(KV.first, InternalDeps);
     }
 
     ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet),
@@ -116,7 +115,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
 
         InternedResult[InternedName] =
             JITEvaluatedSymbol(Sym->getAddress(), Flags);
-        if (AutoClaim && !MR->getSymbols().count(InternedName)) {
+        if (AutoClaim && !MR.getSymbols().count(InternedName)) {
           assert(!ExtraSymbolsToClaim.count(InternedName) &&
                  "Duplicate symbol to claim?");
           ExtraSymbolsToClaim[InternedName] = Flags;
@@ -134,7 +133,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
           Flags |= JITSymbolFlags::Weak;
         InternedResult[InternedName] =
             JITEvaluatedSymbol(Sym->getAddress(), Flags);
-        if (AutoClaim && !MR->getSymbols().count(InternedName)) {
+        if (AutoClaim && !MR.getSymbols().count(InternedName)) {
           assert(!ExtraSymbolsToClaim.count(InternedName) &&
                  "Duplicate symbol to claim?");
           ExtraSymbolsToClaim[InternedName] = Flags;
@@ -142,19 +141,19 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
       }
 
     if (!ExtraSymbolsToClaim.empty())
-      if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim))
+      if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim))
         return Err;
 
     {
 
-      // Check that InternedResult matches up with MR->getSymbols().
+      // Check that InternedResult matches up with MR.getSymbols().
       // This guards against faulty transformations / compilers / object caches.
 
       // First check that there aren't any missing symbols.
       size_t NumMaterializationSideEffectsOnlySymbols = 0;
       SymbolNameVector ExtraSymbols;
       SymbolNameVector MissingSymbols;
-      for (auto &KV : MR->getSymbols()) {
+      for (auto &KV : MR.getSymbols()) {
 
         // If this is a materialization-side-effects only symbol then bump
         // the counter and make sure it's *not* defined, otherwise make
@@ -176,9 +175,9 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
       // If there are more definitions than expected, add them to the
       // ExtraSymbols vector.
       if (InternedResult.size() >
-          MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) {
+          MR.getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) {
         for (auto &KV : InternedResult)
-          if (!MR->getSymbols().count(KV.first))
+          if (!MR.getSymbols().count(KV.first))
             ExtraSymbols.push_back(KV.first);
       }
 
@@ -188,23 +187,23 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
                                                        std::move(ExtraSymbols));
     }
 
-    if (auto Err = MR->notifyResolved(InternedResult))
+    if (auto Err = MR.notifyResolved(InternedResult))
       return Err;
 
-    Layer.notifyLoaded(*MR);
+    Layer.notifyLoaded(MR);
     return Error::success();
   }
 
   void notifyFinalized(
       std::unique_ptr<JITLinkMemoryManager::Allocation> A) override {
-    if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) {
+    if (auto Err = Layer.notifyEmitted(MR, std::move(A))) {
       Layer.getExecutionSession().reportError(std::move(Err));
-      MR->failMaterialization();
+      MR.failMaterialization();
       return;
     }
-    if (auto Err = MR->notifyEmitted()) {
+    if (auto Err = MR.notifyEmitted()) {
       Layer.getExecutionSession().reportError(std::move(Err));
-      MR->failMaterialization();
+      MR.failMaterialization();
     }
   }
 
@@ -218,7 +217,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
     Config.PrePrunePasses.push_back(
         [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); });
 
-    Layer.modifyPassConfig(*MR, TT, Config);
+    Layer.modifyPassConfig(MR, TT, Config);
 
     Config.PostPrunePasses.push_back(
         [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); });
@@ -238,13 +237,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
     auto &ES = Layer.getExecutionSession();
     for (auto *Sym : G.defined_symbols())
       if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
-        if (!MR->getSymbols().count(ES.intern(Sym->getName())))
+        if (!MR.getSymbols().count(ES.intern(Sym->getName())))
           G.makeExternal(*Sym);
       }
 
     for (auto *Sym : G.absolute_symbols())
       if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
-        if (!MR->getSymbols().count(ES.intern(Sym->getName())))
+        if (!MR.getSymbols().count(ES.intern(Sym->getName())))
           G.makeExternal(*Sym);
       }
 
@@ -254,13 +253,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
   Error markResponsibilitySymbolsLive(LinkGraph &G) const {
     auto &ES = Layer.getExecutionSession();
     for (auto *Sym : G.defined_symbols())
-      if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName())))
+      if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName())))
         Sym->setLive(true);
     return Error::success();
   }
 
   Error computeNamedSymbolDependencies(LinkGraph &G) {
-    auto &ES = MR->getTargetJITDylib().getExecutionSession();
+    auto &ES = MR.getTargetJITDylib().getExecutionSession();
     auto LocalDeps = computeLocalDeps(G);
 
     // Compute dependencies for symbols defined in the JITLink graph.
@@ -307,7 +306,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
     }
 
     for (auto &P : Layer.Plugins) {
-      auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR);
+      auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(MR);
       if (SyntheticLocalDeps.empty())
         continue;
 
@@ -427,12 +426,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
           SymbolDeps.erase(&SourceJD);
       }
 
-      MR->addDependencies(Name, SymbolDeps);
+      MR.addDependencies(Name, SymbolDeps);
     }
   }
 
   ObjectLinkingLayer &Layer;
-  std::unique_ptr<MaterializationResponsibility> MR;
+  MaterializationResponsibility MR;
   std::unique_ptr<MemoryBuffer> ObjBuffer;
   DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps;
   DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps;
@@ -453,7 +452,7 @@ ObjectLinkingLayer::~ObjectLinkingLayer() {
     getExecutionSession().reportError(std::move(Err));
 }
 
-void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
+void ObjectLinkingLayer::emit(MaterializationResponsibility R,
                               std::unique_ptr<MemoryBuffer> O) {
   assert(O && "Object must not be null");
   jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>(

diff  --git a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
index a57662e10a79..d18eb38a4142 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
@@ -17,9 +17,8 @@ ObjectTransformLayer::ObjectTransformLayer(ExecutionSession &ES,
                                             TransformFunction Transform)
     : ObjectLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
 
-void ObjectTransformLayer::emit(
-    std::unique_ptr<MaterializationResponsibility> R,
-    std::unique_ptr<MemoryBuffer> O) {
+void ObjectTransformLayer::emit(MaterializationResponsibility R,
+                                std::unique_ptr<MemoryBuffer> O) {
   assert(O && "Module must not be null");
 
   // If there is a transform set then apply it.
@@ -27,7 +26,7 @@ void ObjectTransformLayer::emit(
     if (auto TransformedObj = Transform(std::move(O)))
       O = std::move(*TransformedObj);
     else {
-      R->failMaterialization();
+      R.failMaterialization();
       getExecutionSession().reportError(TransformedObj.takeError());
       return;
     }

diff  --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
index 1981039eb9f1..7888c2fcbdbd 100644
--- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
@@ -89,18 +89,23 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() {
   }
 }
 
-void RTDyldObjectLinkingLayer::emit(
-    std::unique_ptr<MaterializationResponsibility> R,
-    std::unique_ptr<MemoryBuffer> O) {
+void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
+                                    std::unique_ptr<MemoryBuffer> O) {
   assert(O && "Object must not be null");
 
+  // This method launches an asynchronous link step that will fulfill our
+  // materialization responsibility. We need to switch R to be heap
+  // allocated before that happens so it can live as long as the asynchronous
+  // link needs it to (i.e. it must be able to outlive this method).
+  auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R));
+
   auto &ES = getExecutionSession();
 
   auto Obj = object::ObjectFile::createObjectFile(*O);
 
   if (!Obj) {
     getExecutionSession().reportError(Obj.takeError());
-    R->failMaterialization();
+    SharedR->failMaterialization();
     return;
   }
 
@@ -116,7 +121,7 @@ void RTDyldObjectLinkingLayer::emit(
           continue;
       } else {
         ES.reportError(SymType.takeError());
-        R->failMaterialization();
+        R.failMaterialization();
         return;
       }
 
@@ -124,7 +129,7 @@ void RTDyldObjectLinkingLayer::emit(
       if (!SymFlagsOrErr) {
         // TODO: Test this error.
         ES.reportError(SymFlagsOrErr.takeError());
-        R->failMaterialization();
+        R.failMaterialization();
         return;
       }
 
@@ -134,14 +139,14 @@ void RTDyldObjectLinkingLayer::emit(
           InternalSymbols->insert(*SymName);
         else {
           ES.reportError(SymName.takeError());
-          R->failMaterialization();
+          R.failMaterialization();
           return;
         }
       }
     }
   }
 
-  auto K = R->getVModuleKey();
+  auto K = R.getVModuleKey();
   RuntimeDyld::MemoryManager *MemMgr = nullptr;
 
   // Create a record a memory manager for this object.
@@ -152,10 +157,6 @@ void RTDyldObjectLinkingLayer::emit(
     MemMgr = MemMgrs.back().get();
   }
 
-  // Switch to shared ownership of MR so that it can be captured by both
-  // lambdas below.
-  std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
-
   JITDylibSearchOrderResolver Resolver(*SharedR);
 
   jitLinkForORC(

diff  --git a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp
index 0b4755fe23cf..3dd536d8253e 100644
--- a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp
@@ -55,7 +55,7 @@ Error Speculator::addSpeculationRuntime(JITDylib &JD,
 // If two modules, share the same LLVMContext, 
diff erent threads must
 // not access them concurrently without locking the associated LLVMContext
 // this implementation follows this contract.
-void IRSpeculationLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
+void IRSpeculationLayer::emit(MaterializationResponsibility R,
                               ThreadSafeModule TSM) {
 
   assert(TSM && "Speculation Layer received Null Module ?");
@@ -127,7 +127,7 @@ void IRSpeculationLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
           assert(Mutator.GetInsertBlock()->getParent() == &Fn &&
                  "IR builder association mismatch?");
           S.registerSymbols(internToJITSymbols(IRNames.getValue()),
-                            &R->getTargetJITDylib());
+                            &R.getTargetJITDylib());
         }
       }
     }

diff  --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
index 9a1dbbb17251..2c008dfdbd33 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
@@ -35,12 +35,12 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
     OnCompletionRun = true;
   };
 
-  std::unique_ptr<MaterializationResponsibility> FooMR;
+  std::shared_ptr<MaterializationResponsibility> FooMR;
 
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooMR = std::move(R);
+      [&](MaterializationResponsibility R) {
+        FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
       })));
 
   ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
@@ -99,9 +99,9 @@ TEST_F(CoreAPIsStandardTest, ResolveUnrequestedSymbol) {
 
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [this](std::unique_ptr<MaterializationResponsibility> R) {
-        cantFail(R->notifyResolved({{Foo, FooSym}, {Bar, BarSym}}));
-        cantFail(R->notifyEmitted());
+      [this](MaterializationResponsibility R) {
+        cantFail(R.notifyResolved({{Foo, FooSym}, {Bar, BarSym}}));
+        cantFail(R.notifyEmitted());
       })));
 
   auto Result =
@@ -116,16 +116,14 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyBasic) {
   // don't return until they're emitted, and that they don't appear in query
   // results.
 
-  std::unique_ptr<MaterializationResponsibility> FooR;
+  Optional<MaterializationResponsibility> FooR;
   Optional<SymbolMap> Result;
 
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap(
           {{Foo, JITSymbolFlags::Exported |
                      JITSymbolFlags::MaterializationSideEffectsOnly}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
-      })));
+      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); })));
 
   ES.lookup(
       LookupKind::Static, makeJITDylibSearchOrder(&JD),
@@ -157,9 +155,7 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffectsOnlyFailuresPersist) {
       SymbolFlagsMap(
           {{Foo, JITSymbolFlags::Exported |
                      JITSymbolFlags::MaterializationSideEffectsOnly}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        R->failMaterialization();
-      })));
+      [&](MaterializationResponsibility R) { R.failMaterialization(); })));
 
   EXPECT_THAT_EXPECTED(
       ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})),
@@ -186,10 +182,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
   bool BarMaterializerDestructed = false;
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [this](std::unique_ptr<MaterializationResponsibility> R) {
+      [this](MaterializationResponsibility R) {
         ADD_FAILURE() << "Unexpected materialization of \"Bar\"";
-        cantFail(R->notifyResolved({{Bar, BarSym}}));
-        cantFail(R->notifyEmitted());
+        cantFail(R.notifyResolved({{Bar, BarSym}}));
+        cantFail(R.notifyEmitted());
       },
       nullptr,
       [&](const JITDylib &JD, const SymbolStringPtr &Name) {
@@ -201,12 +197,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
 
   // Baz will be in the materializing state initially, then
   // materialized for the final removal attempt.
-  std::unique_ptr<MaterializationResponsibility> BazR;
+  Optional<MaterializationResponsibility> BazR;
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Baz, BazSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        BazR = std::move(R);
-      },
+      [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); },
       nullptr,
       [](const JITDylib &JD, const SymbolStringPtr &Name) {
         ADD_FAILURE() << "\"Baz\" discarded unexpectedly";
@@ -303,7 +297,7 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) {
       JITSymbolFlags::Exported | JITSymbolFlags::Weak));
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [](std::unique_ptr<MaterializationResponsibility> R) {
+      [](MaterializationResponsibility R) {
         llvm_unreachable("Symbol materialized on flags lookup");
       });
 
@@ -406,10 +400,10 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {
   bool BarMaterialized = false;
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
+      [&](MaterializationResponsibility R) {
         BarMaterialized = true;
-        cantFail(R->notifyResolved({{Bar, BarSym}}));
-        cantFail(R->notifyEmitted());
+        cantFail(R.notifyResolved({{Bar, BarSym}}));
+        cantFail(R.notifyEmitted());
       });
 
   cantFail(JD.define(BarMU));
@@ -450,12 +444,10 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) {
 }
 
 TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
-  std::unique_ptr<MaterializationResponsibility> FooR;
+  Optional<MaterializationResponsibility> FooR;
   auto FooMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
 
   cantFail(JD.define(FooMU));
 
@@ -484,29 +476,26 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
   // does not prevent any symbol from becoming 'ready' once all symbols are
   // emitted.
 
-  std::unique_ptr<MaterializationResponsibility> FooR;
-  std::unique_ptr<MaterializationResponsibility> BarR;
-  std::unique_ptr<MaterializationResponsibility> BazR;
+  // Create three MaterializationResponsibility objects: one for each of Foo,
+  // Bar and Baz. These are optional because MaterializationResponsibility
+  // does not have a default constructor).
+  Optional<MaterializationResponsibility> FooR;
+  Optional<MaterializationResponsibility> BarR;
+  Optional<MaterializationResponsibility> BazR;
 
   // Create a MaterializationUnit for each symbol that moves the
   // MaterializationResponsibility into one of the locals above.
   auto FooMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        BarR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
 
   auto BazMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Baz, BazSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        BazR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -633,22 +622,18 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
 }
 
 TEST_F(CoreAPIsStandardTest, FailureInDependency) {
-  std::unique_ptr<MaterializationResponsibility> FooR;
-  std::unique_ptr<MaterializationResponsibility> BarR;
+  Optional<MaterializationResponsibility> FooR;
+  Optional<MaterializationResponsibility> BarR;
 
   // Create a MaterializationUnit for each symbol that moves the
   // MaterializationResponsibility into one of the locals above.
   auto FooMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        BarR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -702,22 +687,18 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) {
 }
 
 TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
-  std::unique_ptr<MaterializationResponsibility> FooR;
-  std::unique_ptr<MaterializationResponsibility> BarR;
+  Optional<MaterializationResponsibility> FooR;
+  Optional<MaterializationResponsibility> BarR;
 
   // Create a MaterializationUnit for each symbol that moves the
   // MaterializationResponsibility into one of the locals above.
   auto FooMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        BarR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -772,22 +753,18 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
 }
 
 TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
-  std::unique_ptr<MaterializationResponsibility> FooR;
-  std::unique_ptr<MaterializationResponsibility> BarR;
+  Optional<MaterializationResponsibility> FooR;
+  Optional<MaterializationResponsibility> BarR;
 
   // Create a MaterializationUnit for each symbol that moves the
   // MaterializationResponsibility into one of the locals above.
   auto FooMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        BarR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -842,22 +819,18 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
 }
 
 TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) {
-  std::unique_ptr<MaterializationResponsibility> FooR;
-  std::unique_ptr<MaterializationResponsibility> BarR;
+  Optional<MaterializationResponsibility> FooR;
+  Optional<MaterializationResponsibility> BarR;
 
   // Create a MaterializationUnit for each symbol that moves the
   // MaterializationResponsibility into one of the locals above.
   auto FooMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        BarR = std::move(R);
-      });
+      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -909,9 +882,9 @@ TEST_F(CoreAPIsStandardTest, FailMaterializerWithUnqueriedSymbols) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap(
           {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
+      [&](MaterializationResponsibility R) {
         MaterializerRun = true;
-        R->failMaterialization();
+        R.failMaterialization();
       });
 
   cantFail(JD.define(std::move(MU)));
@@ -938,7 +911,7 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, WeakExported}, {Bar, WeakExported}}),
-      [](std::unique_ptr<MaterializationResponsibility> R) {
+      [](MaterializationResponsibility R) {
         llvm_unreachable("Unexpected call to materialize");
       },
       nullptr,
@@ -970,10 +943,10 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
+      [&](MaterializationResponsibility R) {
         assert(BarDiscarded && "Bar should have been discarded by this point");
-        cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}})));
-        cantFail(R->notifyEmitted());
+        cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}})));
+        cantFail(R.notifyEmitted());
         FooMaterialized = true;
       },
       nullptr,
@@ -1012,18 +985,18 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
   bool BarMaterialized = false;
   auto MU1 = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
-        cantFail(R->notifyEmitted());
+      [&](MaterializationResponsibility R) {
+        cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
+        cantFail(R.notifyEmitted());
         BarMaterialized = true;
       });
 
   bool DuplicateBarDiscarded = false;
   auto MU2 = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
+      [&](MaterializationResponsibility R) {
         ADD_FAILURE() << "Attempt to materialize Bar from the wrong unit";
-        R->failMaterialization();
+        R.failMaterialization();
       },
       nullptr,
       [&](const JITDylib &JD, SymbolStringPtr Name) {
@@ -1053,21 +1026,20 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
 
 TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
   bool ExpectNoMoreMaterialization = false;
-  ES.setDispatchMaterialization(
-      [&](std::unique_ptr<MaterializationUnit> MU,
-          std::unique_ptr<MaterializationResponsibility> MR) {
-        if (ExpectNoMoreMaterialization)
-          ADD_FAILURE() << "Unexpected materialization";
-        MU->materialize(std::move(MR));
-      });
+  ES.setDispatchMaterialization([&](std::unique_ptr<MaterializationUnit> MU,
+                                    MaterializationResponsibility MR) {
+    if (ExpectNoMoreMaterialization)
+      ADD_FAILURE() << "Unexpected materialization";
+    MU->materialize(std::move(MR));
+  });
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
+      [&](MaterializationResponsibility R) {
         cantFail(
-            R->defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}})));
-        cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
-        cantFail(R->notifyEmitted());
+            R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}})));
+        cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
+        cantFail(R.notifyEmitted());
       });
 
   cantFail(JD.define(MU));
@@ -1121,8 +1093,8 @@ TEST_F(CoreAPIsStandardTest, FailResolution) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak},
                       {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        R->failMaterialization();
+      [&](MaterializationResponsibility R) {
+        R.failMaterialization();
       });
 
   cantFail(JD.define(MU));
@@ -1157,23 +1129,23 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
+      [&](MaterializationResponsibility R) {
+        cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
 
         ES.lookup(
             LookupKind::Static, makeJITDylibSearchOrder(&JD),
             SymbolLookupSet({Baz}), SymbolState::Resolved,
-            [&](Expected<SymbolMap> Result) {
+            [&R](Expected<SymbolMap> Result) {
               // Called when "baz" is resolved. We don't actually depend
               // on or care about baz, but use it to trigger failure of
               // this materialization before Baz has been finalized in
               // order to test that error propagation is correct in this
               // scenario.
               cantFail(std::move(Result));
-              R->failMaterialization();
+              R.failMaterialization();
             },
             [&](const SymbolDependenceMap &Deps) {
-              R->addDependenciesForAll(Deps);
+              R.addDependenciesForAll(Deps);
             });
       });
 
@@ -1193,9 +1165,7 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) {
   // Fail materialization of bar.
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        R->failMaterialization();
-      });
+      [&](MaterializationResponsibility R) { R.failMaterialization(); });
 
   cantFail(JD.define(std::move(BarMU)));
 
@@ -1215,9 +1185,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) {
 TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        cantFail(R->notifyResolved({{Foo, FooSym}}));
-        cantFail(R->notifyEmitted());
+      [&](MaterializationResponsibility R) {
+        cantFail(R.notifyResolved({{Foo, FooSym}}));
+        cantFail(R.notifyEmitted());
       });
 
   cantFail(JD.define(MU));
@@ -1234,14 +1204,15 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
 #if LLVM_ENABLE_THREADS
 
   std::thread MaterializationThread;
-  ES.setDispatchMaterialization(
-      [&](std::unique_ptr<MaterializationUnit> MU,
-          std::unique_ptr<MaterializationResponsibility> MR) {
-        MaterializationThread =
-            std::thread([MU = std::move(MU), MR = std::move(MR)]() mutable {
-              MU->materialize(std::move(MR));
-            });
-      });
+  ES.setDispatchMaterialization([&](std::unique_ptr<MaterializationUnit> MU,
+                                    MaterializationResponsibility MR) {
+    auto SharedMR =
+        std::make_shared<MaterializationResponsibility>(std::move(MR));
+    MaterializationThread =
+        std::thread([MU = std::move(MU), MR = std::move(SharedMR)] {
+          MU->materialize(std::move(*MR));
+        });
+  });
 
   cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
 
@@ -1267,23 +1238,23 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        auto Requested = R->getRequestedSymbols();
+      [&](MaterializationResponsibility R) {
+        auto Requested = R.getRequestedSymbols();
         EXPECT_EQ(Requested.size(), 1U) << "Expected one symbol requested";
         EXPECT_EQ(*Requested.begin(), Foo) << "Expected \"Foo\" requested";
 
         auto NewMU = std::make_unique<SimpleMaterializationUnit>(
             SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-            [&](std::unique_ptr<MaterializationResponsibility> R2) {
-              cantFail(R2->notifyResolved(SymbolMap({{Bar, BarSym}})));
-              cantFail(R2->notifyEmitted());
+            [&](MaterializationResponsibility R2) {
+              cantFail(R2.notifyResolved(SymbolMap({{Bar, BarSym}})));
+              cantFail(R2.notifyEmitted());
               BarMaterialized = true;
             });
 
-        R->replace(std::move(NewMU));
+        R.replace(std::move(NewMU));
 
-        cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}})));
-        cantFail(R->notifyEmitted());
+        cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}})));
+        cantFail(R.notifyEmitted());
 
         FooMaterialized = true;
       });
@@ -1309,13 +1280,13 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
 TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        auto R2 = R->delegate({Bar});
+      [&](MaterializationResponsibility R) {
+        auto R2 = R.delegate({Bar});
 
-        cantFail(R->notifyResolved({{Foo, FooSym}}));
-        cantFail(R->notifyEmitted());
-        cantFail(R2->notifyResolved({{Bar, BarSym}}));
-        cantFail(R2->notifyEmitted());
+        cantFail(R.notifyResolved({{Foo, FooSym}}));
+        cantFail(R.notifyEmitted());
+        cantFail(R2.notifyResolved({{Bar, BarSym}}));
+        cantFail(R2.notifyEmitted());
       });
 
   cantFail(JD.define(MU));
@@ -1338,11 +1309,12 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
   JITSymbolFlags WeakExported = JITSymbolFlags::Exported;
   WeakExported &= JITSymbolFlags::Weak;
 
-  std::unique_ptr<MaterializationResponsibility> FooR;
+  std::unique_ptr<MaterializationResponsibility> FooResponsibility;
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
-        FooR = std::move(R);
+      [&](MaterializationResponsibility R) {
+        FooResponsibility =
+            std::make_unique<MaterializationResponsibility>(std::move(R));
       });
 
   cantFail(JD.define(MU));
@@ -1356,7 +1328,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
 
   auto MU2 = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
-      [](std::unique_ptr<MaterializationResponsibility> R) {
+      [](MaterializationResponsibility R) {
         llvm_unreachable("This unit should never be materialized");
       });
 
@@ -1367,8 +1339,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
   consumeError(std::move(Err));
 
   // No dependencies registered, can't fail:
-  cantFail(FooR->notifyResolved(SymbolMap({{Foo, FooSym}})));
-  cantFail(FooR->notifyEmitted());
+  cantFail(FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}})));
+  cantFail(FooResponsibility->notifyEmitted());
 }
 
 static bool linkOrdersEqual(const std::vector<std::shared_ptr<JITDylib>> &LHS,

diff  --git a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
index 81ff3e7a87b3..50e7b60a2df4 100644
--- a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
@@ -39,15 +39,15 @@ TEST_F(LazyReexportsTest, BasicLocalCallThroughManagerOperation) {
 
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}),
-      [&](std::unique_ptr<MaterializationResponsibility> R) {
+      [&](MaterializationResponsibility R) {
         DummyTargetMaterialized = true;
         // No dependencies registered, can't fail.
-        cantFail(R->notifyResolved(
+        cantFail(R.notifyResolved(
             {{DummyTarget,
               JITEvaluatedSymbol(static_cast<JITTargetAddress>(
                                      reinterpret_cast<uintptr_t>(&dummyTarget)),
                                  JITSymbolFlags::Exported)}}));
-        cantFail(R->notifyEmitted());
+        cantFail(R.notifyEmitted());
       })));
 
   unsigned NotifyResolvedCount = 0;

diff  --git a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
index afbc4a9ffaa5..b25851d8f796 100644
--- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
+++ b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -86,7 +86,7 @@ class OrcNativeTarget {
 class SimpleMaterializationUnit : public orc::MaterializationUnit {
 public:
   using MaterializeFunction =
-      std::function<void(std::unique_ptr<orc::MaterializationResponsibility>)>;
+      std::function<void(orc::MaterializationResponsibility)>;
   using DiscardFunction =
       std::function<void(const orc::JITDylib &, orc::SymbolStringPtr)>;
   using DestructorFunction = std::function<void()>;
@@ -108,8 +108,7 @@ class SimpleMaterializationUnit : public orc::MaterializationUnit {
 
   StringRef getName() const override { return "<Simple>"; }
 
-  void
-  materialize(std::unique_ptr<orc::MaterializationResponsibility> R) override {
+  void materialize(orc::MaterializationResponsibility R) override {
     Materialize(std::move(R));
   }
 


        


More information about the llvm-commits mailing list