[RuntimeDyld] Don't allocate unnecessary stub buffer space
authorSanjoy Das <sanjoy@playingwithpointers.com>
Mon, 23 Nov 2015 21:47:51 +0000 (21:47 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Mon, 23 Nov 2015 21:47:51 +0000 (21:47 +0000)
Summary:
For relocation types that are known to not require stub functions, there
is no need to allocate extra space for the stub functions.

Reviewers: lhames, reames, maksfb

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D14676

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253920 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s [new file with mode: 0644]
test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll [new file with mode: 0644]
tools/llvm-rtdyld/llvm-rtdyld.cpp

index 93de920209c7fada153890178cda063512c8fe91..dd02ece3a9f12866018cd2f483c171d346f2d029 100644 (file)
@@ -432,10 +432,9 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
     if (!(RelSecI == Section))
       continue;
 
     if (!(RelSecI == Section))
       continue;
 
-    for (const RelocationRef &Reloc : SI->relocations()) {
-      (void)Reloc;
-      StubBufSize += StubSize;
-    }
+    for (const RelocationRef &Reloc : SI->relocations())
+      if (relocationNeedsStub(Reloc))
+        StubBufSize += StubSize;
   }
 
   // Get section data size and alignment
   }
 
   // Get section data size and alignment
index fea9b96dce06a2e9506d540c4ea732adc178ee50..6f8cb1086f6d218c27a649ec4c5659032786e804 100644 (file)
@@ -1851,4 +1851,23 @@ bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const {
   return Obj.isELF();
 }
 
   return Obj.isELF();
 }
 
+bool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const {
+  if (Arch != Triple::x86_64)
+    return true;  // Conservative answer
+
+  switch (R.getType()) {
+  default:
+    return true;  // Conservative answer
+
+
+  case ELF::R_X86_64_GOTPCREL:
+  case ELF::R_X86_64_PC32:
+  case ELF::R_X86_64_PC64:
+  case ELF::R_X86_64_64:
+    // We know that these reloation types won't need a stub function.  This list
+    // can be extended as needed.
+    return false;
+  }
+}
+
 } // namespace llvm
 } // namespace llvm
index 22f021401d2dfb8d1a8a4911fa460a41fd7f580d..041811d3e285d3023e2106a5d3ae75fe9499c51e 100644 (file)
@@ -152,6 +152,8 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
   SmallVector<SID, 2> UnregisteredEHFrameSections;
   SmallVector<SID, 2> RegisteredEHFrameSections;
 
   SmallVector<SID, 2> UnregisteredEHFrameSections;
   SmallVector<SID, 2> RegisteredEHFrameSections;
 
+  bool relocationNeedsStub(const RelocationRef &R) const override;
+
 public:
   RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
                  RuntimeDyld::SymbolResolver &Resolver);
 public:
   RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
                  RuntimeDyld::SymbolResolver &Resolver);
index 6838648b89454ab797e4e037543f19279b9b9562..2bb6decac0270b29fbcc4737ee2366aeaef0ac45 100644 (file)
@@ -416,6 +416,11 @@ protected:
   // \brief Implementation of the generic part of the loadObject algorithm.
   ObjSectionToIDMap loadObjectImpl(const object::ObjectFile &Obj);
 
   // \brief Implementation of the generic part of the loadObject algorithm.
   ObjSectionToIDMap loadObjectImpl(const object::ObjectFile &Obj);
 
+  // \brief Return true if the relocation R may require allocating a stub.
+  virtual bool relocationNeedsStub(const RelocationRef &R) const {
+    return true;    // Conservative answer
+  }
+
 public:
   RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr,
                   RuntimeDyld::SymbolResolver &Resolver)
 public:
   RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr,
                   RuntimeDyld::SymbolResolver &Resolver)
diff --git a/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s b/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s
new file mode 100644 (file)
index 0000000..8bcba2c
--- /dev/null
@@ -0,0 +1,26 @@
+# RUN: llvm-mc -triple=x86_64-apple-macosx10.10.0 -filetype=obj -o %T/test_ELF_x86_64_StubBuf.o %s
+# RUN: llvm-rtdyld -print-alloc-requests -triple=x86_64-pc-linux -dummy-extern _g=196608 -verify %T/test_ELF_x86_64_StubBuf.o
+
+# Compiled from Inputs/ELF/ELF_x86_64_StubBuf.ll
+
+# CHECK: allocateCodeSection(Size = 42, Alignment = 16, SectionName = __text)
+
+       .section        __TEXT,__text,regular,pure_instructions
+       .macosx_version_min 10, 10
+       .globl  _f
+       .align  4, 0x90
+_f:                                     ## @f
+       .cfi_startproc
+## BB#0:                                ## %entry
+       pushq   %rax
+Ltmp0:
+       .cfi_def_cfa_offset 16
+       callq   _g
+       callq   _g
+       callq   _g
+       popq    %rax
+       retq
+       .cfi_endproc
+
+
+.subsections_via_symbols
diff --git a/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll b/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll
new file mode 100644 (file)
index 0000000..625b487
--- /dev/null
@@ -0,0 +1,12 @@
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+declare void @g()
+
+define void @f() {
+ entry:
+  call void @g()
+  call void @g()
+  call void @g()
+  ret void
+}
index 385cd1bd5caeebe8d148f1ce100c9e298888f7c3..59c9a0c990f335dbe28b3bb9c6eb061a6a2db0d6 100644 (file)
@@ -132,6 +132,12 @@ DummySymbolMappings("dummy-extern",
                     cl::ZeroOrMore,
                     cl::Hidden);
 
                     cl::ZeroOrMore,
                     cl::Hidden);
 
+static cl::opt<bool>
+PrintAllocationRequests("print-alloc-requests",
+                        cl::desc("Print allocation requests made to the memory "
+                                 "manager by RuntimeDyld"),
+                        cl::Hidden);
+
 /* *** */
 
 // A trivial memory manager that doesn't do anything fancy, just uses the
 /* *** */
 
 // A trivial memory manager that doesn't do anything fancy, just uses the
@@ -211,6 +217,10 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
                                                    unsigned Alignment,
                                                    unsigned SectionID,
                                                    StringRef SectionName) {
                                                    unsigned Alignment,
                                                    unsigned SectionID,
                                                    StringRef SectionName) {
+  if (PrintAllocationRequests)
+    outs() << "allocateCodeSection(Size = " << Size << ", Alignment = "
+           << Alignment << ", SectionName = " << SectionName << ")\n";
+
   if (UsePreallocation)
     return allocateFromSlab(Size, Alignment, true /* isCode */);
 
   if (UsePreallocation)
     return allocateFromSlab(Size, Alignment, true /* isCode */);
 
@@ -227,6 +237,10 @@ uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
                                                    unsigned SectionID,
                                                    StringRef SectionName,
                                                    bool IsReadOnly) {
                                                    unsigned SectionID,
                                                    StringRef SectionName,
                                                    bool IsReadOnly) {
+  if (PrintAllocationRequests)
+    outs() << "allocateDataSection(Size = " << Size << ", Alignment = "
+           << Alignment << ", SectionName = " << SectionName << ")\n";
+
   if (UsePreallocation)
     return allocateFromSlab(Size, Alignment, false /* isCode */);
 
   if (UsePreallocation)
     return allocateFromSlab(Size, Alignment, false /* isCode */);