[lld] r264091 - ELF: Create LTO.{cpp, h} and move LTO-related code to that file.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 23 02:25:45 PDT 2016


On Wed, Mar 23, 2016 at 8:36 AM, Davide Italiano <davide at freebsd.org> wrote:

> On Tue, Mar 22, 2016 at 1:52 PM, Rui Ueyama via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
> > Author: ruiu
> > Date: Tue Mar 22 15:52:10 2016
> > New Revision: 264091
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=264091&view=rev
> > Log:
> > ELF: Create LTO.{cpp,h} and move LTO-related code to that file.
> >
> > The code for LTO has been growing, so now is probably a good time to
> > move it to its own file. SymbolTable.cpp is for symbol table, and
> > because compiling bitcode files are semantically not a part of
> > symbol table, this is I think a good thing to do.
> >
>
> Sorry for noticing this late, but I realized you renamed codegen ->
> compile.
> Is there any particular reason? I prefer the old one. If you have
> other suggestions, I'm happy to hear.
>

I just though that compile is more preferable since it's a plain English
word (at least than codegen.) It's not a strong preference or anything, but
is codegen a good name for a function? (I mean would you say "I codegen
this and this" for example?)


> --
> Davide
>
> > http://reviews.llvm.org/D18370
> >
> > Added:
> >     lld/trunk/ELF/LTO.cpp
> >     lld/trunk/ELF/LTO.h
> > Modified:
> >     lld/trunk/ELF/CMakeLists.txt
> >     lld/trunk/ELF/SymbolTable.cpp
> >     lld/trunk/ELF/SymbolTable.h
> >
> > Modified: lld/trunk/ELF/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/CMakeLists.txt?rev=264091&r1=264090&r2=264091&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/CMakeLists.txt (original)
> > +++ lld/trunk/ELF/CMakeLists.txt Tue Mar 22 15:52:10 2016
> > @@ -9,6 +9,7 @@ add_lld_library(lldELF
> >    ICF.cpp
> >    InputFiles.cpp
> >    InputSection.cpp
> > +  LTO.cpp
> >    LinkerScript.cpp
> >    MarkLive.cpp
> >    OutputSections.cpp
> >
> > Added: lld/trunk/ELF/LTO.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=264091&view=auto
> >
> ==============================================================================
> > --- lld/trunk/ELF/LTO.cpp (added)
> > +++ lld/trunk/ELF/LTO.cpp Tue Mar 22 15:52:10 2016
> > @@ -0,0 +1,140 @@
> > +//===- LTO.cpp
> ------------------------------------------------------------===//
> > +//
> > +//                             The LLVM Linker
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#include "LTO.h"
> > +#include "Config.h"
> > +#include "Error.h"
> > +#include "InputFiles.h"
> > +#include "Symbols.h"
> > +#include "llvm/Analysis/TargetLibraryInfo.h"
> > +#include "llvm/Analysis/TargetTransformInfo.h"
> > +#include "llvm/Bitcode/ReaderWriter.h"
> > +#include "llvm/IR/LegacyPassManager.h"
> > +#include "llvm/Linker/IRMover.h"
> > +#include "llvm/Support/StringSaver.h"
> > +#include "llvm/Support/TargetRegistry.h"
> > +#include "llvm/Target/TargetMachine.h"
> > +#include "llvm/Transforms/IPO.h"
> > +#include "llvm/Transforms/IPO/PassManagerBuilder.h"
> > +
> > +using namespace llvm;
> > +using namespace llvm::object;
> > +using namespace llvm::ELF;
> > +
> > +using namespace lld;
> > +using namespace lld::elf;
> > +
> > +// This is for use when debugging LTO.
> > +static void saveLtoObjectFile(StringRef Buffer) {
> > +  std::error_code EC;
> > +  raw_fd_ostream OS(Config->OutputFile.str() + ".lto.o", EC,
> > +                    sys::fs::OpenFlags::F_None);
> > +  check(EC);
> > +  OS << Buffer;
> > +}
> > +
> > +// This is for use when debugging LTO.
> > +static void saveBCFile(Module &M, StringRef Suffix) {
> > +  std::error_code EC;
> > +  raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC,
> > +                    sys::fs::OpenFlags::F_None);
> > +  check(EC);
> > +  WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);
> > +}
> > +
> > +// Run LTO passes.
> > +// FIXME: Reduce code duplication by sharing this code with the gold
> plugin.
> > +static void runLTOPasses(Module &M, TargetMachine &TM) {
> > +  legacy::PassManager LtoPasses;
> > +
> LtoPasses.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
> > +  PassManagerBuilder PMB;
> > +  PMB.LibraryInfo = new
> TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));
> > +  PMB.Inliner = createFunctionInliningPass();
> > +  PMB.VerifyInput = true;
> > +  PMB.VerifyOutput = true;
> > +  PMB.LoopVectorize = true;
> > +  PMB.SLPVectorize = true;
> > +  PMB.OptLevel = 2; // FIXME: This should be an option.
> > +  PMB.populateLTOPassManager(LtoPasses);
> > +  LtoPasses.run(M);
> > +
> > +  if (Config->SaveTemps)
> > +    saveBCFile(M, ".lto.opt.bc");
> > +}
> > +
> > +void BitcodeCompiler::add(BitcodeFile &F) {
> > +  std::unique_ptr<IRObjectFile> Obj =
> > +      check(IRObjectFile::create(F.MB, Context));
> > +  std::vector<GlobalValue *> Keep;
> > +  unsigned BodyIndex = 0;
> > +  ArrayRef<SymbolBody *> Bodies = F.getSymbols();
> > +
> > +  for (const BasicSymbolRef &Sym : Obj->symbols()) {
> > +    GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
> > +    assert(GV);
> > +    if (GV->hasAppendingLinkage()) {
> > +      Keep.push_back(GV);
> > +      continue;
> > +    }
> > +    if (!BitcodeFile::shouldSkip(Sym))
> > +      if (SymbolBody *B = Bodies[BodyIndex++])
> > +        if (&B->repl() == B && isa<DefinedBitcode>(B))
> > +          Keep.push_back(GV);
> > +  }
> > +
> > +  Mover.move(Obj->takeModule(), Keep,
> > +             [](GlobalValue &, IRMover::ValueAdder) {});
> > +}
> > +
> > +// Merge all the bitcode files we have seen, codegen the result
> > +// and return the resulting ObjectFile.
> > +template <class ELFT>
> > +std::unique_ptr<elf::ObjectFile<ELFT>> BitcodeCompiler::compile() {
> > +  if (Config->SaveTemps)
> > +    saveBCFile(Combined, ".lto.bc");
> > +
> > +  StringRef TripleStr = Combined.getTargetTriple();
> > +  Triple TheTriple(TripleStr);
> > +
> > +  // FIXME: Should we have a default triple? The gold plugin uses
> > +  // sys::getDefaultTargetTriple(), but that is probably wrong given
> that this
> > +  // might be a cross linker.
> > +
> > +  std::string ErrMsg;
> > +  const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr,
> ErrMsg);
> > +  if (!TheTarget)
> > +    fatal("target not found: " + ErrMsg);
> > +
> > +  TargetOptions Options;
> > +  Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;
> > +  std::unique_ptr<TargetMachine> TM(
> > +      TheTarget->createTargetMachine(TripleStr, "", "", Options, R));
> > +
> > +  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());
> > +
> > +  std::unique_ptr<InputFile> IF = createObjectFile(*MB);
> > +  auto *OF = cast<ObjectFile<ELFT>>(IF.release());
> > +  return std::unique_ptr<ObjectFile<ELFT>>(OF);
> > +}
> > +
> > +template std::unique_ptr<elf::ObjectFile<ELF32LE>>
> BitcodeCompiler::compile();
> > +template std::unique_ptr<elf::ObjectFile<ELF32BE>>
> BitcodeCompiler::compile();
> > +template std::unique_ptr<elf::ObjectFile<ELF64LE>>
> BitcodeCompiler::compile();
> > +template std::unique_ptr<elf::ObjectFile<ELF64BE>>
> BitcodeCompiler::compile();
> >
> > Added: lld/trunk/ELF/LTO.h
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=264091&view=auto
> >
> ==============================================================================
> > --- lld/trunk/ELF/LTO.h (added)
> > +++ lld/trunk/ELF/LTO.h Tue Mar 22 15:52:10 2016
> > @@ -0,0 +1,51 @@
> > +//===- LTO.h ----------------------------------------------------*- C++
> -*-===//
> > +//
> > +//                             The LLVM Linker
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +//
> > +// This file provides a way to combine bitcode files into one ELF
> > +// file by compiling them using LLVM.
> > +//
> > +// If LTO is in use, your input files are not in regular ELF files
> > +// but instead LLVM bitcode files. In that case, the linker has to
> > +// convert bitcode files into the native format so that we can create
> > +// an ELF file that contains native code. This file provides that
> > +// functionality.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLD_ELF_LTO_H
> > +#define LLD_ELF_LTO_H
> > +
> > +#include "lld/Core/LLVM.h"
> > +#include "llvm/ADT/SmallString.h"
> > +#include "llvm/IR/LLVMContext.h"
> > +#include "llvm/IR/Module.h"
> > +#include "llvm/Linker/IRMover.h"
> > +
> > +namespace lld {
> > +namespace elf {
> > +
> > +class BitcodeFile;
> > +template <class ELFT> class ObjectFile;
> > +
> > +class BitcodeCompiler {
> > +public:
> > +  void add(BitcodeFile &F);
> > +  template <class ELFT> std::unique_ptr<ObjectFile<ELFT>> compile();
> > +
> > +private:
> > +  llvm::LLVMContext Context;
> > +  llvm::Module Combined{"ld-temp.o", Context};
> > +  llvm::IRMover Mover{Combined};
> > +  SmallString<0> OwningData;
> > +  std::unique_ptr<MemoryBuffer> MB;
> > +};
> > +}
> > +}
> > +
> > +#endif
> >
> > Modified: lld/trunk/ELF/SymbolTable.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=264091&r1=264090&r2=264091&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/SymbolTable.cpp (original)
> > +++ lld/trunk/ELF/SymbolTable.cpp Tue Mar 22 15:52:10 2016
> > @@ -18,16 +18,8 @@
> >  #include "Config.h"
> >  #include "Error.h"
> >  #include "Symbols.h"
> > -#include "llvm/Analysis/TargetLibraryInfo.h"
> > -#include "llvm/Analysis/TargetTransformInfo.h"
> >  #include "llvm/Bitcode/ReaderWriter.h"
> > -#include "llvm/IR/LegacyPassManager.h"
> > -#include "llvm/Linker/IRMover.h"
> >  #include "llvm/Support/StringSaver.h"
> > -#include "llvm/Support/TargetRegistry.h"
> > -#include "llvm/Target/TargetMachine.h"
> > -#include "llvm/Transforms/IPO.h"
> > -#include "llvm/Transforms/IPO/PassManagerBuilder.h"
> >
> >  using namespace llvm;
> >  using namespace llvm::object;
> > @@ -101,131 +93,17 @@ void SymbolTable<ELFT>::addFile(std::uni
> >      resolve(B);
> >  }
> >
> > -// This is for use when debugging LTO.
> > -static void saveLtoObjectFile(StringRef Buffer) {
> > -  std::error_code EC;
> > -  raw_fd_ostream OS(Config->OutputFile.str() + ".lto.o", EC,
> > -                    sys::fs::OpenFlags::F_None);
> > -  check(EC);
> > -  OS << Buffer;
> > -}
> > -
> > -// This is for use when debugging LTO.
> > -static void saveBCFile(Module &M, StringRef Suffix) {
> > -  std::error_code EC;
> > -  raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC,
> > -                    sys::fs::OpenFlags::F_None);
> > -  check(EC);
> > -  WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);
> > -}
> > -
> > -static void runLTOPasses(Module &M, TargetMachine &TM) {
> > -  // Run LTO passes.
> > -  // FIXME: Reduce code duplication by sharing this code with the gold
> plugin.
> > -  legacy::PassManager LtoPasses;
> > -  LtoPasses.add(
> > -      createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
> > -  PassManagerBuilder PMB;
> > -  PMB.LibraryInfo = new
> TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));
> > -  PMB.Inliner = createFunctionInliningPass();
> > -  PMB.VerifyInput = true;
> > -  PMB.VerifyOutput = true;
> > -  PMB.LoopVectorize = true;
> > -  PMB.SLPVectorize = true;
> > -  PMB.OptLevel = 2; // FIXME: This should be an option.
> > -  PMB.populateLTOPassManager(LtoPasses);
> > -  LtoPasses.run(M);
> > -
> > -  if (Config->SaveTemps)
> > -    saveBCFile(M, ".lto.opt.bc");
> > -}
> > -
> > -// Codegen the module M and returns the resulting InputFile.
> > -template <class ELFT>
> > -std::unique_ptr<InputFile> SymbolTable<ELFT>::codegen(Module &M) {
> > -  StringRef TripleStr = M.getTargetTriple();
> > -  Triple TheTriple(TripleStr);
> > -
> > -  // FIXME: Should we have a default triple? The gold plugin uses
> > -  // sys::getDefaultTargetTriple(), but that is probably wrong given
> that this
> > -  // might be a cross linker.
> > -
> > -  std::string ErrMsg;
> > -  const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr,
> ErrMsg);
> > -  if (!TheTarget)
> > -    fatal("target not found: " + ErrMsg);
> > -
> > -  TargetOptions Options;
> > -  Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;
> > -  std::unique_ptr<TargetMachine> TM(
> > -      TheTarget->createTargetMachine(TripleStr, "", "", Options, R));
> > -
> > -  runLTOPasses(M, *TM);
> > -
> > -  raw_svector_ostream OS(OwningLTOData);
> > -  legacy::PassManager CodeGenPasses;
> > -  if (TM->addPassesToEmitFile(CodeGenPasses, OS,
> > -                              TargetMachine::CGFT_ObjectFile))
> > -    fatal("failed to setup codegen");
> > -  CodeGenPasses.run(M);
> > -  LtoBuffer = MemoryBuffer::getMemBuffer(
> > -      OwningLTOData, "LLD-INTERNAL-combined-lto-object", false);
> > -  if (Config->SaveTemps)
> > -    saveLtoObjectFile(LtoBuffer->getBuffer());
> > -  return createObjectFile(*LtoBuffer);
> > -}
> > -
> > -static void addBitcodeFile(IRMover &Mover, BitcodeFile &F,
> > -                           LLVMContext &Context) {
> > -
> > -  std::unique_ptr<IRObjectFile> Obj =
> > -      check(IRObjectFile::create(F.MB, Context));
> > -  std::vector<GlobalValue *> Keep;
> > -  unsigned BodyIndex = 0;
> > -  ArrayRef<SymbolBody *> Bodies = F.getSymbols();
> > -
> > -  for (const BasicSymbolRef &Sym : Obj->symbols()) {
> > -    GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
> > -    assert(GV);
> > -    if (GV->hasAppendingLinkage()) {
> > -      Keep.push_back(GV);
> > -      continue;
> > -    }
> > -    if (BitcodeFile::shouldSkip(Sym))
> > -      continue;
> > -    SymbolBody *B = Bodies[BodyIndex++];
> > -    if (!B || &B->repl() != B)
> > -      continue;
> > -    auto *DB = dyn_cast<DefinedBitcode>(B);
> > -    if (!DB)
> > -      continue;
> > -    Keep.push_back(GV);
> > -  }
> > -
> > -  Mover.move(Obj->takeModule(), Keep,
> > -             [](GlobalValue &, IRMover::ValueAdder) {});
> > -}
> > -
> > -// Merge all the bitcode files we have seen, codegen the result and
> return
> > -// the resulting ObjectFile.
> > -template <class ELFT>
> > -elf::ObjectFile<ELFT> *SymbolTable<ELFT>::createCombinedLtoObject() {
> > -  LLVMContext Context;
> > -  Module Combined("ld-temp.o", Context);
> > -  IRMover Mover(Combined);
> > -  for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles)
> > -    addBitcodeFile(Mover, *F, Context);
> > -  if (Config->SaveTemps)
> > -    saveBCFile(Combined, ".lto.bc");
> > -  std::unique_ptr<InputFile> F = codegen(Combined);
> > -  ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(F.release()));
> > -  return &*ObjectFiles.back();
> > -}
> > -
> >  template <class ELFT> void SymbolTable<ELFT>::addCombinedLtoObject() {
> >    if (BitcodeFiles.empty())
> >      return;
> > -  ObjectFile<ELFT> *Obj = createCombinedLtoObject();
> > +
> > +  // Compile bitcode files.
> > +  Lto.reset(new BitcodeCompiler);
> > +  for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles)
> > +    Lto->add(*F);
> > +  std::unique_ptr<ObjectFile<ELFT>> Obj = Lto->compile<ELFT>();
> > +
> > +  // Replace bitcode symbols.
> >    llvm::DenseSet<StringRef> DummyGroups;
> >    Obj->parse(DummyGroups);
> >    for (SymbolBody *Body : Obj->getNonLocalSymbols()) {
> > @@ -234,6 +112,7 @@ template <class ELFT> void SymbolTable<E
> >        continue;
> >      Sym->Body = Body;
> >    }
> > +  ObjectFiles.push_back(std::move(Obj));
> >  }
> >
> >  // Add an undefined symbol.
> >
> > Modified: lld/trunk/ELF/SymbolTable.h
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=264091&r1=264090&r2=264091&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/SymbolTable.h (original)
> > +++ lld/trunk/ELF/SymbolTable.h Tue Mar 22 15:52:10 2016
> > @@ -11,6 +11,7 @@
> >  #define LLD_ELF_SYMBOL_TABLE_H
> >
> >  #include "InputFiles.h"
> > +#include "LTO.h"
> >  #include "llvm/ADT/MapVector.h"
> >
> >  namespace llvm {
> > @@ -74,8 +75,6 @@ private:
> >    std::unique_ptr<InputFile> codegen(llvm::Module &M);
> >    std::string conflictMsg(SymbolBody *Old, SymbolBody *New);
> >
> > -  SmallString<0> OwningLTOData;
> > -  std::unique_ptr<MemoryBuffer> LtoBuffer;
> >    ObjectFile<ELFT> *createCombinedLtoObject();
> >
> >    // The order the global symbols are in is not defined. We can use an
> arbitrary
> > @@ -101,6 +100,8 @@ private:
> >
> >    // Set of .so files to not link the same shared object file more than
> once.
> >    llvm::DenseSet<StringRef> SoNames;
> > +
> > +  std::unique_ptr<BitcodeCompiler> Lto;
> >  };
> >
> >  } // namespace elf
> >
> >
> > _______________________________________________
> > 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/20160323/1a57599f/attachment-0001.html>


More information about the llvm-commits mailing list