From 96ddcceb80cd68f74b9cda89f043b7c08784a26b Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Mon, 23 Nov 2015 21:47:51 +0000 Subject: [PATCH] [RuntimeDyld] Don't allocate unnecessary stub buffer space 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 --- .../RuntimeDyld/RuntimeDyld.cpp | 7 +++-- .../RuntimeDyld/RuntimeDyldELF.cpp | 19 ++++++++++++++ .../RuntimeDyld/RuntimeDyldELF.h | 2 ++ .../RuntimeDyld/RuntimeDyldImpl.h | 5 ++++ .../RuntimeDyld/X86/ELF_x86_64_StubBuf.s | 26 +++++++++++++++++++ .../X86/Inputs/ELF_x86_64_StubBuf.ll | 12 +++++++++ tools/llvm-rtdyld/llvm-rtdyld.cpp | 14 ++++++++++ 7 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s create mode 100644 test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 93de920209c..dd02ece3a9f 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -432,10 +432,9 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj, 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 diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index fea9b96dce0..6f8cb1086f6 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -1851,4 +1851,23 @@ bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const { 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 diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index 22f021401d2..041811d3e28 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -152,6 +152,8 @@ class RuntimeDyldELF : public RuntimeDyldImpl { SmallVector UnregisteredEHFrameSections; SmallVector RegisteredEHFrameSections; + bool relocationNeedsStub(const RelocationRef &R) const override; + public: RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver); diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 6838648b894..2bb6decac02 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -416,6 +416,11 @@ protected: // \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) 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 index 00000000000..8bcba2c4bac --- /dev/null +++ b/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s @@ -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 index 00000000000..625b487b8af --- /dev/null +++ b/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll @@ -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 +} diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index 385cd1bd5ca..59c9a0c990f 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -132,6 +132,12 @@ DummySymbolMappings("dummy-extern", cl::ZeroOrMore, cl::Hidden); +static cl::opt +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 @@ -211,6 +217,10 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, 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 */); @@ -227,6 +237,10 @@ uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, 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 */); -- 2.34.1