<div dir="ltr">Hi Dave,<div><div class="gmail_extra"><br></div><div class="gmail_extra">Thanks for the review. Some suggestions applied in r239642, comments inline below.</div><div class="gmail_extra"><br></div><div class="gmail_extra">- Lang.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 11, 2015 at 3:18 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Thu, Jun 11, 2015 at 2:45 PM, Lang Hames <span dir="ltr"><<a href="mailto:lhames@gmail.com" target="_blank">lhames@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: lhames<br>
Date: Thu Jun 11 16:45:19 2015<br>
New Revision: 239561<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D239561-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=8qYodrCL7uxJ1Y-eq4mnicwTUdh4XkphuNCTqzS7JDc&s=bl3OJrVNdD04fgO7OUvzDi3NT1oPm5nYdx1zq7S9mls&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=239561&view=rev</a><br>
Log:<br>
[Orc] Make partition identification in the CompileOnDemand layer lazy.<br>
<br>
This also breaks out the logical dylib symbol resolution logic.<br>
<br>
<br>
Added:<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/LogicalDylib.h<br>
Modified:<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>
    llvm/trunk/tools/lli/OrcLazyJIT.h<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_ExecutionEngine_Orc_CompileOnDemandLayer.h-3Frev-3D239561-26r1-3D239560-26r2-3D239561-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=8qYodrCL7uxJ1Y-eq4mnicwTUdh4XkphuNCTqzS7JDc&s=2OchJkFljq8eYPEh1CFjmO7fLe7tWjaEx4ph0OyL7oA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=239561&r1=239560&r2=239561&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h Thu Jun 11 16:45:19 2015<br>
@@ -15,9 +15,9 @@<br>
 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H<br>
 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H<br>
<br>
-//#include "CloneSubModule.h"<br>
 #include "IndirectionUtils.h"<br>
 #include "LambdaResolver.h"<br>
+#include "LogicalDylib.h"<br>
 #include "llvm/ADT/STLExtras.h"<br>
 #include "llvm/ExecutionEngine/SectionMemoryManager.h"<br>
 #include "llvm/Transforms/Utils/Cloning.h"<br>
