[lld] r266484 - [LTO] Implement parallel Codegen for LTO using splitCodeGen.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 15 16:54:48 PDT 2016
Nevermind, it seems that it needs to be std::list instead of std::vector.
raw_svector_ostream has no copy constructor, but std::vector needs it when
the vector is grown, so std::vector<raw_svector_ostream> doesn't compile.
On Fri, Apr 15, 2016 at 4:46 PM, Davide Italiano <davide at freebsd.org> wrote:
> On Fri, Apr 15, 2016 at 3:51 PM, Rui Ueyama <ruiu at google.com> wrote:
> > On Fri, Apr 15, 2016 at 3:38 PM, Davide Italiano via llvm-commits
> > <llvm-commits at lists.llvm.org> wrote:
> >>
> >> Author: davide
> >> Date: Fri Apr 15 17:38:10 2016
> >> New Revision: 266484
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=266484&view=rev
> >> Log:
> >> [LTO] Implement parallel Codegen for LTO using splitCodeGen.
> >>
> >> Parallelism level can be chosen using the new --lto-jobs=K option
> >> where K is the number of threads used for CodeGen. It currently
> >> defaults to 1.
> >>
> >> Added:
> >> lld/trunk/test/ELF/lto/parallel.ll
> >> Modified:
> >> lld/trunk/ELF/Config.h
> >> lld/trunk/ELF/Driver.cpp
> >> lld/trunk/ELF/LTO.cpp
> >> lld/trunk/ELF/LTO.h
> >> lld/trunk/ELF/Options.td
> >> lld/trunk/ELF/SymbolTable.cpp
> >> lld/trunk/test/ELF/basic.s
> >>
> >> Modified: lld/trunk/ELF/Config.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=266484&r1=266483&r2=266484&view=diff
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/ELF/Config.h (original)
> >> +++ lld/trunk/ELF/Config.h Fri Apr 15 17:38:10 2016
> >> @@ -94,6 +94,7 @@ struct Configuration {
> >> ELFKind EKind = ELFNoneKind;
> >> uint16_t EMachine = llvm::ELF::EM_NONE;
> >> uint64_t EntryAddr = -1;
> >> + unsigned LtoJobs;
> >> unsigned LtoO;
> >> unsigned Optimize;
> >> };
> >>
> >> Modified: lld/trunk/ELF/Driver.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=266484&r1=266483&r2=266484&view=diff
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/ELF/Driver.cpp (original)
> >> +++ lld/trunk/ELF/Driver.cpp Fri Apr 15 17:38:10 2016
> >> @@ -321,6 +321,9 @@ void LinkerDriver::readConfigs(opt::Inpu
> >> Config->LtoO = getInteger(Args, OPT_lto_O, 2);
> >> if (Config->LtoO > 3)
> >> error("invalid optimization level for LTO: " + getString(Args,
> >> OPT_lto_O));
> >> + Config->LtoJobs = getInteger(Args, OPT_lto_jobs, 1);
> >> + if (Config->LtoJobs == 0)
> >> + error("number of threads must be > 0");
> >>
> >> Config->ZExecStack = hasZOption(Args, "execstack");
> >> Config->ZNodelete = hasZOption(Args, "nodelete");
> >>
> >> Modified: lld/trunk/ELF/LTO.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=266484&r1=266483&r2=266484&view=diff
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/ELF/LTO.cpp (original)
> >> +++ lld/trunk/ELF/LTO.cpp Fri Apr 15 17:38:10 2016
> >> @@ -16,6 +16,7 @@
> >> #include "llvm/Analysis/TargetTransformInfo.h"
> >> #include "llvm/Bitcode/ReaderWriter.h"
> >> #include "llvm/CodeGen/CommandFlags.h"
> >> +#include "llvm/CodeGen/ParallelCG.h"
> >> #include "llvm/IR/LegacyPassManager.h"
> >> #include "llvm/Linker/IRMover.h"
> >> #include "llvm/Support/StringSaver.h"
> >> @@ -33,10 +34,13 @@ using namespace lld;
> >> using namespace lld::elf;
> >>
> >> // This is for use when debugging LTO.
> >> -static void saveLtoObjectFile(StringRef Buffer) {
> >> +static void saveLtoObjectFile(StringRef Buffer, unsigned I, bool Many)
> {
> >> + SmallString<128> Filename = Config->OutputFile;
> >> + if (Many)
> >> + Filename += utostr(I);
> >> + Filename += ".lto.o";
> >> std::error_code EC;
> >> - raw_fd_ostream OS(Config->OutputFile.str() + ".lto.o", EC,
> >> - sys::fs::OpenFlags::F_None);
> >> + raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::F_None);
> >> check(EC);
> >> OS << Buffer;
> >> }
> >> @@ -136,9 +140,36 @@ static void internalize(GlobalValue &GV)
> >> GV.setLinkage(GlobalValue::InternalLinkage);
> >> }
> >>
> >> +std::vector<std::unique_ptr<InputFile>>
> >> BitcodeCompiler::runSplitCodegen() {
> >> + unsigned NumThreads = Config->LtoJobs;
> >> + OwningData.resize(NumThreads);
> >> +
> >> + std::list<raw_svector_ostream> OSs;
> >> + std::vector<raw_pwrite_stream *> OSPtrs;
> >
> >
> > Is there any reason you used std::list instead of std::vector? I think
> > std::vector is generally preferred unless you really want to have a
> linked
> > list.
> >
>
> I just blatantly modeled this after the gold plugin does.
> If we want to change it, we might want to change it everywhere.
>
> >>
> >> + for (SmallString<0> &Obj : OwningData) {
> >> + OSs.emplace_back(Obj);
> >> + OSPtrs.push_back(&OSs.back());
> >> + }
> >> +
> >> + splitCodeGen(std::move(Combined), OSPtrs, {},
> >> + [this]() { return getTargetMachine(); });
> >> +
> >> + std::vector<std::unique_ptr<InputFile>> ObjFiles;
> >> + for (SmallString<0> &Obj : OwningData)
> >> + ObjFiles.push_back(createObjectFile(
> >> + MemoryBufferRef(Obj, "LLD-INTERNAL-combined-lto-object")));
> >> +
> >> + if (Config->SaveTemps)
> >> + for (unsigned I = 0; I < NumThreads; ++I)
> >> + saveLtoObjectFile(OwningData[I], I, NumThreads > 1);
> >> +
> >> + return ObjFiles;
> >> +}
> >> +
> >> // Merge all the bitcode files we have seen, codegen the result
> >> // and return the resulting ObjectFile.
> >> -std::unique_ptr<InputFile> BitcodeCompiler::compile() {
> >> +std::vector<std::unique_ptr<InputFile>> BitcodeCompiler::compile() {
> >> + TheTriple = Combined->getTargetTriple();
> >> for (const auto &Name : InternalizedSyms) {
> >> GlobalValue *GV = Combined->getNamedValue(Name.first());
> >> assert(GV);
> >> @@ -151,26 +182,16 @@ std::unique_ptr<InputFile> BitcodeCompil
> >> std::unique_ptr<TargetMachine> TM(getTargetMachine());
> >> runLTOPasses(*Combined, *TM);
> >>
> >> - raw_svector_ostream OS(OwningData);
> >> - legacy::PassManager CodeGenPasses;
> >> - if (TM->addPassesToEmitFile(CodeGenPasses, OS,
> >> - TargetMachine::CGFT_ObjectFile))
> >> - fatal("failed to setup codegen");
> >> - CodeGenPasses.run(*Combined);
> >> - MB = MemoryBuffer::getMemBuffer(OwningData,
> >> - "LLD-INTERNAL-combined-lto-object",
> >> false);
> >> - if (Config->SaveTemps)
> >> - saveLtoObjectFile(MB->getBuffer());
> >> - return createObjectFile(*MB);
> >> + return runSplitCodegen();
> >> }
> >>
> >> -TargetMachine *BitcodeCompiler::getTargetMachine() {
> >> - StringRef TripleStr = Combined->getTargetTriple();
> >> +std::unique_ptr<TargetMachine> BitcodeCompiler::getTargetMachine() {
> >> std::string Msg;
> >> - const Target *T = TargetRegistry::lookupTarget(TripleStr, Msg);
> >> + const Target *T = TargetRegistry::lookupTarget(TheTriple, Msg);
> >> if (!T)
> >> fatal("target not found: " + Msg);
> >> TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
> >> Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;
> >> - return T->createTargetMachine(TripleStr, "", "", Options, R);
> >> + return std::unique_ptr<TargetMachine>(
> >> + T->createTargetMachine(TheTriple, "", "", Options, R));
> >> }
> >>
> >> Modified: lld/trunk/ELF/LTO.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=266484&r1=266483&r2=266484&view=diff
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/ELF/LTO.h (original)
> >> +++ lld/trunk/ELF/LTO.h Fri Apr 15 17:38:10 2016
> >> @@ -37,20 +37,22 @@ class InputFile;
> >> class BitcodeCompiler {
> >> public:
> >> void add(BitcodeFile &F);
> >> - std::unique_ptr<InputFile> compile();
> >> + std::vector<std::unique_ptr<InputFile>> compile();
> >>
> >> BitcodeCompiler()
> >> : Combined(new llvm::Module("ld-temp.o", Context)),
> >> Mover(*Combined) {}
> >>
> >> private:
> >> - llvm::TargetMachine *getTargetMachine();
> >> + std::vector<std::unique_ptr<InputFile>> runSplitCodegen();
> >> + std::unique_ptr<llvm::TargetMachine> getTargetMachine();
> >>
> >> llvm::LLVMContext Context;
> >> std::unique_ptr<llvm::Module> Combined;
> >> llvm::IRMover Mover;
> >> - SmallString<0> OwningData;
> >> + std::vector<SmallString<0>> OwningData;
> >> std::unique_ptr<MemoryBuffer> MB;
> >> llvm::StringSet<> InternalizedSyms;
> >> + std::string TheTriple;
> >> };
> >> }
> >> }
> >>
> >> Modified: lld/trunk/ELF/Options.td
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=266484&r1=266483&r2=266484&view=diff
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/ELF/Options.td (original)
> >> +++ lld/trunk/ELF/Options.td Fri Apr 15 17:38:10 2016
> >> @@ -237,7 +237,9 @@ def G : Separate<["-"], "G">;
> >> // Aliases for ignored options
> >> def alias_version_script_version_script : Joined<["--"],
> >> "version-script=">, Alias<version_script>;
> >>
> >> -// Debugging/developer options
> >> +// LTO-related options.
> >> +def lto_jobs : Joined<["--"], "lto-jobs=">,
> >> + HelpText<"Number of threads to run codegen">;
> >> def disable_verify : Flag<["-"], "disable-verify">;
> >> def mllvm : Separate<["-"], "mllvm">;
> >> def save_temps : Flag<["-"], "save-temps">;
> >>
> >> Modified: lld/trunk/ELF/SymbolTable.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=266484&r1=266483&r2=266484&view=diff
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/ELF/SymbolTable.cpp (original)
> >> +++ lld/trunk/ELF/SymbolTable.cpp Fri Apr 15 17:38:10 2016
> >> @@ -122,24 +122,27 @@ template <class ELFT> void SymbolTable<E
> >> Lto.reset(new BitcodeCompiler);
> >> for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles)
> >> Lto->add(*F);
> >> - std::unique_ptr<InputFile> IF = Lto->compile();
> >> - ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(IF.release());
> >> + std::vector<std::unique_ptr<InputFile>> IFs = Lto->compile();
> >>
> >> // Replace bitcode symbols.
> >> - llvm::DenseSet<StringRef> DummyGroups;
> >> - Obj->parse(DummyGroups);
> >> - for (SymbolBody *Body : Obj->getNonLocalSymbols()) {
> >> - Symbol *Sym = insert(Body);
> >> - Sym->Body->setUsedInRegularObj();
> >> - if (Sym->Body->isShared())
> >> - Sym->Body->MustBeInDynSym = true;
> >> - if (Sym->Body->MustBeInDynSym)
> >> - Body->MustBeInDynSym = true;
> >> - if (!Sym->Body->isUndefined() && Body->isUndefined())
> >> - continue;
> >> - Sym->Body = Body;
> >> + for (auto &IF : IFs) {
> >> + ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(IF.release());
> >> +
> >> + llvm::DenseSet<StringRef> DummyGroups;
> >> + Obj->parse(DummyGroups);
> >> + for (SymbolBody *Body : Obj->getNonLocalSymbols()) {
> >> + Symbol *Sym = insert(Body);
> >> + Sym->Body->setUsedInRegularObj();
> >> + if (Sym->Body->isShared())
> >> + Sym->Body->MustBeInDynSym = true;
> >> + if (Sym->Body->MustBeInDynSym)
> >> + Body->MustBeInDynSym = true;
> >> + if (!Sym->Body->isUndefined() && Body->isUndefined())
> >> + continue;
> >> + Sym->Body = Body;
> >> + }
> >> + ObjectFiles.emplace_back(Obj);
> >> }
> >> - ObjectFiles.emplace_back(Obj);
> >> }
> >>
> >> // Add an undefined symbol.
> >>
> >> Modified: lld/trunk/test/ELF/basic.s
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/basic.s?rev=266484&r1=266483&r2=266484&view=diff
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/test/ELF/basic.s (original)
> >> +++ lld/trunk/test/ELF/basic.s Fri Apr 15 17:38:10 2016
> >> @@ -214,3 +214,6 @@ _start:
> >>
> >> # RUN: not ld.lld %t -o %t -m wrong_emul 2>&1 | FileCheck
> >> --check-prefix=UNKNOWN_EMUL %s
> >> # UNKNOWN_EMUL: unknown emulation: wrong_emul
> >> +
> >> +# RUN: not ld.lld %t --lto-jobs=0 2>&1 | FileCheck
> >> --check-prefix=NOTHREADS %s
> >> +# NOTHREADS: number of threads must be > 0
> >>
> >> Added: lld/trunk/test/ELF/lto/parallel.ll
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/parallel.ll?rev=266484&view=auto
> >>
> >>
> ==============================================================================
> >> --- lld/trunk/test/ELF/lto/parallel.ll (added)
> >> +++ lld/trunk/test/ELF/lto/parallel.ll Fri Apr 15 17:38:10 2016
> >> @@ -0,0 +1,22 @@
> >> +; RUN: llvm-as -o %t.bc %s
> >> +; RUN: ld.lld -m elf_x86_64 --lto-jobs=2 -save-temps -o %t %t.bc
> -shared
> >> +; RUN: llvm-nm %t0.lto.o | FileCheck --check-prefix=CHECK0 %s
> >> +; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
> >> +
> >> +target triple = "x86_64-unknown-linux-gnu"
> >> +
> >> +; CHECK0-NOT: bar
> >> +; CHECK0: T foo
> >> +; CHECK0-NOT: bar
> >> +define void @foo() {
> >> + call void @bar()
> >> + ret void
> >> +}
> >> +
> >> +; CHECK1-NOT: foo
> >> +; CHECK1: T bar
> >> +; CHECK1-NOT: foo
> >> +define void @bar() {
> >> + call void @foo()
> >> + ret void
> >> +}
> >>
> >>
> >> _______________________________________________
> >> llvm-commits mailing list
> >> llvm-commits at lists.llvm.org
> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> >
> >
>
>
>
> --
> Davide
>
> "There are no solved problems; there are only problems that are more
> or less solved" -- Henri Poincare
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160415/5f825373/attachment.html>
More information about the llvm-commits
mailing list