[llvm] 7dcd004 - Re-apply "[ORC] Make MaterializationResponsibility immovable..." with fixes.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 14:09:24 PDT 2020


Author: Lang Hames
Date: 2020-09-11T14:09:05-07:00
New Revision: 7dcd0042e8b8581751bd9b915207058d2ab88e1d

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

LOG: Re-apply "[ORC] Make MaterializationResponsibility immovable..." with fixes.

Re-applies c74900ca672 with fixes for the ThinLtoJIT example.

Added: 
    

Modified: 
    llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp
    llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp
    llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h
    llvm/examples/ThinLtoJIT/ThinLtoJIT.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 4de4897053c1..24cf0847558f 100644
--- a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp
+++ b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp
@@ -113,14 +113,13 @@ class SpeculativeJIT {
     this->CODLayer.setImplMap(&Imps);
     this->ES->setDispatchMaterialization(
         [this](std::unique_ptr<MaterializationUnit> MU,
-               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));
-          });
+               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));
+              });
         });
     ExitOnErr(S.addSpeculationRuntime(MainJD, Mangle));
     LocalCXXRuntimeOverrides CXXRuntimeoverrides;

diff  --git a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp
index 345bfd8dd870..df844bf19b9c 100644
--- a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp
+++ b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp
@@ -120,8 +120,8 @@ void ThinLtoInstrumentationLayer::nudgeIntoDiscovery(
   LLVM_DEBUG(dbgs() << "Nudged " << Count << " new functions into discovery\n");
 }
 