@@ -36,7 +36,9 @@ namespace orc {<br>
 /// added to the layer below. When a stub is called it triggers the extraction<br>
 /// of the function body from the original module. The extracted body is then<br>
 /// compiled and executed.<br>
-template <typename BaseLayerT, typename CompileCallbackMgrT><br>
+template <typename BaseLayerT, typename CompileCallbackMgrT,<br>
+          typename PartitioningFtor =<br>
+            std::function<std::set<Function*>(Function&)>><br></blockquote></div></div><div><br>I can't seem to find where/why this is a template parameter - it looks like it's a private implementation detail that users of this class couldn't change even if they wanted to? (the only place it's used is for the Partitioner member of the private nested struct, and the only thing that's initialized with is a lambda of the same type in the addModuleSet function)<br><br>Are there other uses/pieces of this class I should be looking at to get the whole picture? </div></div></div></div></blockquote><div><br></div><div>I plan to expose the partitioning stuff soon, but am holding off while I consider exactly how I want the user to supply it. Passing it along with the module set to the addModuleSet method seems like the best option, but I want to keep that method's signature as uniform as possible across layers to maximize opportunities for composition.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
 class CompileOnDemandLayer {<br>
 private:<br>
<br>
@@ -58,311 +60,23 @@ private:<br>
   };<br>
<br>
   typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;<br>
-  class UncompiledPartition;<br>
<br>
-  // Logical module.<br>
-  //<br>
-  //   This struct contains the handles for the global values and stubs (which<br>
-  // cover the external symbols of the original module), plus the handes for<br>
-  // each of the extracted partitions. These handleds are used for lookup (only<br>
-  // the globals/stubs module is searched) and memory management. The actual<br>
-  // searching and resource management are handled by the LogicalDylib that owns<br>
-  // the LogicalModule.<br>
-  struct LogicalModule {<br>
-    LogicalModule() {}<br>
-<br>
-    LogicalModule(LogicalModule &&Other)<br>
-        : SrcM(std::move(Other.SrcM)),<br>
-          GVsAndStubsHandle(std::move(Other.GVsAndStubsHandle)),<br>
-          ImplHandles(std::move(Other.ImplHandles)) {}<br>
-<br>
-    std::unique_ptr<Module> SrcM;<br>
-    BaseLayerModuleSetHandleT GVsAndStubsHandle;<br>
-    std::vector<BaseLayerModuleSetHandleT> ImplHandles;<br>
+  struct LogicalModuleResources {<br>
+    std::shared_ptr<Module> SourceModule;<br>
   };<br>
<br>
-  // Logical dylib.<br>
-  //<br>
-  //   This class handles symbol resolution and resource management for a set of<br>
-  // modules that were added together as a logical dylib.<br>
-  //<br>
-  //   A logical dylib contains one-or-more LogicalModules plus a set of<br>
-  // UncompiledPartitions. LogicalModules support symbol resolution and resource<br>
-  // management for for code that has already been emitted. UncompiledPartitions<br>
-  // represent code that has not yet been compiled.<br>
-  class LogicalDylib {<br>
-  private:<br>
-    friend class UncompiledPartition;<br>
-    typedef std::list<LogicalModule> LogicalModuleList;<br>
-  public:<br>
-<br>
-    typedef unsigned UncompiledPartitionID;<br>
-    typedef typename LogicalModuleList::iterator LMHandle;<br>
-<br>
-    // Construct a logical dylib.<br>
-    LogicalDylib(CompileOnDemandLayer &CODLayer) : CODLayer(CODLayer) { }<br>
-<br>
-    // Delete this logical dylib, release logical module resources.<br>
-    virtual ~LogicalDylib() {<br>
-      releaseLogicalModuleResources();<br>
-    }<br>
-<br>
-    // Get a reference to the containing layer.<br>
-    CompileOnDemandLayer& getCODLayer() { return CODLayer; }<br>
-<br>
-    // Get a reference to the base layer.<br>
-    BaseLayerT& getBaseLayer() { return CODLayer.BaseLayer; }<br>
-<br>
-    // Start a new context for a single logical module.<br>
-    LMHandle createLogicalModule() {<br>
-      LogicalModules.push_back(LogicalModule());<br>
-      return std::prev(LogicalModules.end());<br>
-    }<br>
-<br>
-    // Set the global-values-and-stubs module handle for this logical module.<br>
-    void setGVsAndStubsHandle(LMHandle LMH, BaseLayerModuleSetHandleT H) {<br>
-      LMH->GVsAndStubsHandle = H;<br>
-    }<br>
-<br>
-    // Return the global-values-and-stubs module handle for this logical module.<br>
-    BaseLayerModuleSetHandleT getGVsAndStubsHandle(LMHandle LMH) {<br>
-      return LMH->GVsAndStubsHandle;<br>
-    }<br>
-<br>
-    //   Add a handle to a module containing lazy function bodies to the given<br>
-    // logical module.<br>
-    void addToLogicalModule(LMHandle LMH, BaseLayerModuleSetHandleT H) {<br>
-      LMH->ImplHandles.push_back(H);<br>
-    }<br>
-<br>
-    // Create an UncompiledPartition attached to this LogicalDylib.<br>
-    UncompiledPartition& createUncompiledPartition(LMHandle LMH,<br>
-                                                   std::shared_ptr<Module> SrcM);<br>
-<br>
-    // Take ownership of the given UncompiledPartition from the logical dylib.<br>
-    std::unique_ptr<UncompiledPartition><br>
-    takeUPOwnership(UncompiledPartitionID ID);<br>
-<br>
-    // Look up a symbol in this context.<br>
-    JITSymbol findSymbolInternally(LMHandle LMH, const std::string &Name) {<br>
-      if (auto Symbol = getBaseLayer().findSymbolIn(LMH->GVsAndStubsHandle,<br>
-                                                    Name, false))<br>
-        return Symbol;<br>
-<br>
-      for (auto I = LogicalModules.begin(), E = LogicalModules.end(); I != E;<br>
-           ++I)<br>
-        if (I != LMH)<br>
-          if (auto Symbol = getBaseLayer().findSymbolIn(I->GVsAndStubsHandle,<br>
-                                                        Name, false))<br>
-            return Symbol;<br>
-<br>
-      return nullptr;<br>
-    }<br>
-<br>
-    JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {<br>
-      for (auto &LM : LogicalModules)<br>
-        if (auto Symbol = getBaseLayer().findSymbolIn(LM.GVsAndStubsHandle,<br>
-                                                      Name,<br>
-                                                      ExportedSymbolsOnly))<br>
-          return Symbol;<br>
-      return nullptr;<br>
-    }<br>
-<br>
-    // Find an external symbol (via the user supplied SymbolResolver).<br>
-    virtual RuntimeDyld::SymbolInfo<br>
-    findSymbolExternally(const std::string &Name) const = 0;<br>
-<br>
-  private:<br>
-<br>
-    void releaseLogicalModuleResources() {<br>
-      for (auto I = LogicalModules.begin(), E = LogicalModules.end(); I != E;<br>
-           ++I) {<br>
-        getBaseLayer().removeModuleSet(I->GVsAndStubsHandle);<br>
-        for (auto H : I->ImplHandles)<br>
-          getBaseLayer().removeModuleSet(H);<br>
-      }<br>
-    }<br>
-<br>
-    CompileOnDemandLayer &CODLayer;<br>
-    LogicalModuleList LogicalModules;<br>
-    std::vector<std::unique_ptr<UncompiledPartition>> UncompiledPartitions;<br>
-  };<br>
-<br>
-  template <typename ResolverPtrT><br>
-  class LogicalDylibImpl : public LogicalDylib  {<br>
-  public:<br>
-    LogicalDylibImpl(CompileOnDemandLayer &CODLayer, ResolverPtrT Resolver)<br>
-      : LogicalDylib(CODLayer), Resolver(std::move(Resolver)) {}<br>
-<br>
-    RuntimeDyld::SymbolInfo<br>
-    findSymbolExternally(const std::string &Name) const override {<br>
-      return Resolver->findSymbol(Name);<br>
-    }<br>
-<br>
-  private:<br>
-    ResolverPtrT Resolver;<br>
+  struct LogicalDylibResources {<br>
+    typedef std::function<RuntimeDyld::SymbolInfo(const std::string&)><br>
+      SymbolResolverFtor;<br>
+    SymbolResolverFtor ExternalSymbolResolver;<br>
+    PartitioningFtor Partitioner;<br>
   };<br>
<br>
-  template <typename ResolverPtrT><br>
-  static std::unique_ptr<LogicalDylib><br>
-  createLogicalDylib(CompileOnDemandLayer &CODLayer,<br>
-                     ResolverPtrT Resolver) {<br>
-    typedef LogicalDylibImpl<ResolverPtrT> Impl;<br>
-    return llvm::make_unique<Impl>(CODLayer, std::move(Resolver));<br>
-  }<br>
+  typedef LogicalDylib<BaseLayerT, LogicalModuleResources,<br>
+                       LogicalDylibResources> CODLogicalDylib;<br>
<br>
-  // Uncompiled partition.<br>
-  //<br>
-  // Represents one as-yet uncompiled portion of a module.<br>
-  class UncompiledPartition {<br>
-  public:<br>
-<br>
-    struct PartitionEntry {<br>
-      PartitionEntry(Function *F, TargetAddress CallbackID)<br>
-          : F(F), CallbackID(CallbackID) {}<br>
-      Function *F;<br>
-      TargetAddress CallbackID;<br>
-    };<br>
-<br>
-    typedef std::vector<PartitionEntry> PartitionEntryList;<br>
-<br>
-    // Creates an uncompiled partition with the list of functions that make up<br>
-    // this partition.<br>
-    UncompiledPartition(LogicalDylib &LD, typename LogicalDylib::LMHandle LMH,<br>
-                        std::shared_ptr<Module> SrcM)<br>
-        : LD(LD), LMH(LMH), SrcM(std::move(SrcM)), ID(~0U) {}<br>
-<br>
-    ~UncompiledPartition() {<br>
-      // FIXME: When we want to support threaded lazy compilation we'll need to<br>
-      //        lock the callback manager here.<br>
-      auto &CCMgr = LD.getCODLayer().CompileCallbackMgr;<br>
-      for (auto PEntry : PartitionEntries)<br>
-        CCMgr.releaseCompileCallback(PEntry.CallbackID);<br>
-    }<br>
-<br>
-    // Set the ID for this partition.<br>
-    void setID(typename LogicalDylib::UncompiledPartitionID ID) {<br>
-      this->ID = ID;<br>
-    }<br>
-<br>
-    // Set the function set and callbacks for this partition.<br>
-    void setPartitionEntries(PartitionEntryList PartitionEntries) {<br>
-      this->PartitionEntries = std::move(PartitionEntries);<br>
-    }<br>
-<br>
-    // Handle a compile callback for the function at index FnIdx.<br>
-    TargetAddress compile(unsigned FnIdx) {<br>
-      // Take ownership of self. This will ensure we delete the partition and<br>
-      // free all its resources once we're done compiling.<br>
-      std::unique_ptr<UncompiledPartition> This = LD.takeUPOwnership(ID);<br>
-<br>
-      // Release all other compile callbacks for this partition.<br>
-      // We skip the callback for this function because that's the one that<br>
-      // called us, and the callback manager will already have removed it.<br>
-      auto &CCMgr = LD.getCODLayer().CompileCallbackMgr;<br>
-      for (unsigned I = 0; I < PartitionEntries.size(); ++I)<br>
-        if (I != FnIdx)<br>
-          CCMgr.releaseCompileCallback(PartitionEntries[I].CallbackID);<br>
-<br>
-      // Grab the name of the function being called here.<br>
-      Function *F = PartitionEntries[FnIdx].F;<br>
-      std::string CalledFnName = Mangle(F->getName(), SrcM->getDataLayout());<br>
-<br>
-      // Extract the function and add it to the base layer.<br>
-      auto PartitionImplH = emitPartition();<br>
-      LD.addToLogicalModule(LMH, PartitionImplH);<br>
-<br>
-      // Update body pointers.<br>
-      // FIXME: When we start supporting remote lazy jitting this will need to<br>
-      //        be replaced with a user-supplied callback for updating the<br>
-      //        remote pointers.<br>
-      TargetAddress CalledAddr = 0;<br>
-      for (unsigned I = 0; I < PartitionEntries.size(); ++I) {<br>
-        auto F = PartitionEntries[I].F;<br>
-        std::string FName(F->getName());<br>
-        auto FnBodySym =<br>
-          LD.getBaseLayer().findSymbolIn(PartitionImplH,<br>
-                                         Mangle(FName, SrcM->getDataLayout()),<br>
-                                         false);<br>
-        auto FnPtrSym =<br>
-          LD.getBaseLayer().findSymbolIn(LD.getGVsAndStubsHandle(LMH),<br>
-                                         Mangle(FName + "$orc_addr",<br>
-                                                SrcM->getDataLayout()),<br>
-                                         false);<br>
-        assert(FnBodySym && "Couldn't find function body.");<br>
-        assert(FnPtrSym && "Couldn't find function body pointer.");<br>
-<br>
-        auto FnBodyAddr = FnBodySym.getAddress();<br>
-        void *FnPtrAddr = reinterpret_cast<void*>(<br>
-                            static_cast<uintptr_t>(FnPtrSym.getAddress()));<br>
-<br>
-        // If this is the function we're calling record the address so we can<br>
-        // return it from this function.<br>
-        if (I == FnIdx)<br>
-          CalledAddr = FnBodyAddr;<br>
-<br>
-        memcpy(FnPtrAddr, &FnBodyAddr, sizeof(uintptr_t));<br>
-      }<br>
-<br>
-      // Finally, clear the partition structure so we don't try to<br>
-      // double-release the callbacks in the UncompiledPartition destructor.<br>
-      PartitionEntries.clear();<br>
-<br>
-      return CalledAddr;<br>
-    }<br>
-<br>
-  private:<br>
-<br>
-    BaseLayerModuleSetHandleT emitPartition() {<br>
-      // Create the module.<br>
-      std::string NewName(SrcM->getName());<br>
-      for (auto &PEntry : PartitionEntries) {<br>
-        NewName += ".";<br>
-        NewName += PEntry.F->getName();<br>
-      }<br>
-      auto PM = llvm::make_unique<Module>(NewName, SrcM->getContext());<br>
-      PM->setDataLayout(SrcM->getDataLayout());<br>
-      ValueToValueMapTy VMap;<br>
-      GlobalDeclMaterializer GDM(*PM);<br>
-<br>
-      // Create decls in the new module.<br>
-      for (auto &PEntry : PartitionEntries)<br>
-        cloneFunctionDecl(*PM, *PEntry.F, &VMap);<br>
-<br>
-      // Move the function bodies.<br>
-      for (auto &PEntry : PartitionEntries)<br>
-        moveFunctionBody(*PEntry.F, VMap);<br>
-<br>
-      // Create memory manager and symbol resolver.<br>
-      auto MemMgr = llvm::make_unique<SectionMemoryManager>();<br>
-      auto Resolver = createLambdaResolver(<br>
-          [this](const std::string &Name) {<br>
-            if (auto Symbol = LD.findSymbolInternally(LMH, Name))<br>
-              return RuntimeDyld::SymbolInfo(Symbol.getAddress(),<br>
-                                             Symbol.getFlags());<br>
-            return LD.findSymbolExternally(Name);<br>
-          },<br>
-          [this](const std::string &Name) {<br>
-            if (auto Symbol = LD.findSymbolInternally(LMH, Name))<br>
-              return RuntimeDyld::SymbolInfo(Symbol.getAddress(),<br>
-                                             Symbol.getFlags());<br>
-            return RuntimeDyld::SymbolInfo(nullptr);<br>
-          });<br>
-      std::vector<std::unique_ptr<Module>> PartMSet;<br>
-      PartMSet.push_back(std::move(PM));<br>
-      return LD.getBaseLayer().addModuleSet(std::move(PartMSet),<br>
-                                            std::move(MemMgr),<br>
-                                            std::move(Resolver));<br>
-    }<br>
-<br>
-    LogicalDylib &LD;<br>
-    typename LogicalDylib::LMHandle LMH;<br>
-    std::shared_ptr<Module> SrcM;<br>
-    typename LogicalDylib::UncompiledPartitionID ID;<br>
-    PartitionEntryList PartitionEntries;<br>
-  };<br>
-<br>
-  typedef std::list<std::unique_ptr<LogicalDylib>> LogicalDylibList;<br>
+  typedef typename CODLogicalDylib::LogicalModuleHandle LogicalModuleHandle;<br>
+  typedef std::list<CODLogicalDylib> LogicalDylibList;<br>
<br>
 public:<br>
   /// @brief Handle to a set of loaded modules.<br>
@@ -382,20 +96,25 @@ public:<br>
     assert(MemMgr == nullptr &&<br>
            "User supplied memory managers not supported with COD yet.");<br>
<br>
-    LogicalDylibs.push_back(createLogicalDylib(*this, std::move(Resolver)));<br>
+    LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));<br>
+    auto &LDLResources = LogicalDylibs.back().getDylibResources();<br>
+<br>
+    LDLResources.ExternalSymbolResolver =<br>
+      [Resolver](const std::string &Name) {<br>
+        return Resolver->findSymbol(Name);<br>
+      };<br>
+<br>
+    LDLResources.Partitioner =<br>
+      [](Function &F) {<br>
+        std::set<Function*> Partition;<br>
+        Partition.insert(&F);<br>
+        return Partition;<br>
+      };<br></blockquote></div></div><div><br>Maybe run this through clang-format (might be worth just clang-formatting this whole patch, see if it looks better that way)? It looks like this:<br><br><div><font face="monospace, monospace">    LDLResources.Partitioner = [](Function &F) {</font></div><div><font face="monospace, monospace">      std::set<Function *> Partition;</font></div><div><font face="monospace, monospace">      Partition.insert(&F);</font></div><div><font face="monospace, monospace">      return Partition;</font></div><div><font face="monospace, monospace">    };</font></div> <br>Which is possibly more idiomatic.<br></div></div></div></div></blockquote><div><br></div><div>Yep. I'll probably run clang-format over all the Orc headers soon - I suspect there are a few bits of non-idiomatic formatting in there. </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><div><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
     // Process each of the modules in this module set.<br>
-    for (auto &M : Ms) {<br>
-      std::vector<std::vector<Function*>> Partitioning;<br>
-      for (auto &F : *M) {<br>
-        if (F.isDeclaration())<br>
-          continue;<br>
-        Partitioning.emplace_back(1, &F);<br>
-      }<br>
-      addLogicalModule(*LogicalDylibs.back(),<br>
-                       std::shared_ptr<Module>(std::move(M)),<br>
-                       std::move(Partitioning));<br>
-    }<br>
+    for (auto &M : Ms)<br>
+      addLogicalModule(LogicalDylibs.back(),<br>
+                       std::shared_ptr<Module>(std::move(M)));<br>
<br>
     return std::prev(LogicalDylibs.end());<br>
   }<br>
