[lld] e90c8c0 - [ELF] Optimize basic block section bytesDropped/jumpInstrMods

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 26 22:17:34 PST 2021


Author: Fangrui Song
Date: 2021-12-26T22:17:30-08:00
New Revision: e90c8c042214c1cfacd3ffc38ad2927390cb6fe1

URL: https://github.com/llvm/llvm-project/commit/e90c8c042214c1cfacd3ffc38ad2927390cb6fe1
DIFF: https://github.com/llvm/llvm-project/commit/e90c8c042214c1cfacd3ffc38ad2927390cb6fe1.diff

LOG: [ELF] Optimize basic block section bytesDropped/jumpInstrMods

and make them more space efficient. This decreases sizeof(InputSection) from 176
to 160, and decreases peak memory usage by 0.3% when linking Chrome.

Added: 
    

Modified: 
    lld/ELF/Arch/X86_64.cpp
    lld/ELF/InputSection.cpp
    lld/ELF/InputSection.h
    lld/ELF/Relocations.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 614b5ed592189..08591d8e5f06b 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -304,7 +304,8 @@ bool X86_64::deleteFallThruJmpInsn(InputSection &is, InputFile *file,
   JmpInsnOpcode jInvert = invertJmpOpcode(jmpOpcodeB);
   if (jInvert == J_UNKNOWN)
     return false;
-  is.jumpInstrMods.push_back({jInvert, (rB.offset - 1), 4});
+  is.jumpInstrMod = make<JumpInstrMod>();
+  *is.jumpInstrMod = {rB.offset - 1, jInvert, 4};
   // Move R's values to rB except the offset.
   rB = {r.expr, r.type, rB.offset, r.addend, r.sym};
   // Cancel R

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 9a2b52cf568d5..844388330d6fa 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -1106,12 +1106,9 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
   // a jmp insn must be modified to shrink the jmp insn or to flip the jmp
   // insn.  This is primarily used to relax and optimize jumps created with
   // basic block sections.
-  if (isa<InputSection>(this)) {
-    for (const JumpInstrMod &jumpMod : jumpInstrMods) {
-      uint64_t offset = jumpMod.offset;
-      uint8_t *bufLoc = buf + offset;
-      target.applyJumpInstrMod(bufLoc, jumpMod.original, jumpMod.size);
-    }
+  if (jumpInstrMod) {
+    target.applyJumpInstrMod(buf + jumpInstrMod->offset, jumpInstrMod->original,
+                             jumpInstrMod->size);
   }
 }
 

diff  --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 3bd180be7d43e..32c9ed26c1fd7 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -130,13 +130,16 @@ class InputSectionBase : public SectionBase {
   // one or two jump instructions at the end that could be relaxed to a smaller
   // instruction. The members below help trimming the trailing jump instruction
   // and shrinking a section.
-  unsigned bytesDropped = 0;
+  uint8_t bytesDropped = 0;
 
   // Whether the section needs to be padded with a NOP filler due to
   // deleteFallThruJmpInsn.
   bool nopFiller = false;
 
-  void drop_back(uint64_t num) { bytesDropped += num; }
+  void drop_back(unsigned num) {
+    assert(bytesDropped + num < 256);
+    bytesDropped += num;
+  }
 
   void push_back(uint64_t num) {
     assert(bytesDropped >= num);
@@ -203,7 +206,7 @@ class InputSectionBase : public SectionBase {
   // block sections are enabled.  Basic block sections creates opportunities to
   // relax jump instructions at basic block boundaries after reordering the
   // basic blocks.
-  SmallVector<JumpInstrMod, 0> jumpInstrMods;
+  JumpInstrMod *jumpInstrMod = nullptr;
 
   // A function compiled with -fsplit-stack calling a function
   // compiled without -fsplit-stack needs its prologue adjusted. Find
@@ -377,9 +380,9 @@ class InputSection : public InputSectionBase {
 };
 
 #ifdef _WIN32
-static_assert(sizeof(InputSection) <= 184, "InputSection is too big");
+static_assert(sizeof(InputSection) <= 168, "InputSection is too big");
 #else
-static_assert(sizeof(InputSection) <= 176, "InputSection is too big");
+static_assert(sizeof(InputSection) <= 160, "InputSection is too big");
 #endif
 
 inline bool isDebugSection(const InputSectionBase &sec) {

diff  --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index c652c0a5f70fc..f9909f236d12e 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -117,8 +117,8 @@ struct Relocation {
 // jump instruction opcodes at basic block boundaries and are particularly
 // useful when basic block sections are enabled.
 struct JumpInstrMod {
-  JumpModType original;
   uint64_t offset;
+  JumpModType original;
   unsigned size;
 };
 


        


More information about the llvm-commits mailing list