[Driver] Replace Target with TargetInfo. Simplify LinkerInput.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Thu, 7 Feb 2013 06:46:48 +0000 (06:46 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Thu, 7 Feb 2013 06:46:48 +0000 (06:46 +0000)
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

12 files changed:
lld/include/lld/Core/LinkerOptions.h
lld/include/lld/Core/TargetInfo.h
lld/include/lld/Driver/Target.h [deleted file]
lld/include/lld/ReaderWriter/ELFTargetInfo.h
lld/include/lld/ReaderWriter/MachOTargetInfo.h
lld/lib/Driver/CMakeLists.txt
lld/lib/Driver/Drivers.cpp
lld/lib/Driver/LinkerInvocation.cpp
lld/lib/Driver/Target.cpp [deleted file]
lld/lib/Driver/Targets.cpp [deleted file]
lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
lld/tools/lld-core/lld-core.cpp

index 968ca4e..2eba90c 100644 (file)
 #include <vector>
 
 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<llvm::MemoryBuffer> buffer,
-              InputKind kind = InputKind::Unknown)
-    : _buffer(std::move(buffer))
-    , _file(_buffer->getBufferIdentifier())
-    , _kind(kind) {}
+  LinkerInput(std::unique_ptr<llvm::MemoryBuffer> 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<InputKind> getKind() const {
-    if (_kind == InputKind::Unknown) {
-      _kind = llvm::StringSwitch<InputKind>(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<llvm::MemoryBuffer> _buffer;
   std::string _file;
-  mutable InputKind _kind;
 };
 
 enum OutputKind {
index 8d7adf7..ef2326d 100644 (file)
@@ -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<Reader &> getReader(const LinkerInput &input) const = 0;
+
+  /// \brief Get the writer.
+  virtual ErrorOr<Writer &> getWriter() const = 0;
+
   // TODO: Split out to TargetRelocationInfo.
   virtual ErrorOr<int32_t> 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 (file)
index b30d707..0000000
+++ /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 <memory>
-
-namespace lld {
-class LinkerInput;
-struct LinkerOptions;
-class Reader;
-class TargetInfo;
-class Writer;
-
-/// \brief Represents a specific target.
-class Target {
-protected:
-  Target(std::unique_ptr<TargetInfo> 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<lld::Reader&> getReader(const LinkerInput &input) = 0;
-
-  /// \brief Get the writer.
-  virtual ErrorOr<lld::Writer&> getWriter() = 0;
-
-  static std::unique_ptr<Target> create(const LinkerOptions&);
-
-protected:
-  std::unique_ptr<TargetInfo> _targetInfo;
-};
-}
-
-#endif
index 5a28ee5..058714f 100644 (file)
@@ -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<Reader &> getReader(const LinkerInput &input) const;
+
+  virtual ErrorOr<Writer &> getWriter() const;
+
   static std::unique_ptr<ELFTargetInfo> create(const LinkerOptions &lo);
 
   template <typename ELFT>
@@ -54,6 +61,8 @@ public:
 
 protected:
   std::unique_ptr<TargetHandlerBase> _targetHandler;
+  mutable std::unique_ptr<Reader> _reader;
+  mutable std::unique_ptr<Writer> _writer;
 };
 } // end namespace lld
 
index 9055316..7e8927b 100644 (file)
@@ -12,6 +12,8 @@
 
 #include "lld/Core/TargetInfo.h"
 
+#include "llvm/Support/ErrorHandling.h"
+
 #include <memory>
 
 namespace lld {
@@ -28,6 +30,14 @@ public:
 
   virtual uint64_t getPageZeroSize() const = 0;
 
+  virtual ErrorOr<Reader &> getReader(const LinkerInput &input) const {
+    llvm_unreachable("Unimplemented!");
+  }
+
+  virtual ErrorOr<Writer &> getWriter() const {
+    llvm_unreachable("Unimplemented!");
+  }
+
   static std::unique_ptr<MachOTargetInfo> create(const LinkerOptions &lo);
 };
 } // end namespace lld
index 83b3953..13e6298 100644 (file)
@@ -8,8 +8,6 @@ add_lld_library(lldDriver
   Driver.cpp
   Drivers.cpp
   LinkerInvocation.cpp
-  Target.cpp
-  Targets.cpp
   )
 
 add_dependencies(lldDriver DriverOptionsTableGen)
index 00085e6..3c143ef 100644 (file)
@@ -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);
index 1027403..6f50051 100644 (file)
@@ -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"
 
 
 using namespace lld;
 
+namespace {
+std::unique_ptr<TargetInfo> 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(Target::create(_options));
+  std::unique_ptr<TargetInfo> 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 (file)
index 8b90ebf..0000000
+++ /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 (file)
index 2e2bc59..0000000
+++ /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 <set>
-
-using namespace lld;
-using namespace std::placeholders;
-
-class ELFTarget : public Target {
-public:
-  ELFTarget(std::unique_ptr<ELFTargetInfo> ti)
-      : Target(std::unique_ptr<TargetInfo>(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<lld::Reader&> 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<lld::Writer&> getWriter() {
-    return _targetInfo->getLinkerOptions()._outputYAML ? *_writerYAML
-                                                       : *_writer;
-  }
-
-protected:
-  const ELFTargetInfo &_elfTargetInfo;
-  std::unique_ptr<lld::Reader> _readerELF, _readerYAML;
-  std::unique_ptr<lld::Writer> _writer, _writerYAML;
-};
-
-class X86LinuxTarget LLVM_FINAL : public ELFTarget {
-public:
-  X86LinuxTarget(std::unique_ptr<ELFTargetInfo> ti)
-      : ELFTarget(std::move(ti)) {}
-};
-
-class HexagonTarget LLVM_FINAL : public ELFTarget {
-public:
-  HexagonTarget(std::unique_ptr<ELFTargetInfo> ti)
-      : ELFTarget(std::move(ti)) {}
-};
-
-std::unique_ptr<Target> Target::create(const LinkerOptions &lo) {
-  llvm::Triple t(lo._target);
-  // Create a TargetInfo.
-  std::unique_ptr<ELFTargetInfo> 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<Target>(new X86LinuxTarget(std::move(ti)));
-  else if (t.getArch() == llvm::Triple::hexagon) 
-    return std::unique_ptr<Target>(new HexagonTarget(std::move(ti)));
-  return std::unique_ptr<Target>();
-}
index 68aa19b..167d92c 100644 (file)
@@ -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<Reader &> ELFTargetInfo::getReader(const LinkerInput &input) const {
+  if (!_reader)
+    _reader = createReaderELF(*this, std::bind(&ELFTargetInfo::getReader, this,
+                                               std::placeholders::_1));
+  return *_reader;
+}
+
+ErrorOr<Writer &> ELFTargetInfo::getWriter() const {
+  if (!_writer) {
+    if (_options._outputYAML)
+      _writer = createWriterYAML(*this);
+    else
+      _writer = createWriterELF(*this);
+  }
+  return *_writer;
+}
+
 std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(const LinkerOptions &lo) {
   switch (llvm::Triple(llvm::Triple::normalize(lo._target)).getArch()) {
   case llvm::Triple::x86:
index bec87e0..296d5d5 100644 (file)
@@ -195,6 +195,15 @@ public:
     }
     return llvm::make_error_code(llvm::errc::invalid_argument);
   }
+
+  virtual ErrorOr<Reader &> getReader(const LinkerInput &input) const {
+    llvm_unreachable("Unimplemented!");
+  }
+
+  virtual ErrorOr<Writer &> getWriter() const {
+    llvm_unreachable("Unimplemented!");
+  }
+
 private:
   bool              _doStubs;
   bool              _doGOT;