-void ThinLtoInstrumentationLayer::emit(MaterializationResponsibility R,
-                                       ThreadSafeModule TSM) {
+void ThinLtoInstrumentationLayer::emit(
+    std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM) {
   TSM.withModuleDo([this](Module &M) {
     std::vector<Function *> FunctionsToInstrument;
 

diff  --git a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h
index cd8720789474..25006b40607f 100644
--- a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h
+++ b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h
@@ -34,7 +34,8 @@ class ThinLtoInstrumentationLayer : public IRLayer {
 
   ~ThinLtoInstrumentationLayer() override;
 
-  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            ThreadSafeModule TSM) override;
 
   unsigned reserveDiscoveryFlags(unsigned Count);
   void registerDiscoveryFlagOwners(std::vector<GlobalValue::GUID> Guids,

diff  --git a/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp b/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp
index f5c2b0696f55..e668be7d11b7 100644
--- a/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp
+++ b/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp
@@ -267,19 +267,18 @@ void ThinLtoJIT::setupLayers(JITTargetMachineBuilder JTMB,
       llvm::hardware_concurrency(NumCompileThreads));
   ES.setDispatchMaterialization(
       [this](std::unique_ptr<MaterializationUnit> MU,
-             MaterializationResponsibility MR) {
+             std::unique_ptr<MaterializationResponsibility> MR) {
         if (IsTrivialModule(MU.get())) {
           // This should be quick and we may save a few session locks.
           MU->materialize(std::move(MR));
         } else {
           // FIXME: Drop the std::shared_ptr workaround once ThreadPool::async()
           // accepts llvm::unique_function to define jobs.
-          auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
-          auto SharedMR =
-            std::make_shared<MaterializationResponsibility>(std::move(MR));
           CompileThreads->async(
-              [MU = std::move(SharedMU), MR = std::move(SharedMR)]() {
-                MU->materialize(std::move(*MR));
+              [UnownedMU = MU.release(), UnownedMR = MR.release()]() {
+                std::unique_ptr<MaterializationUnit> MU(UnownedMU);
+                std::unique_ptr<MaterializationResponsibility> MR(UnownedMR);
+                MU->materialize(std::move(MR));
               });
         }
       });

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 9ecc0464dec1..3a2f8b54ad22 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -96,7 +96,8 @@ 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(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            ThreadSafeModule TSM) override;
 
 private:
   struct PerDylibResources {
@@ -120,7 +121,8 @@ class CompileOnDemandLayer : public IRLayer {
 
   void expandPartition(GlobalValueSet &Partition);
 
-  void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
+  void emitPartition(std::unique_ptr<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 6951df3f2d3f..70bd983c40ce 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 &&) = default;
+  MaterializationResponsibility(MaterializationResponsibility &&) = delete;
   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.
-  MaterializationResponsibility delegate(const SymbolNameSet &Symbols,
-                                         VModuleKey NewKey = VModuleKey());
+  std::unique_ptr<MaterializationResponsibility>
+  delegate(const SymbolNameSet &Symbols, VModuleKey NewKey = VModuleKey());
 
   void addDependencies(const SymbolStringPtr &Name,
                        const SymbolDependenceMap &Dependencies);
@@ -577,7 +577,8 @@ 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(MaterializationResponsibility R) = 0;
+  virtual void
+  materialize(std::unique_ptr<MaterializationResponsibility> R) = 0;
 
   /// Called by JITDylibs to notify MaterializationUnits that the given symbol
   /// has been overridden.
@@ -594,10 +595,11 @@ class MaterializationUnit {
 private:
   virtual void anchor();
 
-  MaterializationResponsibility
+  std::unique_ptr<MaterializationResponsibility>
   createMaterializationResponsibility(std::shared_ptr<JITDylib> JD) {
-    return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
-                                         std::move(InitSymbol), K);
+    return std::unique_ptr<MaterializationResponsibility>(
+        new MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
+                                          std::move(InitSymbol), K));
   }
 
   /// Implementations of this method should discard the given symbol
@@ -621,7 +623,7 @@ class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit {
   StringRef getName() const override;
 
 private:
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolMap &Symbols);
 
@@ -663,7 +665,7 @@ class ReExportsMaterializationUnit : public MaterializationUnit {
   StringRef getName() const override;
 
 private:
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
 
@@ -1116,7 +1118,7 @@ class ExecutionSession {
   /// For dispatching MaterializationUnit::materialize calls.
   using DispatchMaterializationFunction =
       std::function<void(std::unique_ptr<MaterializationUnit> MU,
-                         MaterializationResponsibility MR)>;
+                         std::unique_ptr<MaterializationResponsibility> MR)>;
 
   /// Construct an ExecutionSession.
   ///
@@ -1268,10 +1270,11 @@ class ExecutionSession {
          SymbolState RequiredState = SymbolState::Ready);
 
   /// Materialize the given unit.
-  void dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
-                               MaterializationResponsibility MR) {
+  void
+  dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
+                          std::unique_ptr<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));
   }
 
@@ -1283,9 +1286,9 @@ class ExecutionSession {
     logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
   }
 
-  static void
-  materializeOnCurrentThread(std::unique_ptr<MaterializationUnit> MU,
-                             MaterializationResponsibility MR) {
+  static void materializeOnCurrentThread(
+      std::unique_ptr<MaterializationUnit> MU,
+      std::unique_ptr<MaterializationResponsibility> MR) {
     MU->materialize(std::move(MR));
   }
 
@@ -1309,7 +1312,7 @@ class ExecutionSession {
   //        with callbacks from asynchronous queries.
   mutable std::recursive_mutex OutstandingMUsMutex;
   std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
-                        MaterializationResponsibility>>
+                        std::unique_ptr<MaterializationResponsibility>>>
       OutstandingMUs;
 };
 

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index eb74d283f043..2c53e2f66e85 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -55,7 +55,8 @@ class IRCompileLayer : public IRLayer {
 
   void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled);
 
-  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<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 296d74ae6b86..ee4ee3437fa6 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -37,7 +37,8 @@ class IRTransformLayer : public IRLayer {
     this->Transform = std::move(Transform);
   }
 
-  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<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 e843d0f56245..c8a41199760d 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
@@ -100,7 +100,8 @@ class IRLayer {
                     VModuleKey K = VModuleKey());
 
   /// Emit should materialize the given IR.
-  virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0;
+  virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
+                    ThreadSafeModule TSM) = 0;
 
 private:
   bool CloneToNewContextOnEmit = false;
@@ -117,8 +118,7 @@ class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
                                   ThreadSafeModule TSM, VModuleKey K);
 
 private:
-
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<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(MaterializationResponsibility R,
+  virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
                     std::unique_ptr<MemoryBuffer> O) = 0;
 
 private:
@@ -162,8 +162,7 @@ class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
   StringRef getName() const override;
 
 private:
-
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<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 9206e40fffb1..63e3a80d87d8 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(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<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 cb8ee130ab61..cbcf3928be3d 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(MaterializationResponsibility R,
+  void emit(std::unique_ptr<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 bf989cc8677c..c77649f19fc7 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(MaterializationResponsibility R,
+  void emit(std::unique_ptr<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 9ada0871cf0c..9cd3c57a19c6 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(MaterializationResponsibility R,
+  void emit(std::unique_ptr<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 10f78c8bc6be..a138f60a7756 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
@@ -181,7 +181,8 @@ class IRSpeculationLayer : public IRLayer {
       : IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer),
         S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {}
 
-  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            ThreadSafeModule TSM) override;
 
 private:
   TargetAndLikelies

diff  --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
index 9e38dc36faae..dfb0d06bdba3 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(MaterializationResponsibility R) override {
+  void materialize(std::unique_ptr<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(MaterializationResponsibility R,
-                                ThreadSafeModule TSM) {
+void CompileOnDemandLayer::emit(
+    std::unique_ptr<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(MaterializationResponsibility R,
     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(MaterializationResponsibility R,
   // 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(
-    MaterializationResponsibility R, ThreadSafeModule TSM,
+    std::unique_ptr<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 18eced68f07b..243bac79c012 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));
 }
 
-MaterializationResponsibility
+std::unique_ptr<MaterializationResponsibility>
 MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
                                         VModuleKey NewKey) {
 
@@ -302,9 +302,10 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
     SymbolFlags.erase(I);
   }
 
-  return MaterializationResponsibility(JD, std::move(DelegatedFlags),
-                                       std::move(DelegatedInitSymbol),
-                                       std::move(NewKey));
+  return std::unique_ptr<MaterializationResponsibility>(
+      new MaterializationResponsibility(JD, std::move(DelegatedFlags),
+                                        std::move(DelegatedInitSymbol),
+                                        std::move(NewKey)));
 }
 
 void MaterializationResponsibility::addDependencies(
@@ -338,10 +339,10 @@ StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
 }
 
 void AbsoluteSymbolsMaterializationUnit::materialize(
-    MaterializationResponsibility R) {
+    std::unique_ptr<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,
@@ -370,16 +371,16 @@ StringRef ReExportsMaterializationUnit::getName() const {
 }
 
 void ReExportsMaterializationUnit::materialize(
-    MaterializationResponsibility R) {
+    std::unique_ptr<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) {
@@ -399,18 +400,19 @@ 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(MaterializationResponsibility R, SymbolAliasMap Aliases)
+    OnResolveInfo(std::unique_ptr<MaterializationResponsibility> R,
+                  SymbolAliasMap Aliases)
         : R(std::move(R)), Aliases(std::move(Aliases)) {}
 
-    MaterializationResponsibility R;
+    std::unique_ptr<MaterializationResponsibility> R;
     SymbolAliasMap Aliases;
   };
 
@@ -451,7 +453,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)));
   }
@@ -480,12 +482,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) {
@@ -499,19 +501,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();
       }
     };
 
@@ -2131,7 +2133,7 @@ void ExecutionSession::dump(raw_ostream &OS) {
 void ExecutionSession::runOutstandingMUs() {
   while (1) {
     Optional<std::pair<std::unique_ptr<MaterializationUnit>,
-                       MaterializationResponsibility>>
+                       std::unique_ptr<MaterializationResponsibility>>>
         JMU;
 
     {

diff  --git a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
index 023940dc8298..c6f687027972 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(MaterializationResponsibility R,
+void IRCompileLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
                           ThreadSafeModule TSM) {
   assert(TSM && "Module must not be null");
 
@@ -33,13 +33,13 @@ void IRCompileLayer::emit(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 511248f83b25..d5b11349277c 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(MaterializationResponsibility R,
+void IRTransformLayer::emit(std::unique_ptr<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 4f7f6089e68d..7d57ed5a3a04 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(MaterializationResponsibility R) override {
+  void materialize(std::unique_ptr<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 373d86d92f8d..81f500d66bc2 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -1085,15 +1085,17 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
         std::make_unique<ThreadPool>(hardware_concurrency(S.NumCompileThreads));
     ES->setDispatchMaterialization(
         [this](std::unique_ptr<MaterializationUnit> MU,
-               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));
+               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));
+              });
         });
   }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
index 0a5d5577e99e..8052e7b08a5a 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(
-    MaterializationResponsibility R) {
+    std::unique_ptr<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(
-    MaterializationResponsibility R) {
+    std::unique_ptr<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 5e604130d6ea..695f6cc9c1cb 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(
-    MaterializationResponsibility R) {
-  auto RequestedSymbols = R.getRequestedSymbols();
+    std::unique_ptr<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 d8283fa7e346..9e3245d9cc99 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -24,9 +24,10 @@ namespace orc {
 
 class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
 public:
-  ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer,
-                                   MaterializationResponsibility MR,
-                                   std::unique_ptr<MemoryBuffer> ObjBuffer)
+  ObjectLinkingLayerJITLinkContext(
+      ObjectLinkingLayer &Layer,
+      std::unique_ptr<MaterializationResponsibility> MR,
+      std::unique_ptr<MemoryBuffer> ObjBuffer)
       : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
 
   ~ObjectLinkingLayerJITLinkContext() {
@@ -44,14 +45,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();
@@ -85,8 +86,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),
@@ -115,7 +116,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;
@@ -133,7 +134,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;
@@ -141,19 +142,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
@@ -175,9 +176,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);
       }
 
@@ -187,23 +188,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();
     }
   }
 
@@ -217,7 +218,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); });
@@ -237,13 +238,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);
       }
 
@@ -253,13 +254,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.
@@ -306,7 +307,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;
 
@@ -426,12 +427,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
           SymbolDeps.erase(&SourceJD);
       }
 
-      MR.addDependencies(Name, SymbolDeps);
+      MR->addDependencies(Name, SymbolDeps);
     }
   }
 
   ObjectLinkingLayer &Layer;
