[Orc] Rename IndirectStubsManagerBase to IndirectStubsManager.
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / LazyEmittingLayer.h
index ebc28595f5899ae9a0e043bd1155263ce965a2e9..a5286ff9adde68fc46a502daf94fea5a6c1ccd79 100644 (file)
 #define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
 
 #include "JITSymbol.h"
-#include "LookasideRTDyldMM.h"
 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/Mangler.h"
+#include "llvm/IR/Module.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
 #include <list>
 
 namespace llvm {
+namespace orc {
 
 /// @brief Lazy-emitting IR layer.
 ///
@@ -42,26 +45,32 @@ private:
     JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
       switch (EmitState) {
       case NotEmitted:
-        if (provides(Name, ExportedSymbolsOnly))
-          return JITSymbol(
-              [this,ExportedSymbolsOnly,Name,&B]() -> TargetAddress {
-                if (this->EmitState == Emitting)
-                  return 0;
-                else if (this->EmitState != Emitted) {
-                  this->EmitState = Emitting;
-                  Handle = this->emit(B);
-                  this->EmitState = Emitted;
-                }
-                return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly)
-                          .getAddress();
-              });
-        else
+        if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
+          // Create a std::string version of Name to capture here - the argument
+          // (a StringRef) may go away before the lambda is executed.
+          // FIXME: Use capture-init when we move to C++14.
+          std::string PName = Name;
+          JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV);
+          auto GetAddress =
+            [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
+              if (this->EmitState == Emitting)
+                return 0;
+              else if (this->EmitState == NotEmitted) {
+                this->EmitState = Emitting;
+                Handle = this->emitToBaseLayer(B);
+                this->EmitState = Emitted;
+              }
+              auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
+              return Sym.getAddress();
+          };
+          return JITSymbol(std::move(GetAddress), Flags);
+        } else
           return nullptr;
       case Emitting:
-        // Calling "emit" can trigger external symbol lookup (e.g. to check for
-        // pre-existing definitions of common-symbol), but it will never find in
-        // this module that it would not have found already, so return null from
-        // here.
+        // Calling "emit" can trigger a recursive call to 'find' (e.g. to check
+        // for pre-existing definitions of common-symbol), but any symbol in
+        // this module would already have been found internally (in the
+        // RuntimeDyld that did the lookup), so just return a nullptr here.
         return nullptr;
       case Emitted:
         return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
@@ -74,68 +83,88 @@ private:
         BaseLayer.removeModuleSet(Handle);
     }
 
-    template <typename ModuleSetT>
+    void emitAndFinalize(BaseLayerT &BaseLayer) {
+      assert(EmitState != Emitting &&
+             "Cannot emitAndFinalize while already emitting");
+      if (EmitState == NotEmitted) {
+        EmitState = Emitting;
+        Handle = emitToBaseLayer(BaseLayer);
+        EmitState = Emitted;
+      }
+      BaseLayer.emitAndFinalize(Handle);
+    }
+
+    template <typename ModuleSetT, typename MemoryManagerPtrT,
+              typename SymbolResolverPtrT>
     static std::unique_ptr<EmissionDeferredSet>
-    create(BaseLayerT &B, ModuleSetT Ms,
-           std::unique_ptr<RTDyldMemoryManager> MM);
+    create(BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
+           SymbolResolverPtrT Resolver);
 
   protected:
-    virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
-    virtual BaseLayerHandleT emit(BaseLayerT &BaseLayer) = 0;
+    virtual const GlobalValue* searchGVs(StringRef Name,
+                                         bool ExportedSymbolsOnly) const = 0;
+    virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
 
   private:
     enum { NotEmitted, Emitting, Emitted } EmitState;
     BaseLayerHandleT Handle;
   };
 
-  template <typename ModuleSetT>
+  template <typename ModuleSetT, typename MemoryManagerPtrT,
+            typename SymbolResolverPtrT>
   class EmissionDeferredSetImpl : public EmissionDeferredSet {
   public:
     EmissionDeferredSetImpl(ModuleSetT Ms,
-                            std::unique_ptr<RTDyldMemoryManager> MM)
-        : Ms(std::move(Ms)), MM(std::move(MM)) {}
+                            MemoryManagerPtrT MemMgr,
+                            SymbolResolverPtrT Resolver)
+        : Ms(std::move(Ms)), MemMgr(std::move(MemMgr)),
+          Resolver(std::move(Resolver)) {}
 
   protected:
-    BaseLayerHandleT emit(BaseLayerT &BaseLayer) override {
-      // We don't need the mangled names set any more: Once we've emitted this
-      // to the base layer we'll just look for symbols there.
-      MangledNames.reset();
-      return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
-    }
 