@@ -420,13 +139,12 @@ public:<br>
   ///        below this one.<br>
   JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,<br>
                          bool ExportedSymbolsOnly) {<br>
-    return (*H)->findSymbol(Name, ExportedSymbolsOnly);<br>
+    return H->findSymbol(Name, ExportedSymbolsOnly);<br>
   }<br>
<br>
 private:<br>
<br>
-  void addLogicalModule(LogicalDylib &LD, std::shared_ptr<Module> SrcM,<br>
-                        std::vector<std::vector<Function*>> Partitions) {<br>
+  void addLogicalModule(CODLogicalDylib &LD, std::shared_ptr<Module> SrcM) {<br>
<br>
     // Bump the linkage and rename any anonymous/privote members in SrcM to<br>
     // ensure that everything will resolve properly after we partition SrcM.<br>
@@ -434,6 +152,7 @@ private:<br>
<br>
     // Create a logical module handle for SrcM within the logical dylib.<br>
     auto LMH = LD.createLogicalModule();<br>
+    LD.getLogicalModuleResources(LMH).SourceModule = SrcM;<br>
<br>
     // Create the GVs-and-stubs module.<br>
     auto GVsAndStubsM = llvm::make_unique<Module>(<br>
@@ -442,31 +161,31 @@ private:<br>
     GVsAndStubsM->setDataLayout(SrcM->getDataLayout());<br>
     ValueToValueMapTy VMap;<br>
<br>
-    // Process partitions and create stubs.<br>
+    // Process module and create stubs.<br>
     // We create the stubs before copying the global variables as we know the<br>
     // stubs won't refer to any globals (they only refer to their implementation<br>
     // pointer) so there's no ordering/value-mapping issues.<br>
-    for (auto& Partition : Partitions) {<br>
-      auto &UP = LD.createUncompiledPartition(LMH, SrcM);<br>
-      typename UncompiledPartition::PartitionEntryList PartitionEntries;<br>
-      for (auto &F : Partition) {<br>
-        assert(!F->isDeclaration() &&<br>
-               "Partition should only contain definitions");<br>
-        unsigned FnIdx = PartitionEntries.size();<br>
-        auto CCI = CompileCallbackMgr.getCompileCallback(SrcM->getContext());<br>
-        PartitionEntries.push_back(<br>
-          typename UncompiledPartition::PartitionEntry(F, CCI.getAddress()));<br>
-        Function *StubF = cloneFunctionDecl(*GVsAndStubsM, *F, &VMap);<br>
-        GlobalVariable *FnBodyPtr =<br>
-          createImplPointer(*StubF->getType(), *StubF->getParent(),<br>
-                            StubF->getName() + "$orc_addr",<br>
-                            createIRTypedAddress(*StubF->getFunctionType(),<br>
-                                                 CCI.getAddress()));<br>
-        makeStub(*StubF, *FnBodyPtr);<br>
-        CCI.setCompileAction([&UP, FnIdx]() { return UP.compile(FnIdx); });<br>
-      }<br>
+    for (auto &F : *SrcM) {<br>
<br>
-      UP.setPartitionEntries(std::move(PartitionEntries));<br>
+      // Skip declarations.<br>
+      if (F.isDeclaration())<br>
+        continue;<br>
+<br>
+      // For each definition: create a callback, a stub, and a function body<br>
+      // pointer. Initialize the function body pointer to point at the callback,<br>
+      // and set the callback to compile the function body.<br>
+      auto CCInfo = CompileCallbackMgr.getCompileCallback(SrcM->getContext());<br>
+      Function *StubF = cloneFunctionDecl(*GVsAndStubsM, F, &VMap);<br>
+      GlobalVariable *FnBodyPtr =<br>
+        createImplPointer(*StubF->getType(), *StubF->getParent(),<br>
+                          StubF->getName() + "$orc_addr",<br>
+                          createIRTypedAddress(*StubF->getFunctionType(),<br>
+                                               CCInfo.getAddress()));<br>
+      makeStub(*StubF, *FnBodyPtr);<br>
+      CCInfo.setCompileAction(<br>
+        [this, &LD, LMH, &F]() {<br>
+          return extractAndCompile(LD, LMH, F);<br>
+        });<br>
     }<br>
<br>
     // Now clone the global variable declarations.<br>
@@ -483,12 +202,9 @@ private:<br>
     // Build a resolver for the stubs module and add it to the base layer.<br>
     auto GVsAndStubsResolver = createLambdaResolver(<br>
         [&LD](const std::string &Name) {<br>
-          if (auto Symbol = LD.findSymbol(Name, false))<br>
-            return RuntimeDyld::SymbolInfo(Symbol.getAddress(),<br>
-                                           Symbol.getFlags());<br>
-          return LD.findSymbolExternally(Name);<br>
+          return LD.getDylibResources().ExternalSymbolResolver(Name);<br>
         },<br>
-        [&LD](const std::string &Name) {<br>
+        [](const std::string &Name) {<br>
           return RuntimeDyld::SymbolInfo(nullptr);<br>
         });<br>
<br>
@@ -498,7 +214,7 @@ private:<br>
       BaseLayer.addModuleSet(std::move(GVsAndStubsMSet),<br>
                              llvm::make_unique<SectionMemoryManager>(),<br>
                              std::move(GVsAndStubsResolver));<br>
-    LD.setGVsAndStubsHandle(LMH, GVsAndStubsH);<br>
+    LD.addToLogicalModule(LMH, GVsAndStubsH);<br>
   }<br>
<br>
   static std::string Mangle(StringRef Name, const DataLayout &DL) {<br>
@@ -511,35 +227,101 @@ private:<br>
     return MangledName;<br>
   }<br>
<br>
+  TargetAddress extractAndCompile(CODLogicalDylib &LD,<br>
+                                  LogicalModuleHandle LMH,<br>
+                                  Function &F) {<br>
+    Module &SrcM = *LD.getLogicalModuleResources(LMH).SourceModule;<br>
+<br>
+    // If F is a declaration we must already have compiled it.<br>
+    if (F.isDeclaration())<br>
+      return 0;<br>
+<br>
+    // Grab the name of the function being called here.<br>
+    std::string CalledFnName = Mangle(F.getName(), SrcM.getDataLayout());<br>
+<br>
+    const auto &Partition = LD.getDylibResources().Partitioner(F);<br></blockquote></div></div><div><br>Taking this by const (auto) ref is a bit confusing - what's the intent there? To support non-value-returning partitioning functors/functions? (& like the feedback above, I'm still a bit confused by what kind of instantiations of this class can exist/what types can be specified for the PartitioningFtor type) </div></div></div></div></blockquote><div><br></div><div>That's a think-o: the partition should be taken by value. Fixed in r239642.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+    auto PartitionH = emitPartition(LD, LMH, Partition);<br></blockquote></span><div><br>In fact, emitPartition here requires that Partition be a  " const std::set<Function*> &" - so perhaps it'd be easier if Partition were just declared as a "std::set<Function*>" directly (no reference lifetime extensions of temporaries, etc)? </div></div></div></div></blockquote><div><br></div><div>What heresy is this? You love 'auto'. ;) </div><div>I think the real problem is that I'd pinned down the return type of the Partitioner. That has also been fixed in r239642.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+<br>
+    TargetAddress CalledAddr = 0;<br>
+    for (auto *SubF : Partition) {<br>
+      std::string FName(SubF->getName());<br></blockquote></span><div><br>Prefer copy-init over direct-init?<br></div></div></div></div></blockquote><div><br></div><div>Yep. This is a hangover from the previous code. Fixed in r239642.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+      auto FnBodySym =<br>
+        BaseLayer.findSymbolIn(PartitionH, Mangle(FName, SrcM.getDataLayout()),<br>
+                               false);<br>
+      auto FnPtrSym =<br>
+        BaseLayer.findSymbolIn(*LD.moduleHandlesBegin(LMH),<br>
+                               Mangle(FName + "$orc_addr",<br>
+                                      SrcM.getDataLayout()),<br>
+                               false);<br>
+      assert(FnBodySym && "Couldn't find function body.");<br>
+      assert(FnPtrSym && "Couldn't find function body pointer.");<br>
+<br>
+      auto FnBodyAddr = FnBodySym.getAddress();<br></blockquote></span><div><br>Not sure if these autos improve readability (I guess they're all JITSymbols? (FnBodySym, FnPtrSym, FnBodyAddr)) </div></div></div></div></blockquote><div><br></div><div>The first two are JITSymbols. The latter is a TargetAddress. I think the type is implied by the method names and variable suffixes (Sym/findSymbol, Addr/getAddress), but that's a matter of personal taste. I've actually spelled out the TargetAddress type in r239642. JITSymbol has been left to deduction.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+      void *FnPtrAddr = reinterpret_cast<void*>(<br>
+          static_cast<uintptr_t>(FnPtrSym.getAddress()));<br>
+<br>
+      // If this is the function we're calling record the address so we can<br>
+      // return it from this function.<br>
+      if (SubF == &F)<br>
+        CalledAddr = FnBodyAddr;<br>
+<br>
+      memcpy(FnPtrAddr, &FnBodyAddr, sizeof(uintptr_t));<br>
+    }<br>
+<br>
+    return CalledAddr;<br>
+  }<br>
+<br>
+  BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,<br>
+                                          LogicalModuleHandle LMH,<br>
+                                          const std::set<Function*> &Partition) {<br>
+    Module &SrcM = *LD.getLogicalModuleResources(LMH).SourceModule;<br>
+<br>
+    // Create the module.<br>
+    std::string NewName(SrcM.getName());<br></blockquote></span><div><br>Copy-init over direct-init? </div></div></div></div></blockquote><div><br></div><div>Yep. Fixed in r239642.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+    for (auto *F : Partition) {<br>
+      NewName += ".";<br>
+      NewName += F->getName();<br>
+    }<br>
+<br>
+    auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());<br>
+    M->setDataLayout(SrcM.getDataLayout());<br>
+    ValueToValueMapTy VMap;<br>
+    GlobalDeclMaterializer GDM(*M);<br>
+<br>
+    // Create decls in the new module.<br>
+    for (auto *F : Partition)<br>
+      cloneFunctionDecl(*M, *F, &VMap);<br>
+<br>
+    // Move the function bodies.<br>
+    for (auto *F : Partition)<br>
+      moveFunctionBody(*F, VMap);<br>
+<br>
+    // Create memory manager and symbol resolver.<br>
+    auto MemMgr = llvm::make_unique<SectionMemoryManager>();<br>
+    auto Resolver = createLambdaResolver(<br>
+        [this, &LD, LMH](const std::string &Name) {<br>
+          if (auto Symbol = LD.findSymbolInternally(LMH, Name))<br>
+            return RuntimeDyld::SymbolInfo(Symbol.getAddress(),<br>
+                                           Symbol.getFlags());<br>
+          return LD.getDylibResources().ExternalSymbolResolver(Name);<br>
+        },<br>
+        [this, &LD, LMH](const std::string &Name) {<br>
+          if (auto Symbol = LD.findSymbolInternally(LMH, Name))<br>
+            return RuntimeDyld::SymbolInfo(Symbol.getAddress(),<br>
+                                           Symbol.getFlags());<br>
+          return RuntimeDyld::SymbolInfo(nullptr);<br>
+        });<br>
+    std::vector<std::unique_ptr<Module>> PartMSet;<br>
+    PartMSet.push_back(std::move(M));<br>
+    return BaseLayer.addModuleSet(std::move(PartMSet), std::move(MemMgr),<br>
+                                  std::move(Resolver));</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+  }<br>
+<br>
   BaseLayerT &BaseLayer;<br>
   CompileCallbackMgrT &CompileCallbackMgr;<br>
   LogicalDylibList LogicalDylibs;<br>
 };<br>
