[Orc][MCJIT][RuntimeDyld] Re-apply r231726 and r231724 with fix suggested by
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / LazyEmittingLayer.h
index 947222125561dcadc9ccb517b425539bf562f695..2b5db08c799241f244559c487826bb4cf979a611 100644 (file)
@@ -45,23 +45,25 @@ private:
     JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
       switch (EmitState) {
       case NotEmitted:
-        if (provides(Name, ExportedSymbolsOnly)) {
+        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;
-          return JITSymbol(
-              [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;
-                }
-                return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly)
-                          .getAddress();
-              });
+          auto 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:
@@ -98,7 +100,8 @@ private:
            std::unique_ptr<RTDyldMemoryManager> MM);
 
   protected:
-    virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
+    virtual const GlobalValue* searchGVs(StringRef Name,
+                                         bool ExportedSymbolsOnly) const = 0;
     virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
 
   private:
@@ -115,46 +118,48 @@ private:
 
   protected:
 
-    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.
-      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(MM));
     }
 
   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;
@@ -167,39 +172,42 @@ 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());
 
-        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;
+    mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
   };
 
   typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;