<div dir="ltr">This change is essentially unrelated to that. This is really about allowing you to request additional stubs at any point in your execution, rather than having to request all stubs up front.<div><br></div><div>The lightweight stub creation patch that went in a week or so back was an emphatic success: It reduced the cost for creating a stub by several orders of magnitude.</div><div><br></div><div>- Lang.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 29, 2015 at 3:15 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Thu, Oct 29, 2015 at 3:04 PM, Lang Hames via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: lhames<br>
Date: Thu Oct 29 17:04:22 2015<br>
New Revision: 251658<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=251658&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=251658&view=rev</a><br>
Log:<br>
[Orc] Teach IndirectStubsManager to manage an expandable pool of stubs, rather<br>
than a pre-allocated slab of stubs. Also add a convenience method for creating a<br>
single stub, rather than a whole block a time.<br></blockquote><div><br></div></span><div>Even with the lighter weight stub construction this still seems to be a hot point & worth removing the upfront O(sizeof initial module) cost with the smaller factor? (I know we chatted about it a week or two ago & you weren't sure if that'd be the case)</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h<br>
    llvm/trunk/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp<br>
    llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h?rev=251658&r1=251657&r2=251658&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h?rev=251658&r1=251657&r2=251658&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h Thu Oct 29 17:04:22 2015<br>
@@ -234,6 +234,10 @@ public:<br>
<br>
   virtual ~IndirectStubsManagerBase() {}<br>
<br>
+  /// @brief Create a single stub with the given name, target address and flags.<br>
+  virtual std::error_code createStub(StringRef StubName, TargetAddress StubAddr,<br>
+                                     JITSymbolFlags StubFlags) = 0;<br>
+<br>
   /// @brief Create StubInits.size() stubs with the given names, target<br>
   ///        addresses, and flags.<br>
   virtual std::error_code createStubs(const StubInitsMap &StubInits) = 0;<br>
@@ -252,25 +256,29 @@ private:<br>
   virtual void anchor();<br>
 };<br>
<br>
-/// @brief IndirectStubsManager implementation for a concrete target, e.g. OrcX86_64.<br>
-///        (See OrcTargetSupport.h).<br>
+/// @brief IndirectStubsManager implementation for a concrete target, e.g.<br>
+///        OrcX86_64. (See OrcTargetSupport.h).<br>
 template <typename TargetT><br>
 class IndirectStubsManager : public IndirectStubsManagerBase {<br>
 public:<br>
<br>
-  std::error_code<br>
-  createStubs(const StubInitsMap &StubInits) override {<br>
-    if (auto EC = TargetT::emitIndirectStubsBlock(IndirectStubsInfo,<br>
-                                                  StubInits.size(),<br>
-                                                  nullptr))<br>
+  std::error_code createStub(StringRef StubName, TargetAddress StubAddr,<br>
+                             JITSymbolFlags StubFlags) override {<br>
+    if (auto EC = reserveStubs(1))<br>
       return EC;<br>
<br>
-    unsigned I = 0;<br>
-    for (auto &Entry : StubInits) {<br>
-      *IndirectStubsInfo.getPtr(I) =<br>
-        reinterpret_cast<void*>(static_cast<uintptr_t>(Entry.second.first));<br>
-      StubIndexes[Entry.first()] = std::make_pair(I++, Entry.second.second);<br>
-    }<br>
+    createStubInternal(StubName, StubAddr, StubFlags);<br>
+<br>
+    return std::error_code();<br>
+  }<br>
+<br>
+  std::error_code createStubs(const StubInitsMap &StubInits) override {<br>
+    if (auto EC = reserveStubs(StubInits.size()))<br>
+      return EC;<br>
+<br>
+    for (auto &Entry : StubInits)<br>
+      createStubInternal(Entry.first(), Entry.second.first,<br>
+                         Entry.second.second);<br>
<br>
     return std::error_code();<br>
   }<br>
@@ -279,7 +287,8 @@ public:<br>
     auto I = StubIndexes.find(Name);<br>
     if (I == StubIndexes.end())<br>
       return nullptr;<br>
-    void *StubAddr = IndirectStubsInfo.getStub(I->second.first);<br>
+    auto Key = I->second.first;<br>
+    void *StubAddr = IndirectStubsInfos[Key.first].getStub(Key.second);<br>
     assert(StubAddr && "Missing stub address");<br>
     auto StubTargetAddr =<br>
       static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(StubAddr));<br>
@@ -293,23 +302,54 @@ public:<br>
     auto I = StubIndexes.find(Name);<br>
     if (I == StubIndexes.end())<br>
       return nullptr;<br>
-    void *PtrAddr = IndirectStubsInfo.getPtr(StubIndexes[Name].first);<br>
+    auto Key = I->second.first;<br>
+    void *PtrAddr = IndirectStubsInfos[Key.first].getPtr(Key.second);<br>
     assert(PtrAddr && "Missing pointer address");<br>
     auto PtrTargetAddr =<br>
       static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(PtrAddr));<br>
-    return JITSymbol(PtrTargetAddr, JITSymbolFlags::None);<br>
+    return JITSymbol(PtrTargetAddr, I->second.second);<br>
   }<br>