<br>
-template <typename BaseLayerT, typename CompileCallbackMgrT><br>
-typename CompileOnDemandLayer<BaseLayerT, CompileCallbackMgrT>::<br>
-           UncompiledPartition&<br>
-CompileOnDemandLayer<BaseLayerT, CompileCallbackMgrT>::LogicalDylib::<br>
-  createUncompiledPartition(LMHandle LMH, std::shared_ptr<Module> SrcM) {<br>
-  UncompiledPartitions.push_back(<br>
-      llvm::make_unique<UncompiledPartition>(*this, LMH, std::move(SrcM)));<br>
-  UncompiledPartitions.back()->setID(UncompiledPartitions.size() - 1);<br>
-  return *UncompiledPartitions.back();<br>
-}<br>
-<br>
-template <typename BaseLayerT, typename CompileCallbackMgrT><br>
-std::unique_ptr<typename CompileOnDemandLayer<BaseLayerT, CompileCallbackMgrT>::<br>
-                  UncompiledPartition><br>
-CompileOnDemandLayer<BaseLayerT, CompileCallbackMgrT>::LogicalDylib::<br>
-  takeUPOwnership(UncompiledPartitionID ID) {<br>
-<br>
-  std::swap(UncompiledPartitions[ID], UncompiledPartitions.back());<br>
-  UncompiledPartitions[ID]->setID(ID);<br>
-  auto UP = std::move(UncompiledPartitions.back());<br>
-  UncompiledPartitions.pop_back();<br>
-  return UP;<br>
-}<br>
-<br>
 } // End namespace orc.<br>
 } // End namespace llvm.<br>