-    bool provides(StringRef Name, bool ExportedSymbolsOnly) const override {
+    const GlobalValue* searchGVs(StringRef Name,
+                                 bool ExportedSymbolsOnly) const override {
       // FIXME: We could clean all this up if we had a way to reliably demangle
       //        names: We could just demangle name and search, rather than
       //        mangling everything else.
 
       // If we have already built the mangled name set then just search it.
-      if (MangledNames) {
-        auto VI = MangledNames->find(Name);
-        if (VI == MangledNames->end())
-          return false;
-        return !ExportedSymbolsOnly || VI->second;
+      if (MangledSymbols) {
+        auto VI = MangledSymbols->find(Name);
+        if (VI == MangledSymbols->end())
+          return nullptr;
+        auto GV = VI->second;
+        if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
+          return GV;
+        return nullptr;
       }
 
       // If we haven't built the mangled name set yet, try to build it. As an
       // optimization this will leave MangledNames set to nullptr if we find
       // Name in the process of building the set.
-      buildMangledNames(Name, ExportedSymbolsOnly);
-      if (!MangledNames)
-        return true;
-      return false;
+      return buildMangledSymbols(Name, ExportedSymbolsOnly);
+    }
+
+    BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
+      // We don't need the mangled names set any more: Once we've emitted this
+      // to the base layer we'll just look for symbols there.
+      MangledSymbols.reset();
+      return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
+                                    std::move(Resolver));
     }
 
   private:
     // If the mangled name of the given GlobalValue matches the given search
     // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
-    // just return 'true'. Otherwise, add the mangled name to the Names map and
-    // return 'false'.
-    bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV,
-                        const Mangler &Mang, StringRef SearchName,
-                        bool ExportedSymbolsOnly) const {
+    // return the symbol. Otherwise, add the mangled name to the Names map and
+    // return nullptr.
+    const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
+                                      const GlobalValue &GV,
+                                      const Mangler &Mang, StringRef SearchName,
+                                      bool ExportedSymbolsOnly) const {
       // Modules don't "provide" decls or common symbols.
       if (GV.isDeclaration() || GV.hasCommonLinkage())
-        return false;
+        return nullptr;
 
       // Mangle the GV name.
       std::string MangledName;
@@ -148,39 +177,43 @@ private:
       // bail out early.
       if (MangledName == SearchName)
         if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
-          return true;
+          return &GV;
 
       // Otherwise add this to the map for later.
-      Names[MangledName] = GV.hasDefaultVisibility();
-      return false;
+      Names[MangledName] = &GV;
+      return nullptr;
     }
 
-    // Build the MangledNames map. Bails out early (with MangledNames left set
+    // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
     // to nullptr) if the given SearchName is found while building the map.
-    void buildMangledNames(StringRef SearchName,
-                           bool ExportedSymbolsOnly) const {
-      assert(!MangledNames && "Mangled names map already exists?");
+    const GlobalValue* buildMangledSymbols(StringRef SearchName,
+                                           bool ExportedSymbolsOnly) const {
+      assert(!MangledSymbols && "Mangled symbols map already exists?");
 
-      auto Names = llvm::make_unique<StringMap<bool>>();
+      auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
 
       for (const auto &M : Ms) {
-        Mangler Mang(M->getDataLayout());
+        Mangler Mang;
 
-        for (const auto &GV : M->globals())
-          if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly))
-            return;
+        for (const auto &V : M->globals())
+          if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName,
+                                       ExportedSymbolsOnly))
+            return GV;
 
         for (const auto &F : *M)
-          if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly))
-            return;
+          if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName,
+                                       ExportedSymbolsOnly))
+            return GV;
       }
 
-      MangledNames = std::move(Names);
+      MangledSymbols = std::move(Symbols);
+      return nullptr;
     }
 
     ModuleSetT Ms;
-    std::unique_ptr<RTDyldMemoryManager> MM;
-    mutable std::unique_ptr<StringMap<bool>> MangledNames;
+    MemoryManagerPtrT MemMgr;
+    SymbolResolverPtrT Resolver;
+    mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
   };
 
   typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
@@ -196,12 +229,15 @@ public:
   LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
 
   /// @brief Add the given set of modules to the lazy emitting layer.
-  template <typename ModuleSetT>
+  template <typename ModuleSetT, typename MemoryManagerPtrT,
+            typename SymbolResolverPtrT>
   ModuleSetHandleT addModuleSet(ModuleSetT Ms,
-                                std::unique_ptr<RTDyldMemoryManager> MM) {
+                                MemoryManagerPtrT MemMgr,
+                                SymbolResolverPtrT Resolver) {
     return ModuleSetList.insert(
         ModuleSetList.end(),
-        EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MM)));
+        EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MemMgr),
+                                    std::move(Resolver)));
   }
 
   /// @brief Remove the module set represented by the given handle.
@@ -239,16 +275,30 @@ public:
                          bool ExportedSymbolsOnly) {
     return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
   }
+
+  /// @brief Immediately emit and finalize the moduleOB set represented by the
+  ///        given handle.
+  /// @param H Handle for module set to emit/finalize.
+  void emitAndFinalize(ModuleSetHandleT H) {
+    (*H)->emitAndFinalize(BaseLayer);
+  }
+
 };
 
 template <typename BaseLayerT>
-template <typename ModuleSetT>
+template <typename ModuleSetT, typename MemoryManagerPtrT,
+          typename SymbolResolverPtrT>
 std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet>
 LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create(
-    BaseLayerT &B, ModuleSetT Ms, std::unique_ptr<RTDyldMemoryManager> MM) {
-  return llvm::make_unique<EmissionDeferredSetImpl<ModuleSetT>>(std::move(Ms),
-                                                                std::move(MM));
-}
+    BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
+    SymbolResolverPtrT Resolver) {
+  typedef EmissionDeferredSetImpl<ModuleSetT, MemoryManagerPtrT, SymbolResolverPtrT>
+    EDS;
+  return llvm::make_unique<EDS>(std::move(Ms), std::move(MemMgr),
+                                std::move(Resolver));
 }
 
+} // End namespace orc.
+} // End namespace llvm.
+
 #endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H