<br>
   std::error_code updatePointer(StringRef Name, TargetAddress NewAddr) override {<br>
-    assert(StubIndexes.count(Name) && "No stub pointer for symbol");<br>
-    *IndirectStubsInfo.getPtr(StubIndexes[Name].first) =<br>
+    auto I = StubIndexes.find(Name);<br>
+    assert(I != StubIndexes.end() && "No stub pointer for symbol");<br>
+    auto Key = I->second.first;<br>
+    *IndirectStubsInfos[Key.first].getPtr(Key.second) =<br>
       reinterpret_cast<void*>(static_cast<uintptr_t>(NewAddr));<br>
     return std::error_code();<br>
   }<br>
<br>
 private:<br>
-  typename TargetT::IndirectStubsInfo IndirectStubsInfo;<br>
-  StringMap<std::pair<unsigned, JITSymbolFlags>> StubIndexes;<br>
+<br>
+  std::error_code reserveStubs(unsigned NumStubs) {<br>
+    if (NumStubs <= FreeStubs.size())<br>
+      return std::error_code();<br>
+<br>
+    unsigned NewStubsRequired = NumStubs - FreeStubs.size();<br>
+    unsigned NewBlockId = IndirectStubsInfos.size();<br>
+    typename TargetT::IndirectStubsInfo ISI;<br>
+    if (auto EC = TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired,<br>
+                                                  nullptr))<br>
+      return EC;<br>
+    for (unsigned I = 0; I < ISI.getNumStubs(); ++I)<br>
+      FreeStubs.push_back(std::make_pair(NewBlockId, I));<br>
+    IndirectStubsInfos.push_back(std::move(ISI));<br>
+    return std::error_code();<br>
+  }<br>
+<br>
+  void createStubInternal(StringRef StubName, TargetAddress InitAddr,<br>
+                          JITSymbolFlags StubFlags) {<br>
+    auto Key = FreeStubs.back();<br>
+    FreeStubs.pop_back();<br>
+    *IndirectStubsInfos[Key.first].getPtr(Key.second) =<br>
+      reinterpret_cast<void*>(static_cast<uintptr_t>(InitAddr));<br>
+    StubIndexes[StubName] = std::make_pair(Key, StubFlags);<br>
+  }<br>
+<br>
+  std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos;<br>
+  typedef std::pair<uint16_t, uint16_t> StubKey;<br>
+  std::vector<StubKey> FreeStubs;<br>
+  StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;<br>
 };<br>
<br>
 /// @brief Build a function pointer of FunctionType with the given constant<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h?rev=251658&r1=251657&r2=251658&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h?rev=251658&r1=251657&r2=251658&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h Thu Oct 29 17:04:22 2015<br>
@@ -59,6 +59,8 @@ public:<br>
     const static unsigned PtrSize = 8;<br>
<br>
     IndirectStubsInfo() : NumStubs(0) {}<br>
+    IndirectStubsInfo(IndirectStubsInfo&&);<br>
+    IndirectStubsInfo& operator=(IndirectStubsInfo&&);<br>
     ~IndirectStubsInfo();<br>
<br>
     /// @brief Number of stubs in this block.<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp?rev=251658&r1=251657&r2=251658&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp?rev=251658&r1=251657&r2=251658&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp Thu Oct 29 17:04:22 2015<br>
@@ -144,6 +144,22 @@ OrcX86_64::insertCompileCallbackTrampoli<br>
   return GetLabelName;<br>
 }<br>
<br>
+OrcX86_64::IndirectStubsInfo::IndirectStubsInfo(IndirectStubsInfo &&Other) {<br>
+  StubsBlock = std::move(Other.StubsBlock);<br>
+  PtrsBlock = std::move(Other.PtrsBlock);<br>
+  Other.StubsBlock = sys::MemoryBlock();<br>
+  Other.PtrsBlock = sys::MemoryBlock();<br>
+}<br>
+<br>
+OrcX86_64::IndirectStubsInfo&<br>
+OrcX86_64::IndirectStubsInfo::operator=(IndirectStubsInfo &&Other) {<br>
+  StubsBlock = std::move(Other.StubsBlock);<br>
+  PtrsBlock = std::move(Other.PtrsBlock);<br>
+  Other.StubsBlock = sys::MemoryBlock();<br>
+  Other.PtrsBlock = sys::MemoryBlock();<br>
+  return *this;<br>
+}<br>
+<br>
 OrcX86_64::IndirectStubsInfo::~IndirectStubsInfo() {<br>
   sys::Memory::releaseMappedMemory(StubsBlock);<br>
   sys::Memory::releaseMappedMemory(PtrsBlock);<br>
<br>
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp?rev=251658&r1=251657&r2=251658&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp?rev=251658&r1=251657&r2=251658&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp (original)<br>
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp Thu Oct 29 17:04:22 2015<br>
@@ -33,6 +33,11 @@ public:<br>
<br>
 class DummyStubsManager : public orc::IndirectStubsManagerBase {<br>
 public:<br>
+  std::error_code createStub(StringRef StubName, TargetAddress InitAddr,<br>
+                             JITSymbolFlags Flags) override {<br>
+    llvm_unreachable("Not implemented");<br>
+  }<br>
+<br>
   std::error_code createStubs(const StubInitsMap &StubInits) override {<br>
     llvm_unreachable("Not implemented");<br>
   }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>