-  MaterializationResponsibility MR;
+  std::unique_ptr<MaterializationResponsibility> MR;
   std::unique_ptr<MemoryBuffer> ObjBuffer;
   DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps;
   DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps;
@@ -452,7 +453,7 @@ ObjectLinkingLayer::~ObjectLinkingLayer() {
     getExecutionSession().reportError(std::move(Err));
 }
 
-void ObjectLinkingLayer::emit(MaterializationResponsibility R,
+void ObjectLinkingLayer::emit(std::unique_ptr<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 d18eb38a4142..a57662e10a79 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp
@@ -17,8 +17,9 @@ ObjectTransformLayer::ObjectTransformLayer(ExecutionSession &ES,
                                             TransformFunction Transform)
     : ObjectLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
 
-void ObjectTransformLayer::emit(MaterializationResponsibility R,
-                                std::unique_ptr<MemoryBuffer> O) {
+void ObjectTransformLayer::emit(
+    std::unique_ptr<MaterializationResponsibility> R,
+    std::unique_ptr<MemoryBuffer> O) {
   assert(O && "Module must not be null");
 
   // If there is a transform set then apply it.
@@ -26,7 +27,7 @@ void ObjectTransformLayer::emit(MaterializationResponsibility R,
     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 7888c2fcbdbd..1981039eb9f1 100644
--- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
@@ -89,23 +89,18 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() {
   }
 }
 
-void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
-                                    std::unique_ptr<MemoryBuffer> O) {
+void RTDyldObjectLinkingLayer::emit(
+    std::unique_ptr<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());
-    SharedR->failMaterialization();
+    R->failMaterialization();
     return;
   }
 
@@ -121,7 +116,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
           continue;
       } else {
         ES.reportError(SymType.takeError());
-        R.failMaterialization();
+        R->failMaterialization();
         return;
       }
 
@@ -129,7 +124,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
       if (!SymFlagsOrErr) {
         // TODO: Test this error.
         ES.reportError(SymFlagsOrErr.takeError());
-        R.failMaterialization();
+        R->failMaterialization();
         return;
       }
 
@@ -139,14 +134,14 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
           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.
@@ -157,6 +152,10 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
     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 3dd536d8253e..0b4755fe23cf 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(MaterializationResponsibility R,
+void IRSpeculationLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
                               ThreadSafeModule TSM) {
 
   assert(TSM && "Speculation Layer received Null Module ?");
@@ -127,7 +127,7 @@ void IRSpeculationLayer::emit(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 2c008dfdbd33..9a1dbbb17251 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::shared_ptr<MaterializationResponsibility> FooMR;
+  std::unique_ptr<MaterializationResponsibility> FooMR;
 
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
-        FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooMR = 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](MaterializationResponsibility R) {
-        cantFail(R.notifyResolved({{Foo, FooSym}, {Bar, BarSym}}));
-        cantFail(R.notifyEmitted());
+      [this](std::unique_ptr<MaterializationResponsibility> R) {
+        cantFail(R->notifyResolved({{Foo, FooSym}, {Bar, BarSym}}));
+        cantFail(R->notifyEmitted());
       })));
 
   auto Result =
@@ -116,14 +116,16 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyBasic) {
   // don't return until they're emitted, and that they don't appear in query
   // results.
 
-  Optional<MaterializationResponsibility> FooR;
+  std::unique_ptr<MaterializationResponsibility> FooR;
   Optional<SymbolMap> Result;
 
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap(
           {{Foo, JITSymbolFlags::Exported |
                      JITSymbolFlags::MaterializationSideEffectsOnly}}),
-      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); })));
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
+      })));
 
   ES.lookup(
       LookupKind::Static, makeJITDylibSearchOrder(&JD),
@@ -155,7 +157,9 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffectsOnlyFailuresPersist) {
       SymbolFlagsMap(
           {{Foo, JITSymbolFlags::Exported |
                      JITSymbolFlags::MaterializationSideEffectsOnly}}),
-      [&](MaterializationResponsibility R) { R.failMaterialization(); })));
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        R->failMaterialization();
+      })));
 
   EXPECT_THAT_EXPECTED(
       ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})),