<br>
<br>
Added: llvm/trunk/include/llvm/ExecutionEngine/Orc/LogicalDylib.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_ExecutionEngine_Orc_LogicalDylib.h-3Frev-3D239561-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=8qYodrCL7uxJ1Y-eq4mnicwTUdh4XkphuNCTqzS7JDc&s=13hsTKLnrfAkE_kIXAQceK89ZL1TO3Oai6-7x6BUn7I&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/LogicalDylib.h?rev=239561&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/LogicalDylib.h (added)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/LogicalDylib.h Thu Jun 11 16:45:19 2015<br>
@@ -0,0 +1,118 @@<br>
+//===--- LogicalDylib.h - Simulates dylib-style symbol lookup ---*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// Simulates symbol resolution inside a dylib.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H<br>
+#define LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H<br>
+<br>
+#include "llvm/ADT/iterator.h"<br>
+#include "llvm/ADT/Optional.h"<br>
+<br>
+namespace llvm {<br>
+namespace orc {<br>
+<br>
+template <typename BaseLayerT,<br>
+          typename LogicalModuleResources,<br>
+          typename LogicalDylibResources><br>
+class LogicalDylib {<br>
+public:<br>
+  typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;<br>
+private:<br>
+<br>
+  typedef std::vector<BaseLayerModuleSetHandleT> BaseLayerHandleList;<br>
+<br>
+  struct LogicalModule {<br>
+    LogicalModuleResources Resources;<br>
+    BaseLayerHandleList BaseLayerHandles;<br>
+  };<br>
+  typedef std::vector<LogicalModule> LogicalModuleList;<br>
+<br>
+public:<br>
+<br>
+  typedef typename BaseLayerHandleList::iterator BaseLayerHandleIterator;<br>
+  typedef typename LogicalModuleList::iterator LogicalModuleHandle;<br>
+<br>
+  LogicalDylib(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}<br>
+<br>
+  ~LogicalDylib() {<br>
+    for (auto &LM : LogicalModules)<br>
+      for (auto BLH : LM.BaseLayerHandles)<br>
+        BaseLayer.removeModuleSet(BLH);<br>
+  }<br>
+<br>
+  LogicalModuleHandle createLogicalModule() {<br>
+    LogicalModules.push_back(LogicalModule());<br>
+    return std::prev(LogicalModules.end());<br>
+  }<br>
+<br>
+  void addToLogicalModule(LogicalModuleHandle LMH,<br>
+                          BaseLayerModuleSetHandleT BaseLayerHandle) {<br>
+    LMH->BaseLayerHandles.push_back(BaseLayerHandle);<br>
+  }<br>
+<br>
+  LogicalModuleResources& getLogicalModuleResources(LogicalModuleHandle LMH) {<br>
+    return LMH->Resources;<br>
+  }<br>
+<br>
+  BaseLayerHandleIterator moduleHandlesBegin(LogicalModuleHandle LMH) {<br>
+    return LMH->BaseLayerHandles.begin();<br>
+  }<br>
+<br>
+  BaseLayerHandleIterator moduleHandlesEnd(LogicalModuleHandle LMH) {<br>
+    return LMH->BaseLayerHandles.end();<br>
+  }<br>
+<br>
+  JITSymbol findSymbolInLogicalModule(LogicalModuleHandle LMH,<br>
+                                      const std::string &Name) {<br>
+    for (auto BLH : LMH->BaseLayerHandles)<br>
+      if (auto Symbol = BaseLayer.findSymbolIn(BLH, Name, false))<br>
+        return Symbol;<br>
+    return nullptr;<br>
+  }<br>
+<br>
+  JITSymbol findSymbolInternally(LogicalModuleHandle LMH,<br>
+                                 const std::string &Name) {<br>
+    if (auto Symbol = findSymbolInLogicalModule(LMH, Name))<br>
+      return Symbol;<br>
+<br>
+    for (auto LMI = LogicalModules.begin(), LME = LogicalModules.end();<br>
+           LMI != LME; ++LMI) {<br>
+      if (LMI != LMH)<br>
+        if (auto Symbol = findSymbolInLogicalModule(LMI, Name))<br>
+          return Symbol;<br>
+    }<br>
+<br>
+    return nullptr;<br>
+  }<br>
+<br>
+  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {<br>
+    for (auto &LM : LogicalModules)<br>
+      for (auto BLH : LM.BaseLayerHandles)<br>
+        if (auto Symbol =<br>
+            BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))<br>
+          return Symbol;<br>
+    return nullptr;<br>
+  }<br>
+<br>
+  LogicalDylibResources& getDylibResources() { return DylibResources; }<br>
+<br>
+protected:<br>
+  BaseLayerT BaseLayer;<br>
+  LogicalModuleList LogicalModules;<br>
+  LogicalDylibResources DylibResources;<br>
+<br>
+};<br>
+<br>
+} // End namespace orc.<br>
+} // End namespace llvm.<br>
+<br>
+#endif // LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H<br>
<br>
Modified: llvm/trunk/tools/lli/OrcLazyJIT.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_lli_OrcLazyJIT.h-3Frev-3D239561-26r1-3D239560-26r2-3D239561-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=8qYodrCL7uxJ1Y-eq4mnicwTUdh4XkphuNCTqzS7JDc&s=tA2USw1rHI7aLGUAinLNgAfaLPO9vmAbsi4ZF3_zWek&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/OrcLazyJIT.h?rev=239561&r1=239560&r2=239561&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/OrcLazyJIT.h (original)<br>
+++ llvm/trunk/tools/lli/OrcLazyJIT.h Thu Jun 11 16:45:19 2015<br>
@@ -89,22 +89,26 @@ public:<br>
     //   2) Check for C++ runtime overrides.<br>
     //   3) Search the host process (LLI)'s symbol table.<br>
     auto Resolver =<br>
