From cfe59fd0d3ee74110e7d30abfe994fe154532850 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Thu, 7 Feb 2013 06:46:48 +0000 Subject: [PATCH] [Driver] Replace Target with TargetInfo. Simplify LinkerInput. This removes Target and moves the functionality it had over to TargetInfo. This also simplifies LinkerInput by removing the InputKind. This will be handled elsewhere. llvm-svn: 174589 --- lld/include/lld/Core/LinkerOptions.h | 65 +++++------------- lld/include/lld/Core/TargetInfo.h | 11 +++ lld/include/lld/Driver/Target.h | 58 ---------------- lld/include/lld/ReaderWriter/ELFTargetInfo.h | 11 ++- lld/include/lld/ReaderWriter/MachOTargetInfo.h | 10 +++ lld/lib/Driver/CMakeLists.txt | 2 - lld/lib/Driver/Drivers.cpp | 2 +- lld/lib/Driver/LinkerInvocation.cpp | 20 ++++-- lld/lib/Driver/Target.cpp | 14 ---- lld/lib/Driver/Targets.cpp | 92 -------------------------- lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp | 19 ++++++ lld/tools/lld-core/lld-core.cpp | 9 +++ 12 files changed, 88 insertions(+), 225 deletions(-) delete mode 100644 lld/include/lld/Driver/Target.h delete mode 100644 lld/lib/Driver/Target.cpp delete mode 100644 lld/lib/Driver/Targets.cpp diff --git a/lld/include/lld/Core/LinkerOptions.h b/lld/include/lld/Core/LinkerOptions.h index 968ca4e..2eba90c 100644 --- a/lld/include/lld/Core/LinkerOptions.h +++ b/lld/include/lld/Core/LinkerOptions.h @@ -29,38 +29,31 @@ #include namespace lld { -enum class InputKind { - Unknown, - YAML, - Native, - Object, - LLVM, - Script -}; - +/// \brief An input to the linker. +/// +/// This class represents an input to the linker. It create the MemoryBuffer +/// lazily when needed based on the file path. It can also take a MemoryBuffer +/// directly. +/// +/// The intent is that we only open each file once. And have strong ownership +/// semantics. class LinkerInput { LinkerInput(const LinkerInput &) LLVM_DELETED_FUNCTION; public: - LinkerInput(StringRef file, InputKind kind = InputKind::Unknown) - : _file(file) - , _kind(kind) {} + LinkerInput(StringRef file) : _file(file) {} - LinkerInput(std::unique_ptr buffer, - InputKind kind = InputKind::Unknown) - : _buffer(std::move(buffer)) - , _file(_buffer->getBufferIdentifier()) - , _kind(kind) {} + LinkerInput(std::unique_ptr buffer) + : _buffer(std::move(buffer)), _file(_buffer->getBufferIdentifier()) { + } - LinkerInput(LinkerInput &&other) - : _buffer(std::move(other._buffer)) - , _file(std::move(other._file)) - , _kind(other._kind) {} + LinkerInput(LinkerInput && other) + : _buffer(std::move(other._buffer)), _file(std::move(other._file)) { + } LinkerInput &operator=(LinkerInput &&rhs) { _buffer = std::move(rhs._buffer); _file = std::move(rhs._file); - _kind = rhs._kind; return *this; } @@ -75,33 +68,6 @@ public: return *_buffer; } - ErrorOr getKind() const { - if (_kind == InputKind::Unknown) { - _kind = llvm::StringSwitch(getPath()) - .EndsWith(".objtxt", InputKind::YAML) - .EndsWith(".yaml", InputKind::YAML) - .Default(InputKind::Unknown); - - if (_kind != InputKind::Unknown) - return _kind; - - auto buf = getBuffer(); - if (!buf) - return error_code(buf); - - llvm::sys::fs::file_magic magic = - llvm::sys::fs::identify_magic(buf->getBuffer()); - - switch (magic) { - case llvm::sys::fs::file_magic::elf_relocatable: - _kind = InputKind::Object; - break; - } - } - - return _kind; - } - StringRef getPath() const { return _file; } @@ -114,7 +80,6 @@ public: private: mutable std::unique_ptr _buffer; std::string _file; - mutable InputKind _kind; }; enum OutputKind { diff --git a/lld/include/lld/Core/TargetInfo.h b/lld/include/lld/Core/TargetInfo.h index 8d7adf7..ef2326d 100644 --- a/lld/include/lld/Core/TargetInfo.h +++ b/lld/include/lld/Core/TargetInfo.h @@ -31,8 +31,11 @@ namespace llvm { } namespace lld { +class LinkerInput; struct LinkerOptions; class PassManager; +class Reader; +class Writer; class TargetInfo { protected: @@ -53,6 +56,14 @@ public: virtual void addPasses(PassManager &pm) const {} + /// \brief Get a reference to a Reader for the given input. + /// + /// Will always return the same object for the same input. + virtual ErrorOr getReader(const LinkerInput &input) const = 0; + + /// \brief Get the writer. + virtual ErrorOr getWriter() const = 0; + // TODO: Split out to TargetRelocationInfo. virtual ErrorOr relocKindFromString(StringRef str) const { int32_t val; diff --git a/lld/include/lld/Driver/Target.h b/lld/include/lld/Driver/Target.h deleted file mode 100644 index b30d707..0000000 --- a/lld/include/lld/Driver/Target.h +++ /dev/null @@ -1,58 +0,0 @@ -//===- lld/Driver/Target.h - Linker Target Abstraction --------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// -/// Interface and factory for creating a specific Target. A Target is used to -/// encapsulate all of the target specific configurations for the linker. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLD_DRIVER_TARGET_H -#define LLD_DRIVER_TARGET_H - -#include "lld/Core/TargetInfo.h" - -#include "llvm/Support/ErrorOr.h" - -#include - -namespace lld { -class LinkerInput; -struct LinkerOptions; -class Reader; -class TargetInfo; -class Writer; - -/// \brief Represents a specific target. -class Target { -protected: - Target(std::unique_ptr ti) : _targetInfo(std::move(ti)) {} - -public: - virtual ~Target(); - - const TargetInfo &getTargetInfo() const { return *_targetInfo; }; - - /// \brief Get a reference to a Reader for the given input. - /// - /// Will always return the same object for the same input. - virtual ErrorOr getReader(const LinkerInput &input) = 0; - - /// \brief Get the writer. - virtual ErrorOr getWriter() = 0; - - static std::unique_ptr create(const LinkerOptions&); - -protected: - std::unique_ptr _targetInfo; -}; -} - -#endif diff --git a/lld/include/lld/ReaderWriter/ELFTargetInfo.h b/lld/include/lld/ReaderWriter/ELFTargetInfo.h index 5a28ee5..058714f 100644 --- a/lld/include/lld/ReaderWriter/ELFTargetInfo.h +++ b/lld/include/lld/ReaderWriter/ELFTargetInfo.h @@ -12,6 +12,9 @@ #include "lld/Core/LinkerOptions.h" #include "lld/Core/TargetInfo.h" +#include "lld/ReaderWriter/Reader.h" +#include "lld/ReaderWriter/Writer.h" + #include "llvm/Object/ELF.h" #include "llvm/Support/ELF.h" @@ -30,7 +33,7 @@ public: class ELFTargetInfo : public TargetInfo { protected: - ELFTargetInfo(const LinkerOptions &lo) : TargetInfo(lo) {} + ELFTargetInfo(const LinkerOptions &lo); public: uint16_t getOutputType() const; @@ -44,6 +47,10 @@ public: return false; } + virtual ErrorOr getReader(const LinkerInput &input) const; + + virtual ErrorOr getWriter() const; + static std::unique_ptr create(const LinkerOptions &lo); template @@ -54,6 +61,8 @@ public: protected: std::unique_ptr _targetHandler; + mutable std::unique_ptr _reader; + mutable std::unique_ptr _writer; }; } // end namespace lld diff --git a/lld/include/lld/ReaderWriter/MachOTargetInfo.h b/lld/include/lld/ReaderWriter/MachOTargetInfo.h index 9055316..7e8927b 100644 --- a/lld/include/lld/ReaderWriter/MachOTargetInfo.h +++ b/lld/include/lld/ReaderWriter/MachOTargetInfo.h @@ -12,6 +12,8 @@ #include "lld/Core/TargetInfo.h" +#include "llvm/Support/ErrorHandling.h" + #include namespace lld { @@ -28,6 +30,14 @@ public: virtual uint64_t getPageZeroSize() const = 0; + virtual ErrorOr getReader(const LinkerInput &input) const { + llvm_unreachable("Unimplemented!"); + } + + virtual ErrorOr getWriter() const { + llvm_unreachable("Unimplemented!"); + } + static std::unique_ptr create(const LinkerOptions &lo); }; } // end namespace lld diff --git a/lld/lib/Driver/CMakeLists.txt b/lld/lib/Driver/CMakeLists.txt index 83b3953..13e6298 100644 --- a/lld/lib/Driver/CMakeLists.txt +++ b/lld/lib/Driver/CMakeLists.txt @@ -8,8 +8,6 @@ add_lld_library(lldDriver Driver.cpp Drivers.cpp LinkerInvocation.cpp - Target.cpp - Targets.cpp ) add_dependencies(lldDriver DriverOptionsTableGen) diff --git a/lld/lib/Driver/Drivers.cpp b/lld/lib/Driver/Drivers.cpp index 00085e6..3c143ef 100644 --- a/lld/lib/Driver/Drivers.cpp +++ b/lld/lib/Driver/Drivers.cpp @@ -218,7 +218,7 @@ LinkerOptions lld::generateOptions(const llvm::opt::ArgList &args) { for (llvm::opt::arg_iterator it = args.filtered_begin(ld::OPT_INPUT), ie = args.filtered_end(); it != ie; ++it) { - ret._input.push_back(LinkerInput((*it)->getValue(), InputKind::Object)); + ret._input.push_back(LinkerInput((*it)->getValue())); } ret._llvmArgs = args.getAllArgValues(core::OPT_mllvm); diff --git a/lld/lib/Driver/LinkerInvocation.cpp b/lld/lib/Driver/LinkerInvocation.cpp index 1027403..6f50051 100644 --- a/lld/lib/Driver/LinkerInvocation.cpp +++ b/lld/lib/Driver/LinkerInvocation.cpp @@ -12,7 +12,7 @@ #include "lld/Core/InputFiles.h" #include "lld/Core/PassManager.h" #include "lld/Core/Resolver.h" -#include "lld/Driver/Target.h" +#include "lld/ReaderWriter/ELFTargetInfo.h" #include "lld/ReaderWriter/Reader.h" #include "lld/ReaderWriter/Writer.h" @@ -21,6 +21,12 @@ using namespace lld; +namespace { +std::unique_ptr createTargetInfo(const LinkerOptions &lo) { + return ELFTargetInfo::create(lo); +} +} + void LinkerInvocation::operator()() { // Honor -mllvm if (!_options._llvmArgs.empty()) { @@ -34,9 +40,9 @@ void LinkerInvocation::operator()() { } // Create target. - std::unique_ptr target(Target::create(_options)); + std::unique_ptr targetInfo(createTargetInfo(_options)); - if (!target) { + if (!targetInfo) { llvm::errs() << "Failed to create target for " << _options._target << "\n"; return; @@ -45,7 +51,7 @@ void LinkerInvocation::operator()() { // Read inputs InputFiles inputs; for (const auto &input : _options._input) { - auto reader = target->getReader(input); + auto reader = targetInfo->getReader(input); if (error_code ec = reader) { llvm::errs() << "Failed to get reader for: " << input.getPath() << ": " << ec.message() << "\n"; @@ -69,17 +75,17 @@ void LinkerInvocation::operator()() { inputs.appendFiles(files); } - auto writer = target->getWriter(); + auto writer = targetInfo->getWriter(); // Give writer a chance to add files writer->addFiles(inputs); - Resolver resolver(target->getTargetInfo(), inputs); + Resolver resolver(*targetInfo, inputs); resolver.resolve(); MutableFile &merged = resolver.resultFile(); PassManager pm; - target->getTargetInfo().addPasses(pm); + targetInfo->addPasses(pm); pm.runOnFile(merged); if (error_code ec = writer) { diff --git a/lld/lib/Driver/Target.cpp b/lld/lib/Driver/Target.cpp deleted file mode 100644 index 8b90ebf..0000000 --- a/lld/lib/Driver/Target.cpp +++ /dev/null @@ -1,14 +0,0 @@ -//===- lib/Driver/Target.cpp - Linker Target Abstraction ------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lld/Driver/Target.h" - -using namespace lld; - -Target::~Target() {} diff --git a/lld/lib/Driver/Targets.cpp b/lld/lib/Driver/Targets.cpp deleted file mode 100644 index 2e2bc59..0000000 --- a/lld/lib/Driver/Targets.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//===- lib/Driver/Targets.cpp - Linker Targets ----------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// -/// Concrete instances of the Target interface. -/// -//===----------------------------------------------------------------------===// - -#include "lld/Driver/Target.h" - -#include "lld/Core/LinkerOptions.h" -#include "lld/Core/TargetInfo.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" -#include "lld/ReaderWriter/ELFTargetInfo.h" - -#include "llvm/ADT/Triple.h" -#include "llvm/Support/raw_ostream.h" - -#include - -using namespace lld; -using namespace std::placeholders; - -class ELFTarget : public Target { -public: - ELFTarget(std::unique_ptr ti) - : Target(std::unique_ptr(ti.get())), - _elfTargetInfo(*ti.release()), _readerELF(createReaderELF( - _elfTargetInfo, std::bind(&ELFTarget::getReader, this, _1))), - _readerYAML(createReaderYAML(*_targetInfo)), - _writer(createWriterELF(_elfTargetInfo)), - _writerYAML(createWriterYAML(*_targetInfo)) { - } - - virtual ErrorOr getReader(const LinkerInput &input) { - auto kind = input.getKind(); - if (!kind) - return error_code(kind); - - if (*kind == InputKind::YAML) - return *_readerYAML; - - if (*kind == InputKind::Object) - return *_readerELF; - - return llvm::make_error_code(llvm::errc::invalid_argument); - } - - virtual ErrorOr getWriter() { - return _targetInfo->getLinkerOptions()._outputYAML ? *_writerYAML - : *_writer; - } - -protected: - const ELFTargetInfo &_elfTargetInfo; - std::unique_ptr _readerELF, _readerYAML; - std::unique_ptr _writer, _writerYAML; -}; - -class X86LinuxTarget LLVM_FINAL : public ELFTarget { -public: - X86LinuxTarget(std::unique_ptr ti) - : ELFTarget(std::move(ti)) {} -}; - -class HexagonTarget LLVM_FINAL : public ELFTarget { -public: - HexagonTarget(std::unique_ptr ti) - : ELFTarget(std::move(ti)) {} -}; - -std::unique_ptr Target::create(const LinkerOptions &lo) { - llvm::Triple t(lo._target); - // Create a TargetInfo. - std::unique_ptr ti(ELFTargetInfo::create(lo)); - - // Create the Target - if (t.getOS() == llvm::Triple::Linux && (t.getArch() == llvm::Triple::x86 || - t.getArch() == llvm::Triple::x86_64)) - return std::unique_ptr(new X86LinuxTarget(std::move(ti))); - else if (t.getArch() == llvm::Triple::hexagon) - return std::unique_ptr(new HexagonTarget(std::move(ti))); - return std::unique_ptr(); -} diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp index 68aa19b..167d92c 100644 --- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp @@ -18,6 +18,8 @@ #include "llvm/Support/ELF.h" namespace lld { +ELFTargetInfo::ELFTargetInfo(const LinkerOptions &lo) : TargetInfo(lo) {} + uint16_t ELFTargetInfo::getOutputType() const { switch (_options._outputKind) { case OutputKind::Executable: @@ -52,6 +54,23 @@ uint16_t ELFTargetInfo::getOutputMachine() const { } } +ErrorOr ELFTargetInfo::getReader(const LinkerInput &input) const { + if (!_reader) + _reader = createReaderELF(*this, std::bind(&ELFTargetInfo::getReader, this, + std::placeholders::_1)); + return *_reader; +} + +ErrorOr ELFTargetInfo::getWriter() const { + if (!_writer) { + if (_options._outputYAML) + _writer = createWriterYAML(*this); + else + _writer = createWriterELF(*this); + } + return *_writer; +} + std::unique_ptr ELFTargetInfo::create(const LinkerOptions &lo) { switch (llvm::Triple(llvm::Triple::normalize(lo._target)).getArch()) { case llvm::Triple::x86: diff --git a/lld/tools/lld-core/lld-core.cpp b/lld/tools/lld-core/lld-core.cpp index bec87e0..296d5d5 100644 --- a/lld/tools/lld-core/lld-core.cpp +++ b/lld/tools/lld-core/lld-core.cpp @@ -195,6 +195,15 @@ public: } return llvm::make_error_code(llvm::errc::invalid_argument); } + + virtual ErrorOr getReader(const LinkerInput &input) const { + llvm_unreachable("Unimplemented!"); + } + + virtual ErrorOr getWriter() const { + llvm_unreachable("Unimplemented!"); + } + private: bool _doStubs; bool _doGOT; -- 2.7.4