[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
Tue Mar 22 13:52:11 PDT 2016


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.

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




More information about the llvm-commits mailing list