-      orc::createLambdaResolver(<br>
-        [this](const std::string &Name) {<br>
+      std::shared_ptr<RuntimeDyld::SymbolResolver>(<br></blockquote></div></div><div><br>Prefer copy init over direct init (otherwise it looks like createLambdaResolver might be returning a raw pointer you're taking ownership of here - which raises a bit more care than is otherwise due) ^<br></div></div></div></div></blockquote><div><br></div><div>This is copy-init, isn't it?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+        orc::createLambdaResolver(<br>
+          [this](const std::string &Name) {<br>
+            if (auto Sym = CODLayer.findSymbol(Name, true))<br>
+              return RuntimeDyld::SymbolInfo(Sym.getAddress(),<br>
+                                             Sym.getFlags());<br>
+<br>
+            if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))<br>
+              return Sym;<br>
<br>
-          if (auto Sym = CODLayer.findSymbol(Name, true))<br>
-            return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());<br>
+            if (auto Addr =<br>
+                RTDyldMemoryManager::getSymbolAddressInProcess(Name))<br>
+              return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);<br>
<br>
-          if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))<br>
-            return Sym;<br>
-<br>
-          if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))<br>
-            return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);<br>
-<br>
-          return RuntimeDyld::SymbolInfo(nullptr);<br>
-        },<br>
-        [](const std::string &Name) { return RuntimeDyld::SymbolInfo(nullptr); }<br>
-      );<br>
+            return RuntimeDyld::SymbolInfo(nullptr);<br>
+          },<br>
+          [](const std::string &Name) {<br>
+            return RuntimeDyld::SymbolInfo(nullptr);<br>
+          }<br>
+        ));<br>
<br>
     // Add the module to the JIT.<br>
     std::vector<std::unique_ptr<Module>> S;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div></div>