From 97b2b0636bc1019f8987ddc53b97d33070f25255 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea Date: Wed, 27 Feb 2019 20:53:50 +0000 Subject: [PATCH] [LLD][COFF] Support /threads[:no] like the ELF driver Differential review: https://reviews.llvm.org/D58594 llvm-svn: 355029 --- lld/COFF/Driver.cpp | 3 +++ lld/COFF/MapFile.cpp | 4 ++-- lld/COFF/Options.td | 3 +++ lld/COFF/PDB.cpp | 9 ++++----- lld/COFF/Writer.cpp | 17 +++++++++-------- lld/include/lld/Common/Threads.h | 7 +++++++ lld/test/COFF/pdb-globals.test | 5 +++++ 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 6266ed6..564f6c1 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -19,6 +19,7 @@ #include "lld/Common/Driver.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" +#include "lld/Common/Threads.h" #include "lld/Common/Timer.h" #include "lld/Common/Version.h" #include "llvm/ADT/Optional.h" @@ -987,6 +988,8 @@ void LinkerDriver::link(ArrayRef ArgsArr) { return; } + lld::ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_threads_no, true); + if (Args.hasArg(OPT_show_timing)) Config->ShowTiming = true; diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp index f8cdcc1..5e1a3d0 100644 --- a/lld/COFF/MapFile.cpp +++ b/lld/COFF/MapFile.cpp @@ -23,7 +23,7 @@ #include "Symbols.h" #include "Writer.h" #include "lld/Common/ErrorHandler.h" -#include "llvm/Support/Parallel.h" +#include "lld/Common/Threads.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -75,7 +75,7 @@ static SymbolMapTy getSectionSyms(ArrayRef Syms) { static DenseMap getSymbolStrings(ArrayRef Syms) { std::vector Str(Syms.size()); - for_each_n(parallel::par, (size_t)0, Syms.size(), [&](size_t I) { + parallelForEachN((size_t)0, Syms.size(), [&](size_t I) { raw_string_ostream OS(Str[I]); writeHeader(OS, Syms[I]->getRVA(), 0, 0); OS << Indent16 << toString(*Syms[I]); diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index f83e445..08a706a 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -163,6 +163,9 @@ def rsp_quoting : Joined<["--"], "rsp-quoting=">, HelpText<"Quoting style for response files, 'windows' (default) or 'posix'">; def dash_dash_version : Flag<["--"], "version">, HelpText<"Print version information">; +defm threads: B<"threads", + "Run the linker multi-threaded (default)", + "Do not run the linker multi-threaded">; // Flags for debugging def lldmap : F<"lldmap">; diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 8a9c5fe..a49ac51 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -15,6 +15,7 @@ #include "Writer.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Timer.h" +#include "lld/Common/Threads.h" #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" @@ -52,7 +53,6 @@ #include "llvm/Support/Errc.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/JamCRC.h" -#include "llvm/Support/Parallel.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" #include @@ -1340,10 +1340,9 @@ void PDBLinker::addObjectsToPDB() { if (!Publics.empty()) { // Sort the public symbols and add them to the stream. - sort(parallel::par, Publics.begin(), Publics.end(), - [](const PublicSym32 &L, const PublicSym32 &R) { - return L.Name < R.Name; - }); + parallelSort(Publics, [](const PublicSym32 &L, const PublicSym32 &R) { + return L.Name < R.Name; + }); for (const PublicSym32 &Pub : Publics) GsiBuilder.addPublicSymbol(Pub); } diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index d054490..06ede72 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -16,6 +16,7 @@ #include "Symbols.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" +#include "lld/Common/Threads.h" #include "lld/Common/Timer.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -1096,8 +1097,7 @@ void Writer::mergeSections() { // Visits all sections to initialize their relocation targets. void Writer::readRelocTargets() { for (OutputSection *Sec : OutputSections) - for_each(parallel::par, Sec->Chunks.begin(), Sec->Chunks.end(), - [&](Chunk *C) { C->readRelocTargets(); }); + parallelForEach(Sec->Chunks, [&](Chunk *C) { C->readRelocTargets(); }); } // Visits all sections to assign incremental, non-overlapping RVAs and @@ -1613,8 +1613,7 @@ void Writer::writeSections() { // ADD instructions). if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE) memset(SecBuf, 0xCC, Sec->getRawSize()); - for_each(parallel::par, Sec->Chunks.begin(), Sec->Chunks.end(), - [&](Chunk *C) { C->writeTo(SecBuf); }); + parallelForEach(Sec->Chunks, [&](Chunk *C) { C->writeTo(SecBuf); }); } } @@ -1682,14 +1681,16 @@ void Writer::sortExceptionTable() { uint8_t *End = BufAddr(LastPdata) + LastPdata->getSize(); if (Config->Machine == AMD64) { struct Entry { ulittle32_t Begin, End, Unwind; }; - sort(parallel::par, (Entry *)Begin, (Entry *)End, - [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); + parallelSort( + MutableArrayRef((Entry *)Begin, (Entry *)End), + [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); return; } if (Config->Machine == ARMNT || Config->Machine == ARM64) { struct Entry { ulittle32_t Begin, Unwind; }; - sort(parallel::par, (Entry *)Begin, (Entry *)End, - [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); + parallelSort( + MutableArrayRef((Entry *)Begin, (Entry *)End), + [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); return; } errs() << "warning: don't know how to handle .pdata.\n"; diff --git a/lld/include/lld/Common/Threads.h b/lld/include/lld/Common/Threads.h index e356fcd..fba0e93 100644 --- a/lld/include/lld/Common/Threads.h +++ b/lld/include/lld/Common/Threads.h @@ -80,6 +80,13 @@ inline void parallelForEachN(size_t Begin, size_t End, for_each_n(llvm::parallel::seq, Begin, End, Fn); } +template void parallelSort(R &&Range, FuncTy Fn) { + if (ThreadsEnabled) + sort(llvm::parallel::par, std::begin(Range), std::end(Range), Fn); + else + sort(llvm::parallel::seq, std::begin(Range), std::end(Range), Fn); +} + } // namespace lld #endif diff --git a/lld/test/COFF/pdb-globals.test b/lld/test/COFF/pdb-globals.test index ee9c0ef..00909fa 100644 --- a/lld/test/COFF/pdb-globals.test +++ b/lld/test/COFF/pdb-globals.test @@ -2,6 +2,11 @@ RUN: yaml2obj %S/Inputs/pdb-globals.yaml > %t.obj RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s +RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads +RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s +RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads:no +RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s + # Test that we correctly distribute symbols between the globals and module # symbol streams. Specifically: # * S_UDT, S_GDATA32, and S_CONSTANT end up in the globals stream, and are -- 2.7.4