From f596d82385a0fdf45543fb4266dc9832f4b64d8d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 1 Oct 2022 15:12:50 -0700 Subject: [PATCH] [ELF] Move driver into ctx and remove indirection. NFC This removes one global variable and removes GOT and unique_ptr indirection. --- lld/ELF/Config.h | 30 +++++++++++++++++++++++++++++- lld/ELF/Driver.cpp | 10 +++++----- lld/ELF/Driver.h | 32 -------------------------------- lld/ELF/DriverUtils.cpp | 2 +- lld/ELF/InputFiles.cpp | 6 +++--- lld/ELF/ScriptParser.cpp | 18 +++++++++--------- 6 files changed, 47 insertions(+), 51 deletions(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 9b84669..c5da9b4 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/Option/ArgList.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Compiler.h" @@ -37,6 +38,7 @@ class ELFFileBase; class SharedFile; class InputSectionBase; class Symbol; +class BitcodeCompiler; enum ELFKind : uint8_t { ELFNoneKind, @@ -98,10 +100,35 @@ struct VersionDefinition { SmallVector localPatterns; }; +class LinkerDriver { +public: + void linkerMain(ArrayRef args); + void addFile(StringRef path, bool withLOption); + void addLibrary(StringRef name); + +private: + void createFiles(llvm::opt::InputArgList &args); + void inferMachineType(); + void link(llvm::opt::InputArgList &args); + template void compileBitcodeFiles(bool skipLinkedOutput); + + // True if we are in --whole-archive and --no-whole-archive. + bool inWholeArchive = false; + + // True if we are in --start-lib and --end-lib. + bool inLib = false; + + std::unique_ptr lto; + std::vector files; + +public: + SmallVector, 0> archiveFiles; +}; + // This struct contains the global configuration for the linker. // Most fields are direct mapping from the command line options // and such fields have the same name as the corresponding options. -// Most fields are initialized by the driver. +// Most fields are initialized by the ctx.driver. struct Config { uint8_t osabi = 0; uint32_t andFeatures = 0; @@ -384,6 +411,7 @@ struct DuplicateSymbol { }; struct Ctx { + LinkerDriver driver; SmallVector> memoryBuffers; SmallVector objectFiles; SmallVector sharedFiles; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index f452052..7a48536 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -15,7 +15,7 @@ // linker path or library paths) for each host OS. // // I don't think implicit default values are useful because they are -// usually explicitly specified by the compiler driver. They can even +// usually explicitly specified by the compiler ctx.driver. They can even // be harmful when you are doing cross-linking. Therefore, in LLD, we // simply trust the compiler driver to pass all required options and // don't try to make effort on our side. @@ -27,6 +27,7 @@ #include "ICF.h" #include "InputFiles.h" #include "InputSection.h" +#include "LTO.h" #include "LinkerScript.h" #include "MarkLive.h" #include "OutputSections.h" @@ -75,7 +76,6 @@ using namespace lld::elf; ConfigWrapper elf::config; Ctx elf::ctx; -std::unique_ptr elf::driver; static void setConfigs(opt::InputArgList &args); static void readConfigs(opt::InputArgList &args); @@ -88,6 +88,7 @@ void elf::errorOrWarn(const Twine &msg) { } void Ctx::reset() { + driver = LinkerDriver(); memoryBuffers.clear(); objectFiles.clear(); sharedFiles.clear(); @@ -131,7 +132,6 @@ bool elf::link(ArrayRef args, llvm::raw_ostream &stdoutOS, "--error-limit=0 to see all errors)"; config = ConfigWrapper(); - driver = std::make_unique(); script = std::make_unique(); symAux.emplace_back(); @@ -141,7 +141,7 @@ bool elf::link(ArrayRef args, llvm::raw_ostream &stdoutOS, config->progName = args[0]; - driver->linkerMain(args); + elf::ctx.driver.linkerMain(args); return errorCount() == 0; } @@ -1879,7 +1879,7 @@ static void writeArchiveStats() { for (BitcodeFile *file : ctx.bitcodeFiles) if (file->archiveName.size()) ++extracted[CachedHashStringRef(file->archiveName)]; - for (std::pair f : driver->archiveFiles) { + for (std::pair f : ctx.driver.archiveFiles) { unsigned &v = extracted[CachedHashString(f.first)]; os << f.second << '\t' << v << '\t' << f.first << '\n'; // If the archive occurs multiple times, other instances have a count of 0. diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h index f864daa..20a7a8e 100644 --- a/lld/ELF/Driver.h +++ b/lld/ELF/Driver.h @@ -9,44 +9,12 @@ #ifndef LLD_ELF_DRIVER_H #define LLD_ELF_DRIVER_H -#include "LTO.h" #include "lld/Common/LLVM.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/Option/ArgList.h" namespace lld::elf { -class InputFile; - -extern std::unique_ptr driver; - -class LinkerDriver { -public: - void linkerMain(ArrayRef args); - void addFile(StringRef path, bool withLOption); - void addLibrary(StringRef name); - -private: - void createFiles(llvm::opt::InputArgList &args); - void inferMachineType(); - void link(llvm::opt::InputArgList &args); - template void compileBitcodeFiles(bool skipLinkedOutput); - - // True if we are in --whole-archive and --no-whole-archive. - bool inWholeArchive = false; - - // True if we are in --start-lib and --end-lib. - bool inLib = false; - - // For LTO. - std::unique_ptr lto; - - std::vector files; - -public: - SmallVector, 0> archiveFiles; -}; - // Parses command line options. class ELFOptTable : public llvm::opt::OptTable { public: diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp index 42ab5c0..ec2f6ba 100644 --- a/lld/ELF/DriverUtils.cpp +++ b/lld/ELF/DriverUtils.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file contains utility functions for the driver. Because there +// This file contains utility functions for the ctx.driver. Because there // are so many small functions, we created this separate file to make // Driver.cpp less cluttered. // diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index dd581cf..d135143 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -358,11 +358,11 @@ static void addDependentLibrary(StringRef specifier, const InputFile *f) { if (!config->dependentLibraries) return; if (Optional s = searchLibraryBaseName(specifier)) - driver->addFile(saver().save(*s), /*withLOption=*/true); + ctx.driver.addFile(saver().save(*s), /*withLOption=*/true); else if (Optional s = findFromSearchPaths(specifier)) - driver->addFile(saver().save(*s), /*withLOption=*/true); + ctx.driver.addFile(saver().save(*s), /*withLOption=*/true); else if (fs::exists(specifier)) - driver->addFile(specifier, /*withLOption=*/false); + ctx.driver.addFile(specifier, /*withLOption=*/false); else error(toString(f) + ": unable to find library from dependent library specifier: " + diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 111f168..a758fdc 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -294,7 +294,7 @@ void ScriptParser::addFile(StringRef s) { SmallString<128> pathData; StringRef path = (config->sysroot + s).toStringRef(pathData); if (sys::fs::exists(path)) - driver->addFile(saver().save(path), /*withLOption=*/false); + ctx.driver.addFile(saver().save(path), /*withLOption=*/false); else setError("cannot find " + s + " inside " + config->sysroot); return; @@ -302,17 +302,17 @@ void ScriptParser::addFile(StringRef s) { if (s.startswith("/")) { // Case 1: s is an absolute path. Just open it. - driver->addFile(s, /*withLOption=*/false); + ctx.driver.addFile(s, /*withLOption=*/false); } else if (s.startswith("=")) { // Case 2: relative to the sysroot. if (config->sysroot.empty()) - driver->addFile(s.substr(1), /*withLOption=*/false); + ctx.driver.addFile(s.substr(1), /*withLOption=*/false); else - driver->addFile(saver().save(config->sysroot + "/" + s.substr(1)), - /*withLOption=*/false); + ctx.driver.addFile(saver().save(config->sysroot + "/" + s.substr(1)), + /*withLOption=*/false); } else if (s.startswith("-l")) { // Case 3: search in the list of library paths. - driver->addLibrary(s.substr(2)); + ctx.driver.addLibrary(s.substr(2)); } else { // Case 4: s is a relative path. Search in the directory of the script file. std::string filename = std::string(getCurrentMB().getBufferIdentifier()); @@ -321,17 +321,17 @@ void ScriptParser::addFile(StringRef s) { SmallString<0> path(directory); sys::path::append(path, s); if (sys::fs::exists(path)) { - driver->addFile(path, /*withLOption=*/false); + ctx.driver.addFile(path, /*withLOption=*/false); return; } } // Then search in the current working directory. if (sys::fs::exists(s)) { - driver->addFile(s, /*withLOption=*/false); + ctx.driver.addFile(s, /*withLOption=*/false); } else { // Finally, search in the list of library paths. if (Optional path = findFromSearchPaths(s)) - driver->addFile(saver().save(*path), /*withLOption=*/true); + ctx.driver.addFile(saver().save(*path), /*withLOption=*/true); else setError("unable to find " + s); } -- 2.7.4