<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">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><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><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">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><br></div></div>