[lld] 099a52f - [ELF] Reorder SectionBase/InputSectionBase members

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 23 16:34:27 PST 2024


Author: Fangrui Song
Date: 2024-11-23T16:34:21-08:00
New Revision: 099a52fd2f3723db6b0550c99a1adc12d2d8d909

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

LOG: [ELF] Reorder SectionBase/InputSectionBase members

Move `sectionKind` outside the bitfield and move bss/keepUnique to
InputSectionBase.

* sizeof(InputSection) decreases from 160 to 152 on 64-bit systems.
* The numerous `sectionKind` accesses are faster.

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/InputSection.cpp
    lld/ELF/InputSection.h
    lld/ELF/MapFile.cpp
    lld/ELF/SyntheticSections.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 10c52d7206b805..53dc0e0cc62861 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2375,8 +2375,9 @@ static void markAddrsig(bool icfSafe, Symbol *s) {
   // We don't need to keep text sections unique under --icf=all even if they
   // are address-significant.
   if (auto *d = dyn_cast_or_null<Defined>(s))
-    if (d->section && (icfSafe || !(d->section->flags & SHF_EXECINSTR)))
-      d->section->keepUnique = true;
+    if (auto *sec = dyn_cast_or_null<InputSectionBase>(d->section))
+      if (icfSafe || !(sec->flags & SHF_EXECINSTR))
+        sec->keepUnique = true;
 }
 
 // Record sections that define symbols mentioned in --keep-unique <symbol>
@@ -2391,7 +2392,8 @@ static void findKeepUniqueSections(Ctx &ctx, opt::InputArgList &args) {
       Warn(ctx) << "could not find symbol " << name << " to keep unique";
       continue;
     }
-    d->section->keepUnique = true;
+    if (auto *sec = dyn_cast<InputSectionBase>(d->section))
+      sec->keepUnique = true;
   }
 
   // --icf=all --ignore-data-address-equality means that we can ignore

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index c24c3f35ed2c06..0a1b742a4ccfd1 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -59,6 +59,7 @@ InputSectionBase::InputSectionBase(InputFile *file, StringRef name,
                                    Kind sectionKind)
     : SectionBase(sectionKind, file, name, type, flags, link, info, addralign,
                   entsize),
