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

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 23 00:36:14 PDT 2016


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.

--
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


More information about the llvm-commits mailing list