From: Rui Ueyama Date: Thu, 29 Jan 2015 22:12:50 +0000 (+0000) Subject: PECOFF: Do not use LayoutPass and instead use simpler one. X-Git-Tag: llvmorg-3.7.0-rc1~13685 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c4038ab5bf3ee228a2bb0d3e1b2940e7c3318a0c;p=platform%2Fupstream%2Fllvm.git 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. llvm-svn: 227500 --- diff --git a/lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h b/lld/lib/ReaderWriter/PECOFF/OrderPass.h similarity index 51% rename from lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h rename to lld/lib/ReaderWriter/PECOFF/OrderPass.h index ab902ef..8f8b408 100644 --- a/lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h +++ b/lld/lib/ReaderWriter/PECOFF/OrderPass.h @@ -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 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 &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); } }; diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp index b115969..a139e95 100644 --- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp @@ -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(PassManager &pm) { pm.add(std::unique_ptr(new pecoff::PDBPass(*this))); pm.add(std::unique_ptr(new pecoff::EdataPass(*this))); pm.add(std::unique_ptr(new pecoff::IdataPass(*this))); - pm.add(std::unique_ptr(new LayoutPass(registry()))); + pm.add(std::unique_ptr(new pecoff::OrderPass())); pm.add(std::unique_ptr(new pecoff::LoadConfigPass(*this))); - pm.add(std::unique_ptr(new pecoff::GroupedSectionsPass())); pm.add(std::unique_ptr(new pecoff::InferSubsystemPass(*this))); } diff --git a/lld/test/pecoff/entry.test b/lld/test/pecoff/entry.test index b48e5a0..c833843 100644 --- a/lld/test/pecoff/entry.test +++ b/lld/test/pecoff/entry.test @@ -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 diff --git a/lld/test/pecoff/merge-largest.test b/lld/test/pecoff/merge-largest.test index 9273cf0..c3ee96c 100644 --- a/lld/test/pecoff/merge-largest.test +++ b/lld/test/pecoff/merge-largest.test @@ -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