diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:19:15 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:19:15 +0000 |
commit | d93e1dfac8711cfed1a9d9cd1876a788b83945cd (patch) | |
tree | 5896fa6c02a262a6148b215487e545d937de58b7 /include | |
parent | 8d43286d630f9224de07809ea253e83ebb9cdee6 (diff) | |
download | src-d93e1dfac8711cfed1a9d9cd1876a788b83945cd.tar.gz src-d93e1dfac8711cfed1a9d9cd1876a788b83945cd.zip |
Vendor import of lld trunk r290819:vendor/lld/lld-trunk-r290819
Notes
Notes:
svn path=/vendor/lld/dist/; revision=311125
svn path=/vendor/lld/lld-trunk-r290819/; revision=311126; tag=vendor/lld/lld-trunk-r290819
Diffstat (limited to 'include')
-rw-r--r-- | include/lld/Config/Version.h | 34 | ||||
-rw-r--r-- | include/lld/Config/Version.inc.in | 1 | ||||
-rw-r--r-- | include/lld/Core/Atom.h | 16 | ||||
-rw-r--r-- | include/lld/Core/DefinedAtom.h | 4 | ||||
-rw-r--r-- | include/lld/Core/LinkingContext.h | 21 | ||||
-rw-r--r-- | include/lld/Core/Node.h | 11 | ||||
-rw-r--r-- | include/lld/Core/Parallel.h | 69 | ||||
-rw-r--r-- | include/lld/Core/Pass.h | 13 | ||||
-rw-r--r-- | include/lld/Core/PassManager.h | 2 | ||||
-rw-r--r-- | include/lld/Core/Reader.h | 17 | ||||
-rw-r--r-- | include/lld/Core/Reference.h | 10 | ||||
-rw-r--r-- | include/lld/Core/Reproduce.h | 73 | ||||
-rw-r--r-- | include/lld/Core/Simple.h | 83 | ||||
-rw-r--r-- | include/lld/Core/SymbolTable.h | 10 | ||||
-rw-r--r-- | include/lld/Driver/Driver.h | 2 | ||||
-rw-r--r-- | include/lld/ReaderWriter/MachOLinkingContext.h | 6 | ||||
-rw-r--r-- | include/lld/Support/Memory.h | 63 |
17 files changed, 264 insertions, 171 deletions
diff --git a/include/lld/Config/Version.h b/include/lld/Config/Version.h index 41433c1175ef..1cec3cc7678c 100644 --- a/include/lld/Config/Version.h +++ b/include/lld/Config/Version.h @@ -6,11 +6,9 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines version macros and version-related utility functions -/// for lld. -/// +// +// Defines a version-related utility function. +// //===----------------------------------------------------------------------===// #ifndef LLD_VERSION_H @@ -18,34 +16,10 @@ #include "lld/Config/Version.inc" #include "llvm/ADT/StringRef.h" -#include <string> - -/// \brief Helper macro for LLD_VERSION_STRING. -#define LLD_MAKE_VERSION_STRING2(X) #X - -/// \brief Helper macro for LLD_VERSION_STRING. -#define LLD_MAKE_VERSION_STRING(X, Y) LLD_MAKE_VERSION_STRING2(X.Y) - -/// \brief A string that describes the lld version number, e.g., "1.0". -#define LLD_VERSION_STRING \ - LLD_MAKE_VERSION_STRING(LLD_VERSION_MAJOR, LLD_VERSION_MINOR) namespace lld { -/// \brief Retrieves the repository path (e.g., Subversion path) that -/// identifies the particular lld branch, tag, or trunk from which this -/// lld was built. -llvm::StringRef getLLDRepositoryPath(); - -/// \brief Retrieves the repository revision number (or identifer) from which -/// this lld was built. -llvm::StringRef getLLDRevision(); - -/// \brief Retrieves the full repository version that is an amalgamation of -/// the information in getLLDRepositoryPath() and getLLDRevision(). -std::string getLLDRepositoryVersion(); - /// \brief Retrieves a string representing the complete lld version. -llvm::StringRef getLLDVersion(); +std::string getLLDVersion(); } #endif // LLD_VERSION_H diff --git a/include/lld/Config/Version.inc.in b/include/lld/Config/Version.inc.in index c893a56686c0..2789a5c46089 100644 --- a/include/lld/Config/Version.inc.in +++ b/include/lld/Config/Version.inc.in @@ -1,4 +1,5 @@ #define LLD_VERSION @LLD_VERSION@ +#define LLD_VERSION_STRING "@LLD_VERSION@" #define LLD_VERSION_MAJOR @LLD_VERSION_MAJOR@ #define LLD_VERSION_MINOR @LLD_VERSION_MINOR@ #define LLD_REVISION_STRING "@LLD_REVISION@" diff --git a/include/lld/Core/Atom.h b/include/lld/Core/Atom.h index 42ca2bb8af8c..156a5d4a736f 100644 --- a/include/lld/Core/Atom.h +++ b/include/lld/Core/Atom.h @@ -1,4 +1,4 @@ -//===- Core/Atom.h - A node in linking graph ------------------------------===// +//===- Core/Atom.h - A node in linking graph --------------------*- C++ -*-===// // // The LLVM Linker // @@ -11,6 +11,7 @@ #define LLD_CORE_ATOM_H #include "lld/Core/LLVM.h" +#include "llvm/ADT/StringRef.h" namespace lld { @@ -28,6 +29,7 @@ class OwningAtomPtr; /// class Atom { template<typename T> friend class OwningAtomPtr; + public: /// Whether this atom is defined or a proxy for an undefined symbol enum Definition { @@ -47,7 +49,6 @@ public: /// loader (e.g. visibility=default). }; - /// file - returns the File that produced/owns this Atom virtual const File& file() const = 0; @@ -69,7 +70,7 @@ protected: /// object. Therefore, no one but the owning File object should call /// delete on an Atom. In fact, some File objects may bulk allocate /// an array of Atoms, so they cannot be individually deleted by anyone. - virtual ~Atom() {} + virtual ~Atom() = default; private: Definition _definition; @@ -81,9 +82,10 @@ template<typename T> class OwningAtomPtr { private: OwningAtomPtr(const OwningAtomPtr &) = delete; - void operator=(const OwningAtomPtr&) = delete; + void operator=(const OwningAtomPtr &) = delete; + public: - OwningAtomPtr() : atom(nullptr) { } + OwningAtomPtr() = default; OwningAtomPtr(T *atom) : atom(atom) { } ~OwningAtomPtr() { @@ -121,9 +123,9 @@ public: } private: - T *atom; + T *atom = nullptr; }; -} // namespace lld +} // end namespace lld #endif // LLD_CORE_ATOM_H diff --git a/include/lld/Core/DefinedAtom.h b/include/lld/Core/DefinedAtom.h index e3193f8aaf2e..7f623d2ea5e6 100644 --- a/include/lld/Core/DefinedAtom.h +++ b/include/lld/Core/DefinedAtom.h @@ -354,10 +354,6 @@ public: return atomContentType == typeCFI; } - // Returns true if lhs should be placed before rhs in the final output. - static bool compareByPosition(const DefinedAtom *lhs, - const DefinedAtom *rhs); - protected: // DefinedAtom is an abstract base class. Only subclasses can access // constructor. diff --git a/include/lld/Core/LinkingContext.h b/include/lld/Core/LinkingContext.h index 7e4edaf22cf3..b3a999b00fbd 100644 --- a/include/lld/Core/LinkingContext.h +++ b/include/lld/Core/LinkingContext.h @@ -1,4 +1,4 @@ -//===- lld/Core/LinkingContext.h - Linker Target Info Interface -----------===// +//===- lld/Core/LinkingContext.h - Linker Target Info Interface -*- C++ -*-===// // // The LLVM Linker // @@ -10,17 +10,21 @@ #ifndef LLD_CORE_LINKING_CONTEXT_H #define LLD_CORE_LINKING_CONTEXT_H -#include "lld/Core/Error.h" -#include "lld/Core/LLVM.h" #include "lld/Core/Node.h" -#include "lld/Core/Reference.h" #include "lld/Core/Reader.h" -#include "llvm/Support/ErrorOr.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" +#include <cassert> +#include <cstdint> +#include <memory> #include <string> #include <vector> namespace lld { + class PassManager; class File; class Writer; @@ -117,12 +121,15 @@ public: void setDeadStripping(bool enable) { _deadStrip = enable; } void setGlobalsAreDeadStripRoots(bool v) { _globalsAreDeadStripRoots = v; } + void setPrintRemainingUndefines(bool print) { _printRemainingUndefines = print; } + void setAllowRemainingUndefines(bool allow) { _allowRemainingUndefines = allow; } + void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; } void setLogInputFiles(bool log) { _logInputFiles = log; } @@ -149,7 +156,7 @@ public: /// during link. Flavors can override this function in their LinkingContext /// to add more internal files. These internal files are positioned before /// the actual input files. - virtual void createInternalFiles(std::vector<std::unique_ptr<File> > &) const; + virtual void createInternalFiles(std::vector<std::unique_ptr<File>> &) const; /// Return the list of undefined symbols that are specified in the /// linker command line, using the -u option. @@ -248,4 +255,4 @@ private: } // end namespace lld -#endif +#endif // LLD_CORE_LINKING_CONTEXT_H diff --git a/include/lld/Core/Node.h b/include/lld/Core/Node.h index 8de0ecdbba6a..c30482409e7a 100644 --- a/include/lld/Core/Node.h +++ b/include/lld/Core/Node.h @@ -1,4 +1,4 @@ -//===- lld/Core/Node.h - Input file class ---------------------------------===// +//===- lld/Core/Node.h - Input file class -----------------------*- C++ -*-===// // // The LLVM Linker // @@ -17,9 +17,8 @@ #define LLD_CORE_NODE_H #include "lld/Core/File.h" -#include "llvm/Option/ArgList.h" +#include <algorithm> #include <memory> -#include <vector> namespace lld { @@ -29,8 +28,10 @@ namespace lld { class Node { public: enum class Kind { File, GroupEnd }; + explicit Node(Kind type) : _kind(type) {} - virtual ~Node() {} + virtual ~Node() = default; + virtual Kind kind() const { return _kind; } private: @@ -69,6 +70,6 @@ protected: std::unique_ptr<File> _file; }; -} // namespace lld +} // end namespace lld #endif // LLD_CORE_NODE_H diff --git a/include/lld/Core/Parallel.h b/include/lld/Core/Parallel.h index 2dde97d9e3f0..f241453a4d39 100644 --- a/include/lld/Core/Parallel.h +++ b/include/lld/Core/Parallel.h @@ -121,7 +121,7 @@ public: // Spawn all but one of the threads in another thread as spawning threads // can take a while. std::thread([&, threadCount] { - for (std::size_t i = 1; i < threadCount; ++i) { + for (size_t i = 1; i < threadCount; ++i) { std::thread([=] { work(); }).detach(); @@ -270,26 +270,65 @@ template <class T> void parallel_sort(T *start, T *end) { } #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 -template <class Iterator, class Func> -void parallel_for_each(Iterator begin, Iterator end, Func func) { - std::for_each(begin, end, func); +template <class IterTy, class FuncTy> +void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) { + std::for_each(Begin, End, Fn); +} + +template <class IndexTy, class FuncTy> +void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) { + for (IndexTy I = Begin; I != End; ++I) + Fn(I); } #elif defined(_MSC_VER) // Use ppl parallel_for_each on Windows. -template <class Iterator, class Func> -void parallel_for_each(Iterator begin, Iterator end, Func func) { - concurrency::parallel_for_each(begin, end, func); +template <class IterTy, class FuncTy> +void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) { + concurrency::parallel_for_each(Begin, End, Fn); +} + +template <class IndexTy, class FuncTy> +void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) { + concurrency::parallel_for(Begin, End, Fn); } #else -template <class Iterator, class Func> -void parallel_for_each(Iterator begin, Iterator end, Func func) { - TaskGroup tg; - ptrdiff_t taskSize = 1024; - while (taskSize <= std::distance(begin, end)) { - tg.spawn([=, &func] { std::for_each(begin, begin + taskSize, func); }); - begin += taskSize; +template <class IterTy, class FuncTy> +void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) { + // TaskGroup has a relatively high overhead, so we want to reduce + // the number of spawn() calls. We'll create up to 1024 tasks here. + // (Note that 1024 is an arbitrary number. This code probably needs + // improving to take the number of available cores into account.) + ptrdiff_t TaskSize = std::distance(Begin, End) / 1024; + if (TaskSize == 0) + TaskSize = 1; + + TaskGroup Tg; + while (TaskSize <= std::distance(Begin, End)) { + Tg.spawn([=, &Fn] { std::for_each(Begin, Begin + TaskSize, Fn); }); + Begin += TaskSize; } - std::for_each(begin, end, func); + Tg.spawn([=, &Fn] { std::for_each(Begin, End, Fn); }); +} + +template <class IndexTy, class FuncTy> +void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) { + ptrdiff_t TaskSize = (End - Begin) / 1024; + if (TaskSize == 0) + TaskSize = 1; + + TaskGroup Tg; + IndexTy I = Begin; + for (; I < End; I += TaskSize) { + Tg.spawn([=, &Fn] { + for (IndexTy J = I, E = I + TaskSize; J != E; ++J) + Fn(J); + }); + Begin += TaskSize; + } + Tg.spawn([=, &Fn] { + for (IndexTy J = I; J < End; ++J) + Fn(J); + }); } #endif } // end namespace lld diff --git a/include/lld/Core/Pass.h b/include/lld/Core/Pass.h index 0527f02cd362..bfe3f9b10e0c 100644 --- a/include/lld/Core/Pass.h +++ b/include/lld/Core/Pass.h @@ -1,4 +1,4 @@ -//===------ Core/Pass.h - Base class for linker passes --------------------===// +//===------ Core/Pass.h - Base class for linker passes ----------*- C++ -*-===// // // The LLVM Linker // @@ -10,13 +10,10 @@ #ifndef LLD_CORE_PASS_H #define LLD_CORE_PASS_H -#include "lld/Core/Atom.h" -#include "lld/Core/File.h" -#include "lld/Core/Reference.h" #include "llvm/Support/Error.h" -#include <vector> namespace lld { + class SimpleFile; /// Once the core linking is done (which resolves references, coalesces atoms @@ -31,16 +28,16 @@ class SimpleFile; /// new Atoms to the graph using the File's addAtom() method. class Pass { public: - virtual ~Pass() { } + virtual ~Pass() = default; /// Do the actual work of the Pass. virtual llvm::Error perform(SimpleFile &mergedFile) = 0; protected: // Only subclassess can be instantiated. - Pass() { } + Pass() = default; }; -} // namespace lld +} // end namespace lld #endif // LLD_CORE_PASS_H diff --git a/include/lld/Core/PassManager.h b/include/lld/Core/PassManager.h index 71a25cc7f3cd..09b417a2985d 100644 --- a/include/lld/Core/PassManager.h +++ b/include/lld/Core/PassManager.h @@ -36,7 +36,7 @@ public: for (std::unique_ptr<Pass> &pass : _passes) if (llvm::Error EC = pass->perform(file)) return EC; - return llvm::Error(); + return llvm::Error::success(); } private: diff --git a/include/lld/Core/Reader.h b/include/lld/Core/Reader.h index 66df4380dc76..5105eb1aa2be 100644 --- a/include/lld/Core/Reader.h +++ b/include/lld/Core/Reader.h @@ -12,9 +12,10 @@ #include "lld/Core/LLVM.h" #include "lld/Core/Reference.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/YAMLTraits.h" -#include <functional> +#include "llvm/Support/MemoryBuffer.h" #include <memory> #include <vector> @@ -23,10 +24,11 @@ using llvm::sys::fs::file_magic; namespace llvm { namespace yaml { class IO; -} -} +} // end namespace yaml +} // end namespace llvm namespace lld { + class File; class LinkingContext; class MachOLinkingContext; @@ -37,7 +39,7 @@ class MachOLinkingContext; /// Each file format (e.g. mach-o, etc) has a concrete subclass of Reader. class Reader { public: - virtual ~Reader() {} + virtual ~Reader() = default; /// Sniffs the file to determine if this Reader can parse it. /// The method is called with: @@ -52,7 +54,6 @@ public: loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &) const = 0; }; - /// \brief An abstract class for handling alternate yaml representations /// of object files. /// @@ -74,7 +75,6 @@ public: virtual bool handledDocTag(llvm::yaml::IO &io, const lld::File *&f) const = 0; }; - /// A registry to hold the list of currently registered Readers and /// tables which map Reference kind values to strings. /// The linker does not directly invoke Readers. Instead, it registers @@ -127,7 +127,6 @@ public: void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch, const KindStrings array[]); - private: struct KindEntry { Reference::KindNamespace ns; @@ -154,4 +153,4 @@ private: } // end namespace lld -#endif +#endif // LLD_CORE_READER_H diff --git a/include/lld/Core/Reference.h b/include/lld/Core/Reference.h index 86de4f6a4236..1d3003c84616 100644 --- a/include/lld/Core/Reference.h +++ b/include/lld/Core/Reference.h @@ -1,4 +1,4 @@ -//===- Core/References.h - A Reference to Another Atom --------------------===// +//===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===// // // The LLVM Linker // @@ -10,10 +10,10 @@ #ifndef LLD_CORE_REFERENCES_H #define LLD_CORE_REFERENCES_H -#include "lld/Core/LLVM.h" -#include "llvm/ADT/StringSwitch.h" +#include <cstdint> namespace lld { + class Atom; /// @@ -107,13 +107,13 @@ protected: /// object. Therefore, no one but the owning File object should call /// delete on an Reference. In fact, some File objects may bulk allocate /// an array of References, so they cannot be individually deleted by anyone. - virtual ~Reference() {} + virtual ~Reference() = default; KindValue _kindValue; uint8_t _kindNamespace; uint8_t _kindArch; }; -} // namespace lld +} // end namespace lld #endif // LLD_CORE_REFERENCES_H diff --git a/include/lld/Core/Reproduce.h b/include/lld/Core/Reproduce.h new file mode 100644 index 000000000000..cf2747493834 --- /dev/null +++ b/include/lld/Core/Reproduce.h @@ -0,0 +1,73 @@ +//===- Reproduce.h - Utilities for creating reproducers ---------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_REPRODUCE_H +#define LLD_CORE_REPRODUCE_H + +#include "lld/Core/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/Error.h" + +namespace llvm { + +class raw_fd_ostream; + +namespace opt { class Arg; } + +} + +namespace lld { + +// This class creates a .cpio file for --reproduce (ELF) or /linkrepro (COFF). +// +// If "--reproduce foo" is given, we create a file "foo.cpio" and +// copy all input files to the archive, along with a response file +// to re-run the same command with the same inputs. +// It is useful for reporting issues to LLD developers. +// +// Cpio as a file format is a deliberate choice. It's standardized in +// POSIX and very easy to create. cpio command is available virtually +// on all Unix systems. See +// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_07 +// for the format details. +class CpioFile { +public: + static ErrorOr<CpioFile *> create(StringRef OutputPath); + void append(StringRef Path, StringRef Data); + +private: + CpioFile(std::unique_ptr<llvm::raw_fd_ostream> OS, StringRef Basename); + + std::unique_ptr<llvm::raw_fd_ostream> OS; + llvm::StringSet<> Seen; + std::string Basename; +}; + +// Makes a given pathname an absolute path first, and then remove +// beginning /. For example, "../foo.o" is converted to "home/john/foo.o", +// assuming that the current directory is "/home/john/bar". +std::string relativeToRoot(StringRef Path); + +// Quote a given string if it contains a space character. +std::string quote(StringRef S); + +// Rewrite the given path if a file exists with that pathname, otherwise +// returns the original path. +std::string rewritePath(StringRef S); + +// Returns the string form of the given argument. +std::string stringize(llvm::opt::Arg *Arg); + +// Replaces backslashes with slashes if Windows. +std::string convertToUnixPathSeparator(StringRef S); +} + +#endif diff --git a/include/lld/Core/Simple.h b/include/lld/Core/Simple.h index f75b40327db4..3aa7abf5d12b 100644 --- a/include/lld/Core/Simple.h +++ b/include/lld/Core/Simple.h @@ -25,6 +25,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -111,19 +112,17 @@ private: AtomVector<AbsoluteAtom> _absolute; }; -class SimpleReference : public Reference { +class SimpleReference : public Reference, + public llvm::ilist_node<SimpleReference> { public: SimpleReference(Reference::KindNamespace ns, Reference::KindArch arch, Reference::KindValue value, uint64_t off, const Atom *t, Reference::Addend a) - : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a), - _next(nullptr), _prev(nullptr) { + : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a) { } SimpleReference() : Reference(Reference::KindNamespace::all, Reference::KindArch::all, 0), - _target(nullptr), _offsetInAtom(0), _addend(0), _next(nullptr), - _prev(nullptr) { - } + _target(nullptr), _offsetInAtom(0), _addend(0) {} uint64_t offsetInAtom() const override { return _offsetInAtom; } @@ -135,72 +134,17 @@ public: Addend addend() const override { return _addend; } void setAddend(Addend a) override { _addend = a; } void setTarget(const Atom *newAtom) override { _target = newAtom; } - SimpleReference *getNext() const { return _next; } - SimpleReference *getPrev() const { return _prev; } - void setNext(SimpleReference *n) { _next = n; } - void setPrev(SimpleReference *p) { _prev = p; } private: const Atom *_target; uint64_t _offsetInAtom; Addend _addend; - SimpleReference *_next; - SimpleReference *_prev; -}; - -} // end namespace lld - -// ilist will lazily create a sentinal (so end() can return a node past the -// end of the list). We need this trait so that the sentinal is allocated -// via the BumpPtrAllocator. -namespace llvm { - -template<> -struct ilist_sentinel_traits<lld::SimpleReference> { - - ilist_sentinel_traits() : _allocator(nullptr) { } - - void setAllocator(llvm::BumpPtrAllocator *alloc) { - _allocator = alloc; - } - - lld::SimpleReference *createSentinel() const { - return new (*_allocator) lld::SimpleReference(); - } - - static void destroySentinel(lld::SimpleReference*) {} - - static lld::SimpleReference *provideInitialHead() { return nullptr; } - - lld::SimpleReference *ensureHead(lld::SimpleReference *&head) const { - if (!head) { - head = createSentinel(); - noteHead(head, head); - ilist_traits<lld::SimpleReference>::setNext(head, nullptr); - return head; - } - return ilist_traits<lld::SimpleReference>::getPrev(head); - } - - void noteHead(lld::SimpleReference *newHead, - lld::SimpleReference *sentinel) const { - ilist_traits<lld::SimpleReference>::setPrev(newHead, sentinel); - } - -private: - mutable llvm::BumpPtrAllocator *_allocator; }; -} // end namespace llvm - -namespace lld { - class SimpleDefinedAtom : public DefinedAtom { public: explicit SimpleDefinedAtom(const File &f) - : _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) { - _references.setAllocator(&f.allocator()); - } + : _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {} ~SimpleDefinedAtom() override { _references.clearAndLeakNodesUnsafely(); @@ -232,23 +176,26 @@ public: } DefinedAtom::reference_iterator begin() const override { - const void *it = reinterpret_cast<const void *>(&*_references.begin()); + const void *it = + reinterpret_cast<const void *>(_references.begin().getNodePtr()); return reference_iterator(*this, it); } DefinedAtom::reference_iterator end() const override { - const void *it = reinterpret_cast<const void *>(&*_references.end()); + const void *it = + reinterpret_cast<const void *>(_references.end().getNodePtr()); return reference_iterator(*this, it); } const Reference *derefIterator(const void *it) const override { - return reinterpret_cast<const Reference*>(it); + return &*RefList::const_iterator( + *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it)); } void incrementIterator(const void *&it) const override { - const SimpleReference* node = reinterpret_cast<const SimpleReference*>(it); - const SimpleReference* next = node->getNext(); - it = reinterpret_cast<const void*>(next); + RefList::const_iterator ref( + *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it)); + it = reinterpret_cast<const void *>(std::next(ref).getNodePtr()); } void addReference(Reference::KindNamespace ns, diff --git a/include/lld/Core/SymbolTable.h b/include/lld/Core/SymbolTable.h index db610ad14066..ba4951e5bd13 100644 --- a/include/lld/Core/SymbolTable.h +++ b/include/lld/Core/SymbolTable.h @@ -46,22 +46,12 @@ public: /// @brief add atom to symbol table bool add(const AbsoluteAtom &); - /// @brief checks if name is in symbol table and if so atom is not - /// UndefinedAtom - bool isDefined(StringRef sym); - /// @brief returns atom in symbol table for specified name (or nullptr) const Atom *findByName(StringRef sym); /// @brief returns vector of remaining UndefinedAtoms std::vector<const UndefinedAtom *> undefines(); - /// returns vector of tentative definitions - std::vector<StringRef> tentativeDefinitions(); - - /// @brief add atom to replacement table - void addReplacement(const Atom *replaced, const Atom *replacement); - /// @brief if atom has been coalesced away, return replacement, else return atom const Atom *replacement(const Atom *); diff --git a/include/lld/Driver/Driver.h b/include/lld/Driver/Driver.h index 312f4f812b77..a3265c85716a 100644 --- a/include/lld/Driver/Driver.h +++ b/include/lld/Driver/Driver.h @@ -19,7 +19,7 @@ bool link(llvm::ArrayRef<const char *> Args); } namespace elf { -bool link(llvm::ArrayRef<const char *> Args, +bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, llvm::raw_ostream &Diag = llvm::errs()); } diff --git a/include/lld/ReaderWriter/MachOLinkingContext.h b/include/lld/ReaderWriter/MachOLinkingContext.h index 7b673f0dad3e..a9e80f50b23d 100644 --- a/include/lld/ReaderWriter/MachOLinkingContext.h +++ b/include/lld/ReaderWriter/MachOLinkingContext.h @@ -377,6 +377,10 @@ public: uint32_t dylibCompatVersion(StringRef installName) const; + ArrayRef<mach_o::MachODylibFile*> allDylibs() const { + return _allDylibs; + } + /// Creates a copy (owned by this MachOLinkingContext) of a string. StringRef copy(StringRef str) { return str.copy(_allocator); } @@ -485,7 +489,7 @@ private: mutable std::unique_ptr<Writer> _writer; std::vector<SectionAlign> _sectAligns; mutable llvm::StringMap<mach_o::MachODylibFile*> _pathToDylibMap; - mutable std::set<mach_o::MachODylibFile*> _allDylibs; + mutable std::vector<mach_o::MachODylibFile*> _allDylibs; mutable std::set<mach_o::MachODylibFile*> _upwardDylibs; mutable std::vector<std::unique_ptr<File>> _indirectDylibs; mutable std::mutex _dylibsMutex; diff --git a/include/lld/Support/Memory.h b/include/lld/Support/Memory.h new file mode 100644 index 000000000000..46db4a39f696 --- /dev/null +++ b/include/lld/Support/Memory.h @@ -0,0 +1,63 @@ +//===- Memory.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines arena allocators. +// +// Almost all large objects, such as files, sections or symbols, are +// used for the entire lifetime of the linker once they are created. +// This usage characteristic makes arena allocator an attractive choice +// where the entire linker is one arena. With an arena, newly created +// objects belong to the arena and freed all at once when everything is done. +// Arena allocators are efficient and easy to understand. +// Most objects are allocated using the arena allocators defined by this file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_MEMORY_H +#define LLD_MEMORY_H + +#include "llvm/Support/Allocator.h" +#include "llvm/Support/StringSaver.h" +#include <vector> + +namespace lld { + +// Use this arena if your object doesn't have a destructor. +extern llvm::BumpPtrAllocator BAlloc; +extern llvm::StringSaver Saver; + +// These two classes are hack to keep track of all +// SpecificBumpPtrAllocator instances. +struct SpecificAllocBase { + SpecificAllocBase() { Instances.push_back(this); } + virtual ~SpecificAllocBase() = default; + virtual void reset() = 0; + static std::vector<SpecificAllocBase *> Instances; +}; + +template <class T> struct SpecificAlloc : public SpecificAllocBase { + void reset() override { Alloc.DestroyAll(); } + llvm::SpecificBumpPtrAllocator<T> Alloc; +}; + +// Use this arena if your object has a destructor. +// Your destructor will be invoked from freeArena(). +template <typename T, typename... U> inline T *make(U &&... Args) { + static SpecificAlloc<T> Alloc; + return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...); +} + +inline void freeArena() { + for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances) + Alloc->reset(); + BAlloc.Reset(); +} +} + +#endif |