+      bss(0), decodedCrel(0), keepUnique(0), nopFiller(0),
       content_(data.data()), size(data.size()) {
   // In order to reduce memory allocation, we assume that mergeable
   // sections are smaller than 4 GiB, which is not an unreasonable

diff  --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index b14aaef7107677..e3b4b387320588 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -59,25 +59,17 @@ template <class ELFT> struct RelsOrRelas {
 // sections.
 class SectionBase {
 public:
-  enum Kind { Regular, Synthetic, Spill, EHFrame, Merge, Output, Class };
-
-  Kind kind() const { return (Kind)sectionKind; }
-
-  LLVM_PREFERRED_TYPE(Kind)
-  uint8_t sectionKind : 3;
-
-  // The next two bit fields are only used by InputSectionBase, but we
-  // put them here so the struct packs better.
-
-  LLVM_PREFERRED_TYPE(bool)
-  uint8_t bss : 1;
-
-  // Set for sections that should not be folded by ICF.
-  LLVM_PREFERRED_TYPE(bool)
-  uint8_t keepUnique : 1;
+  enum Kind : uint8_t {
+    Regular,
+    Synthetic,
+    Spill,
+    EHFrame,
+    Merge,
+    Output,
+    Class,
+  };
 
-  uint8_t partition = 1;
-  uint32_t type;
+  Kind kind() const { return sectionKind; }
 
   // The file which contains this section. For InputSectionBase, its dynamic
   // type is usually ObjFile<ELFT>, but may be an InputFile of InternalKind
@@ -93,11 +85,18 @@ class SectionBase {
 
   // These corresponds to the fields in Elf_Shdr.
   uint64_t flags;
+  uint32_t type;
   uint32_t link;
   uint32_t info;
   uint32_t addralign;
   uint32_t entsize;
 
+  Kind sectionKind;
+  uint8_t partition = 1;
+
+  // The next two bit fields are only used by InputSectionBase, but we
+  // put them here so the struct packs better.
+
   Ctx &getCtx() const;
   OutputSection *getOutputSection();
   const OutputSection *getOutputSection() const {
@@ -118,9 +117,9 @@ class SectionBase {
   constexpr SectionBase(Kind sectionKind, InputFile *file, StringRef name,
                         uint32_t type, uint64_t flags, uint32_t link,
                         uint32_t info, uint32_t addralign, uint32_t entsize)
-      : sectionKind(sectionKind), bss(false), keepUnique(false), type(type),
-        file(file), name(name), flags(flags), link(link), info(info),
-        addralign(addralign), entsize(entsize) {}
+      : file(file), name(name), flags(flags), type(type), link(link),
+        info(info), addralign(addralign), entsize(entsize),
+        sectionKind(sectionKind) {}
 };
 
 struct SymbolAnchor {
@@ -157,6 +156,25 @@ class InputSectionBase : public SectionBase {
     return s->kind() != Output && s->kind() != Class;
   }
 
+  LLVM_PREFERRED_TYPE(bool)
+  uint8_t bss : 1;
+
+  // Whether this section is SHT_CREL and has been decoded to RELA by
+  // relsOrRelas.
+  LLVM_PREFERRED_TYPE(bool)
+  uint8_t decodedCrel : 1;
+
+  // Set for sections that should not be folded by ICF.
+  LLVM_PREFERRED_TYPE(bool)
+  uint8_t keepUnique : 1;
+
+  // Whether the section needs to be padded with a NOP filler due to
+  // deleteFallThruJmpInsn.
+  LLVM_PREFERRED_TYPE(bool)
+  uint8_t nopFiller : 1;
+
+  mutable bool compressed = false;
+
   // Input sections are part of an output section. Special sections
   // like .eh_frame and merge sections are first combined into a
   // synthetic section that is then added to an output section. In all
@@ -176,16 +194,6 @@ class InputSectionBase : public SectionBase {
   // be reset to zero after uses.
   uint32_t bytesDropped = 0;
 
-  mutable bool compressed = false;
-
-  // Whether this section is SHT_CREL and has been decoded to RELA by
-  // relsOrRelas.
-  bool decodedCrel = false;
-
-  // Whether the section needs to be padded with a NOP filler due to
-  // deleteFallThruJmpInsn.
-  bool nopFiller = false;
-
   void drop_back(unsigned num) {
     assert(bytesDropped + num < 256);
     bytesDropped += num;
@@ -467,7 +475,7 @@ class PotentialSpillSection : public InputSection {
   }
 };
 
-static_assert(sizeof(InputSection) <= 160, "InputSection is too big");
+static_assert(sizeof(InputSection) <= 152, "InputSection is too big");
 
 class SyntheticSection : public InputSection {
 public:

diff  --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index f18d799a8c4e4b..138d35951a3bbc 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -59,7 +59,9 @@ static std::vector<Defined *> getSymbols(Ctx &ctx) {
     for (Symbol *b : file->getSymbols())
       if (auto *dr = dyn_cast<Defined>(b))
         if (!dr->isSection() && dr->section && dr->section->isLive() &&
-            (dr->file == file || dr->hasFlag(NEEDS_COPY) || dr->section->bss))
+            (dr->file == file || dr->hasFlag(NEEDS_COPY) ||
+             (isa<SyntheticSection>(dr->section) &&
+              cast<SyntheticSection>(dr->section)->bss)))
           v.push_back(dr);
   return v;
 }

diff  --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index f2dde20f7e41fa..4b643e86335510 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -177,7 +177,9 @@ class BssSection final : public SyntheticSection {
   bool isNeeded() const override { return size != 0; }
   size_t getSize() const override { return size; }
 
-  static bool classof(const SectionBase *s) { return s->bss; }
+  static bool classof(const SectionBase *s) {
+    return isa<SyntheticSection>(s) && cast<SyntheticSection>(s)->bss;
+  }
   uint64_t size;
 };
 


        


More information about the llvm-commits mailing list