@@ -182,10 +186,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
   bool BarMaterializerDestructed = false;
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [this](MaterializationResponsibility R) {
+      [this](std::unique_ptr<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) {
@@ -197,10 +201,12 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
 
   // Baz will be in the materializing state initially, then
   // materialized for the final removal attempt.
-  Optional<MaterializationResponsibility> BazR;
+  std::unique_ptr<MaterializationResponsibility> BazR;
   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Baz, BazSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); },
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        BazR = std::move(R);
+      },
       nullptr,
       [](const JITDylib &JD, const SymbolStringPtr &Name) {
         ADD_FAILURE() << "\"Baz\" discarded unexpectedly";
@@ -297,7 +303,7 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) {
       JITSymbolFlags::Exported | JITSymbolFlags::Weak));
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [](MaterializationResponsibility R) {
+      [](std::unique_ptr<MaterializationResponsibility> R) {
         llvm_unreachable("Symbol materialized on flags lookup");
       });
 
@@ -400,10 +406,10 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {
   bool BarMaterialized = false;
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
         BarMaterialized = true;
-        cantFail(R.notifyResolved({{Bar, BarSym}}));
-        cantFail(R.notifyEmitted());
+        cantFail(R->notifyResolved({{Bar, BarSym}}));
+        cantFail(R->notifyEmitted());
       });
 
   cantFail(JD.define(BarMU));
