[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