[lld] r227500 - PECOFF: Do not use LayoutPass and instead use simpler one.

Rui Ueyama ruiu at google.com
Thu Jan 29 14:12:51 PST 2015


Author: ruiu
Date: Thu Jan 29 16:12:50 2015
New Revision: 227500

URL: http://llvm.org/viewvc/llvm-project?rev=227500&view=rev
Log:
PECOFF: Do not use LayoutPass and instead use simpler one.

The LayoutPass is one of the slowest pass. This change is to skip
that pass. This change not only improve performance but also improve
maintainability of the code because the LayoutPass is pretty complex.

Previously we used the LayoutPass to sort all atoms in a specific way,
and reorder them again for PE/COFF in GroupedSectionPass.

I spent time on improving and fixing bugs in the LayoutPass (e.g.
r193029), but the pass is still hard to understand and hard to use.
It's better not to depend on that if we don't need. For PE/COFF, we
just wanted to sort atoms in the same order as the file order in the
command line.

The feature we used in the LayoutPass is now simplified to
compareByPosition function in OrderPass.cpp. The function is just 5
lines.

This patch changes the order of final output because it changes the
sort order a bit. The output is still correct, though.

Added:
    lld/trunk/lib/ReaderWriter/PECOFF/OrderPass.h
      - copied, changed from r227410, lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h
Removed:
    lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h
Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/test/pecoff/entry.test
    lld/trunk/test/pecoff/merge-largest.test

Removed: lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h?rev=227499&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h (removed)
@@ -1,59 +0,0 @@
-//===- lib/ReaderWriter/PECOFF/GroupedSectionsPass.h ----------------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file \brief This pass sorts atoms by section name, so that they will appear
-/// in the correct order in the output.
-///
-/// In COFF, sections will be merged into one section by the linker if their
-/// names are the same after discarding the "$" character and all characters
-/// follow it from their names. The characters following the "$" character
-/// determines the merge order. Assume there's an object file containing four
-/// data sections in the following order.
-///
-///   - .data$2
-///   - .data$3
-///   - .data$1
-///   - .data
-///
-/// In this case, the resulting binary should have ".data" section with the
-/// contents of ".data", ".data$1", ".data$2" and ".data$3" in that order.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_READER_WRITER_PE_COFF_GROUPED_SECTIONS_PASS_H
-#define LLD_READER_WRITER_PE_COFF_GROUPED_SECTIONS_PASS_H
-
-#include "Atoms.h"
-#include "lld/Core/Pass.h"
-#include <algorithm>
-
-namespace lld {
-namespace pecoff {
-
-static bool compare(const DefinedAtom *left, const DefinedAtom *right) {
-  if (left->sectionChoice() == DefinedAtom::sectionCustomRequired &&
-      right->sectionChoice() == DefinedAtom::sectionCustomRequired) {
-    return left->customSectionName().compare(right->customSectionName()) < 0;
-  }
-  return left->sectionChoice() == DefinedAtom::sectionCustomRequired &&
-         right->sectionChoice() != DefinedAtom::sectionCustomRequired;
-}
-
-class GroupedSectionsPass : public lld::Pass {
-public:
-  void perform(std::unique_ptr<MutableFile> &file) override {
-    auto definedAtoms = file->definedAtoms();
-    std::stable_sort(definedAtoms.begin(), definedAtoms.end(), compare);
-  }
-};
-
-} // namespace pecoff
-} // namespace lld
-
-#endif