@@ -444,10 +450,12 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) {
 }
 
 TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
-  Optional<MaterializationResponsibility> FooR;
+  std::unique_ptr<MaterializationResponsibility> FooR;
   auto FooMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
+      });
 
   cantFail(JD.define(FooMU));
 
@@ -476,26 +484,29 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
   // does not prevent any symbol from becoming 'ready' once all symbols are
   // emitted.
 
-  // 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;
+  std::unique_ptr<MaterializationResponsibility> FooR;
+  std::unique_ptr<MaterializationResponsibility> BarR;
+  std::unique_ptr<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()}}),
-      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
+      });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        BarR = std::move(R);
+      });
 
   auto BazMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Baz, BazSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        BazR = std::move(R);
+      });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -622,18 +633,22 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
 }
 
 TEST_F(CoreAPIsStandardTest, FailureInDependency) {
-  Optional<MaterializationResponsibility> FooR;
-  Optional<MaterializationResponsibility> BarR;
+  std::unique_ptr<MaterializationResponsibility> FooR;
+  std::unique_ptr<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()}}),
-      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
+      });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        BarR = std::move(R);
+      });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -687,18 +702,22 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) {
 }
 
 TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
-  Optional<MaterializationResponsibility> FooR;
-  Optional<MaterializationResponsibility> BarR;
+  std::unique_ptr<MaterializationResponsibility> FooR;
+  std::unique_ptr<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()}}),
-      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
+      });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        BarR = std::move(R);
+      });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -753,18 +772,22 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
 }
 
 TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
