[lld] 7599e98 - [lld-macho][nfc] Remove unnecessary parameterization of section sort

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Tue May 25 11:58:47 PDT 2021


Author: Jez Ng
Date: 2021-05-25T14:58:30-04:00
New Revision: 7599e98ab7904dce34ea208009f00e87d9d965fb

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

LOG: [lld-macho][nfc] Remove unnecessary parameterization of section sort

As @alexshap pointed out [here](https://reviews.llvm.org/D102972#inline-975208),
it's a bit confusing to have the option to sort OutputSections with any
comparator when in practice we only use one.

Reviewed By: #lld-macho, alexshap, thakis

Differential Revision: https://reviews.llvm.org/D102974

Added: 
    

Modified: 
    lld/MachO/OutputSegment.cpp
    lld/MachO/OutputSegment.h
    lld/MachO/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
index 3989d83d2a24..fda47ed3942f 100644
--- a/lld/MachO/OutputSegment.cpp
+++ b/lld/MachO/OutputSegment.cpp
@@ -13,6 +13,7 @@
 
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/BinaryFormat/MachO.h"
 
 using namespace llvm;
@@ -60,6 +61,87 @@ void OutputSegment::addOutputSection(OutputSection *osec) {
       osec->align = sectAlign.align;
 }
 
+template <typename T, typename F> static auto compareByOrder(F ord) {
+  return [=](T a, T b) { return ord(a) < ord(b); };
+}
+
+static int segmentOrder(OutputSegment *seg) {
+  return StringSwitch<int>(seg->name)
+      .Case(segment_names::pageZero, -4)
+      .Case(segment_names::text, -3)
+      .Case(segment_names::dataConst, -2)
+      .Case(segment_names::data, -1)
+      .Case(segment_names::llvm, std::numeric_limits<int>::max() - 1)
+      // Make sure __LINKEDIT is the last segment (i.e. all its hidden
+      // sections must be ordered after other sections).
+      .Case(segment_names::linkEdit, std::numeric_limits<int>::max())
+      .Default(seg->inputOrder);
+}
+
+static int sectionOrder(OutputSection *osec) {
+  StringRef segname = osec->parent->name;
+  // Sections are uniquely identified by their segment + section name.
+  if (segname == segment_names::text) {
+    return StringSwitch<int>(osec->name)
+        .Case(section_names::header, -4)
+        .Case(section_names::text, -3)
+        .Case(section_names::stubs, -2)
+        .Case(section_names::stubHelper, -1)
+        .Case(section_names::unwindInfo, std::numeric_limits<int>::max() - 1)
+        .Case(section_names::ehFrame, std::numeric_limits<int>::max())
+        .Default(osec->inputOrder);
+  } else if (segname == segment_names::data ||
+             segname == segment_names::dataConst) {
+    // For each thread spawned, dyld will initialize its TLVs by copying the
+    // address range from the start of the first thread-local data section to
+    // the end of the last one. We therefore arrange these sections contiguously
+    // to minimize the amount of memory used. Additionally, since zerofill
+    // sections must be at the end of their segments, and since TLV data
+    // sections can be zerofills, we end up putting all TLV data sections at the
+    // end of the segment.
+    switch (sectionType(osec->flags)) {
+    case S_THREAD_LOCAL_REGULAR:
+      return std::numeric_limits<int>::max() - 2;
+    case S_THREAD_LOCAL_ZEROFILL:
+      return std::numeric_limits<int>::max() - 1;
+    case S_ZEROFILL:
+      return std::numeric_limits<int>::max();
+    default:
+      return StringSwitch<int>(osec->name)
+          .Case(section_names::got, -3)
+          .Case(section_names::lazySymbolPtr, -2)
+          .Case(section_names::const_, -1)
+          .Default(osec->inputOrder);
+    }
+  } else if (segname == segment_names::linkEdit) {
+    return StringSwitch<int>(osec->name)
+        .Case(section_names::rebase, -9)
+        .Case(section_names::binding, -8)
+        .Case(section_names::weakBinding, -7)
+        .Case(section_names::lazyBinding, -6)
+        .Case(section_names::export_, -5)
+        .Case(section_names::functionStarts, -4)
+        .Case(section_names::symbolTable, -3)
+        .Case(section_names::indirectSymbolTable, -2)
+        .Case(section_names::stringTable, -1)
+        .Case(section_names::codeSignature, std::numeric_limits<int>::max())
+        .Default(osec->inputOrder);
+  }
+  // ZeroFill sections must always be the at the end of their segments,
+  // otherwise subsequent sections may get overwritten with zeroes at runtime.
+  if (sectionType(osec->flags) == S_ZEROFILL)
+    return std::numeric_limits<int>::max();
+  return osec->inputOrder;
+}
+
+void OutputSegment::sortOutputSections() {
+  llvm::sort(sections, compareByOrder<OutputSection *>(sectionOrder));
+}
+
+void macho::sortOutputSegments() {
+  llvm::sort(outputSegments, compareByOrder<OutputSegment *>(segmentOrder));
+}
+
 static DenseMap<StringRef, OutputSegment *> nameToOutputSegment;
 std::vector<OutputSegment *> macho::outputSegments;
 

diff  --git a/lld/MachO/OutputSegment.h b/lld/MachO/OutputSegment.h
index 80d2d73794b2..e5d87ba0a4e0 100644
--- a/lld/MachO/OutputSegment.h
+++ b/lld/MachO/OutputSegment.h
@@ -42,10 +42,7 @@ class OutputSegment {
   const OutputSection *lastSection() const { return sections.back(); }
 
   void addOutputSection(OutputSection *os);
-  void sortOutputSections(
-      llvm::function_ref<bool(OutputSection *, OutputSection *)> comparator) {
-    llvm::sort(sections, comparator);
-  }
+  void sortOutputSections();
 
   const std::vector<OutputSection *> &getSections() const { return sections; }
   size_t numNonHiddenSections() const;
@@ -65,6 +62,8 @@ class OutputSegment {
 
 extern std::vector<OutputSegment *> outputSegments;
 
+void sortOutputSegments();
+
 OutputSegment *getOrCreateOutputSegment(StringRef name);
 
 } // namespace macho

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 3dcf360bf6e5..aa5f60ff57d0 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -755,94 +755,19 @@ static DenseMap<const InputSection *, size_t> buildInputSectionPriorities() {
   return sectionPriorities;
 }
 
-static int segmentOrder(OutputSegment *seg) {
-  return StringSwitch<int>(seg->name)
-      .Case(segment_names::pageZero, -4)
-      .Case(segment_names::text, -3)
-      .Case(segment_names::dataConst, -2)
-      .Case(segment_names::data, -1)
-      .Case(segment_names::llvm, std::numeric_limits<int>::max() - 1)
-      // Make sure __LINKEDIT is the last segment (i.e. all its hidden
-      // sections must be ordered after other sections).
-      .Case(segment_names::linkEdit, std::numeric_limits<int>::max())
-      .Default(seg->inputOrder);
-}
-
-static int sectionOrder(OutputSection *osec) {
-  StringRef segname = osec->parent->name;
-  // Sections are uniquely identified by their segment + section name.
-  if (segname == segment_names::text) {
-    return StringSwitch<int>(osec->name)
-        .Case(section_names::header, -4)
-        .Case(section_names::text, -3)
-        .Case(section_names::stubs, -2)
-        .Case(section_names::stubHelper, -1)
-        .Case(section_names::unwindInfo, std::numeric_limits<int>::max() - 1)
-        .Case(section_names::ehFrame, std::numeric_limits<int>::max())
-        .Default(osec->inputOrder);
-  } else if (segname == segment_names::data ||
-             segname == segment_names::dataConst) {
-    // For each thread spawned, dyld will initialize its TLVs by copying the
-    // address range from the start of the first thread-local data section to
-    // the end of the last one. We therefore arrange these sections contiguously
-    // to minimize the amount of memory used. Additionally, since zerofill
-    // sections must be at the end of their segments, and since TLV data
-    // sections can be zerofills, we end up putting all TLV data sections at the
-    // end of the segment.
-    switch (sectionType(osec->flags)) {
-    case S_THREAD_LOCAL_REGULAR:
-      return std::numeric_limits<int>::max() - 2;
-    case S_THREAD_LOCAL_ZEROFILL:
-      return std::numeric_limits<int>::max() - 1;
-    case S_ZEROFILL:
-      return std::numeric_limits<int>::max();
-    default:
-      return StringSwitch<int>(osec->name)
-          .Case(section_names::got, -3)
-          .Case(section_names::lazySymbolPtr, -2)
-          .Case(section_names::const_, -1)
-          .Default(osec->inputOrder);
-    }
-  } else if (segname == segment_names::linkEdit) {
-    return StringSwitch<int>(osec->name)
-        .Case(section_names::rebase, -9)
-        .Case(section_names::binding, -8)
-        .Case(section_names::weakBinding, -7)
-        .Case(section_names::lazyBinding, -6)
-        .Case(section_names::export_, -5)
-        .Case(section_names::functionStarts, -4)
-        .Case(section_names::symbolTable, -3)
-        .Case(section_names::indirectSymbolTable, -2)
-        .Case(section_names::stringTable, -1)
-        .Case(section_names::codeSignature, std::numeric_limits<int>::max())
-        .Default(osec->inputOrder);
-  }
-  // ZeroFill sections must always be the at the end of their segments,
-  // otherwise subsequent sections may get overwritten with zeroes at runtime.
-  if (sectionType(osec->flags) == S_ZEROFILL)
-    return std::numeric_limits<int>::max();
-  return osec->inputOrder;
-}
-
-template <typename T, typename F>
-static std::function<bool(T, T)> compareByOrder(F ord) {
-  return [=](T a, T b) { return ord(a) < ord(b); };
-}
-
 // Sorting only can happen once all outputs have been collected. Here we sort
 // segments, output sections within each segment, and input sections within each
 // output segment.
 static void sortSegmentsAndSections() {
   TimeTraceScope timeScope("Sort segments and sections");
-
-  llvm::sort(outputSegments, compareByOrder<OutputSegment *>(segmentOrder));
+  sortOutputSegments();
 
   DenseMap<const InputSection *, size_t> isecPriorities =
       buildInputSectionPriorities();
 
   uint32_t sectionIndex = 0;
   for (OutputSegment *seg : outputSegments) {
-    seg->sortOutputSections(compareByOrder<OutputSection *>(sectionOrder));
+    seg->sortOutputSections();
     for (OutputSection *osec : seg->getSections()) {
       // Now that the output sections are sorted, assign the final
       // output section indices.


        


More information about the llvm-commits mailing list