Copied: lld/trunk/lib/ReaderWriter/PECOFF/OrderPass.h (from r227410, lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/OrderPass.h?p2=lld/trunk/lib/ReaderWriter/PECOFF/OrderPass.h&p1=lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h&r1=227410&r2=227500&rev=227500&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/OrderPass.h Thu Jan 29 16:12:50 2015
@@ -1,4 +1,4 @@
-//===- lib/ReaderWriter/PECOFF/GroupedSectionsPass.h ----------------------===//
+//===- lib/ReaderWriter/PECOFF/OrderPass.h -------------------------------===//
 //
 //                             The LLVM Linker
 //
@@ -26,30 +26,46 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLD_READER_WRITER_PE_COFF_GROUPED_SECTIONS_PASS_H
-#define LLD_READER_WRITER_PE_COFF_GROUPED_SECTIONS_PASS_H
+#ifndef LLD_READER_WRITER_PE_COFF_ORDER_PASS_H
+#define LLD_READER_WRITER_PE_COFF_ORDER_PASS_H
 
 #include "Atoms.h"
+#include "lld/Core/Parallel.h"
 #include "lld/Core/Pass.h"
 #include <algorithm>
 
 namespace lld {
 namespace pecoff {
 
-static bool compare(const DefinedAtom *left, const DefinedAtom *right) {
-  if (left->sectionChoice() == DefinedAtom::sectionCustomRequired &&
-      right->sectionChoice() == DefinedAtom::sectionCustomRequired) {
-    return left->customSectionName().compare(right->customSectionName()) < 0;
+static bool compareByPosition(const DefinedAtom *lhs, const DefinedAtom *rhs) {
+  const File *lhsFile = &lhs->file();
+  const File *rhsFile = &rhs->file();
+  if (lhsFile->ordinal() != rhsFile->ordinal())
+    return lhsFile->ordinal() < rhsFile->ordinal();
+  return lhs->ordinal() < rhs->ordinal();
+}
+
+static bool compare(const DefinedAtom *lhs, const DefinedAtom *rhs) {
+  bool lhsCustom = (lhs->sectionChoice() == DefinedAtom::sectionCustomRequired);
+  bool rhsCustom = (rhs->sectionChoice() == DefinedAtom::sectionCustomRequired);
+  if (lhsCustom && rhsCustom) {
+    int cmp = lhs->customSectionName().compare(rhs->customSectionName());
+    if (cmp != 0)
+      return cmp < 0;
+    return compareByPosition(lhs, rhs);
   }
-  return left->sectionChoice() == DefinedAtom::sectionCustomRequired &&
-         right->sectionChoice() != DefinedAtom::sectionCustomRequired;
+  if (lhsCustom && !rhsCustom)
+    return true;
+  if (!lhsCustom && rhsCustom)
+    return false;
+  return compareByPosition(lhs, rhs);
 }
 
-class GroupedSectionsPass : public lld::Pass {
+class OrderPass : public lld::Pass {
 public:
   void perform(std::unique_ptr<MutableFile> &file) override {
-    auto definedAtoms = file->definedAtoms();
-    std::stable_sort(definedAtoms.begin(), definedAtoms.end(), compare);
+    MutableFile::DefinedAtomRange defined = file->definedAtoms();
+    parallel_sort(defined.begin(), defined.end(), compare);
   }
 };
 

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=227500&r1=227499&r2=227500&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Thu Jan 29 16:12:50 2015
@@ -9,11 +9,11 @@
 
 #include "Atoms.h"
 #include "EdataPass.h"
-#include "GroupedSectionsPass.h"
 #include "IdataPass.h"
 #include "InferSubsystemPass.h"
 #include "LinkerGeneratedSymbolFile.h"
 #include "LoadConfigPass.h"
+#include "OrderPass.h"
 #include "PDBPass.h"
 #include "lld/Core/PassManager.h"
 #include "lld/Core/Reader.h"
@@ -351,9 +351,8 @@ void PECOFFLinkingContext::addPasses(Pas
   pm.add(std::unique_ptr<Pass>(new pecoff::PDBPass(*this)));
   pm.add(std::unique_ptr<Pass>(new pecoff::EdataPass(*this)));
   pm.add(std::unique_ptr<Pass>(new pecoff::IdataPass(*this)));
-  pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
+  pm.add(std::unique_ptr<Pass>(new pecoff::OrderPass()));
   pm.add(std::unique_ptr<Pass>(new pecoff::LoadConfigPass(*this)));
-  pm.add(std::unique_ptr<Pass>(new pecoff::GroupedSectionsPass()));
   pm.add(std::unique_ptr<Pass>(new pecoff::InferSubsystemPass(*this)));
 }
 

Modified: lld/trunk/test/pecoff/entry.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/entry.test?rev=227500&r1=227499&r2=227500&view=diff
==============================================================================
--- lld/trunk/test/pecoff/entry.test (original)
+++ lld/trunk/test/pecoff/entry.test Thu Jan 29 16:12:50 2015
@@ -33,7 +33,7 @@ WWINMAIN: _wWinMainCRTStartup
 # RUN:   /alternatename:_mainCRTStartup=_bar -- %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAINADDR %s
 
-MAINADDR: AddressOfEntryPoint: 0x1004
+MAINADDR: AddressOfEntryPoint: 0x100C
 
 # RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:baz -- %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MANGLE %s

Modified: lld/trunk/test/pecoff/merge-largest.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/merge-largest.test?rev=227500&r1=227499&r2=227500&view=diff
==============================================================================
--- lld/trunk/test/pecoff/merge-largest.test (original)
+++ lld/trunk/test/pecoff/merge-largest.test Thu Jan 29 16:12:50 2015
@@ -19,6 +19,6 @@ READOBJ-NEXT: Sections [
 READOBJ-NEXT:   Section {
 READOBJ-NEXT:     Number: 1
 READOBJ-NEXT:     Name: .text (2E 74 65 78 74 00 00 00)
-READOBJ-NEXT:     VirtualSize: 0x12
+READOBJ-NEXT:     VirtualSize: 0x8
 READOBJ-NEXT:     VirtualAddress: 0x1000
 READOBJ-NEXT:     RawDataSize: 512





More information about the llvm-commits mailing list