-  Optional<MaterializationResponsibility> FooR;
-  Optional<MaterializationResponsibility> BarR;
+  std::unique_ptr<MaterializationResponsibility> FooR;
+  std::unique_ptr<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()}}),
-      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
+      });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        BarR = std::move(R);
+      });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -819,18 +842,22 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
 }
 
 TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) {
-  Optional<MaterializationResponsibility> FooR;
-  Optional<MaterializationResponsibility> BarR;
+  std::unique_ptr<MaterializationResponsibility> FooR;
+  std::unique_ptr<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()}}),
-      [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
+      });
 
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        BarR = std::move(R);
+      });
 
   // Define the symbols.
   cantFail(JD.define(FooMU));
@@ -882,9 +909,9 @@ TEST_F(CoreAPIsStandardTest, FailMaterializerWithUnqueriedSymbols) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap(
           {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}),
-      [&](MaterializationResponsibility R) {
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
         MaterializerRun = true;
-        R.failMaterialization();
+        R->failMaterialization();
       });
 
   cantFail(JD.define(std::move(MU)));
@@ -911,7 +938,7 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, WeakExported}, {Bar, WeakExported}}),
-      [](MaterializationResponsibility R) {
+      [](std::unique_ptr<MaterializationResponsibility> R) {
         llvm_unreachable("Unexpected call to materialize");
       },
       nullptr,
@@ -943,10 +970,10 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}),
-      [&](MaterializationResponsibility R) {
+      [&](std::unique_ptr<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,
@@ -985,18 +1012,18 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
   bool BarMaterialized = false;
   auto MU1 = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
-        cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
-        cantFail(R.notifyEmitted());
+      [&](std::unique_ptr<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()}}),
-      [&](MaterializationResponsibility R) {
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
         ADD_FAILURE() << "Attempt to materialize Bar from the wrong unit";
-        R.failMaterialization();
+        R->failMaterialization();
       },
       nullptr,
       [&](const JITDylib &JD, SymbolStringPtr Name) {
@@ -1026,20 +1053,21 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
 
 TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
   bool ExpectNoMoreMaterialization = false;
-  ES.setDispatchMaterialization([&](std::unique_ptr<MaterializationUnit> MU,
-                                    MaterializationResponsibility MR) {
-    if (ExpectNoMoreMaterialization)
-      ADD_FAILURE() << "Unexpected materialization";
-    MU->materialize(std::move(MR));
-  });
+  ES.setDispatchMaterialization(
+      [&](std::unique_ptr<MaterializationUnit> MU,
+          std::unique_ptr<MaterializationResponsibility> MR) {
+        if (ExpectNoMoreMaterialization)
+          ADD_FAILURE() << "Unexpected materialization";
+        MU->materialize(std::move(MR));
+      });
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
+      [&](std::unique_ptr<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));
@@ -1093,8 +1121,8 @@ TEST_F(CoreAPIsStandardTest, FailResolution) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak},
                       {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}),
-      [&](MaterializationResponsibility R) {
-        R.failMaterialization();
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        R->failMaterialization();
       });
 
   cantFail(JD.define(MU));
@@ -1129,23 +1157,23 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
-        cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
 
         ES.lookup(
             LookupKind::Static, makeJITDylibSearchOrder(&JD),
             SymbolLookupSet({Baz}), SymbolState::Resolved,
-            [&R](Expected<SymbolMap> Result) {
+            [&](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);
             });
       });
 
@@ -1165,7 +1193,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) {
   // Fail materialization of bar.
   auto BarMU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) { R.failMaterialization(); });
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        R->failMaterialization();
+      });
 
   cantFail(JD.define(std::move(BarMU)));
 
@@ -1185,9 +1215,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) {
 TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
-      [&](MaterializationResponsibility R) {
-        cantFail(R.notifyResolved({{Foo, FooSym}}));
-        cantFail(R.notifyEmitted());
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        cantFail(R->notifyResolved({{Foo, FooSym}}));
+        cantFail(R->notifyEmitted());
       });
 
   cantFail(JD.define(MU));
@@ -1204,15 +1234,14 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
 #if LLVM_ENABLE_THREADS
 
   std::thread MaterializationThread;
-  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));
-        });
-  });
+  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));
+            });
+      });
 
   cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
 
@@ -1238,23 +1267,23 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
 
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
-        auto Requested = R.getRequestedSymbols();
+      [&](std::unique_ptr<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()}}),
-            [&](MaterializationResponsibility R2) {
-              cantFail(R2.notifyResolved(SymbolMap({{Bar, BarSym}})));
-              cantFail(R2.notifyEmitted());
+            [&](std::unique_ptr<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;
       });
@@ -1280,13 +1309,13 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
 TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) {
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
-        auto R2 = R.delegate({Bar});
+      [&](std::unique_ptr<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));
@@ -1309,12 +1338,11 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
   JITSymbolFlags WeakExported = JITSymbolFlags::Exported;
   WeakExported &= JITSymbolFlags::Weak;
 
-  std::unique_ptr<MaterializationResponsibility> FooResponsibility;
+  std::unique_ptr<MaterializationResponsibility> FooR;
   auto MU = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
-      [&](MaterializationResponsibility R) {
-        FooResponsibility =
-            std::make_unique<MaterializationResponsibility>(std::move(R));
+      [&](std::unique_ptr<MaterializationResponsibility> R) {
+        FooR = std::move(R);
       });
 
   cantFail(JD.define(MU));
@@ -1328,7 +1356,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
 
   auto MU2 = std::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
-      [](MaterializationResponsibility R) {
+      [](std::unique_ptr<MaterializationResponsibility> R) {
         llvm_unreachable("This unit should never be materialized");
       });
 
@@ -1339,8 +1367,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
   consumeError(std::move(Err));
 
   // No dependencies registered, can't fail:
-  cantFail(FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}})));
-  cantFail(FooResponsibility->notifyEmitted());
+  cantFail(FooR->notifyResolved(SymbolMap({{Foo, FooSym}})));
+  cantFail(FooR->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 50e7b60a2df4..81ff3e7a87b3 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}}),
-      [&](MaterializationResponsibility R) {
+      [&](std::unique_ptr<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 b25851d8f796..afbc4a9ffaa5 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(orc::MaterializationResponsibility)>;
+      std::function<void(std::unique_ptr<orc::MaterializationResponsibility>)>;
   using DiscardFunction =
       std::function<void(const orc::JITDylib &, orc::SymbolStringPtr)>;
   using DestructorFunction = std::function<void()>;
@@ -108,7 +108,8 @@ class SimpleMaterializationUnit : public orc::MaterializationUnit {
 
   StringRef getName() const override { return "<Simple>"; }
 
-  void materialize(orc::MaterializationResponsibility R) override {
+  void
+  materialize(std::unique_ptr<orc::MaterializationResponsibility> R) override {
     Materialize(std::move(R));
   }
 


        


More information about the llvm-commits mailing list