diff options
Diffstat (limited to 'lld/include')
-rw-r--r-- | lld/include/lld/Common/DWARF.h | 2 | ||||
-rw-r--r-- | lld/include/lld/Common/Driver.h | 5 | ||||
-rw-r--r-- | lld/include/lld/Common/Memory.h | 13 | ||||
-rw-r--r-- | lld/include/lld/Common/Strings.h | 46 | ||||
-rw-r--r-- | lld/include/lld/Common/Threads.h | 92 | ||||
-rw-r--r-- | lld/include/lld/Common/Timer.h | 10 | ||||
-rw-r--r-- | lld/include/lld/Common/Version.inc.in | 5 | ||||
-rw-r--r-- | lld/include/lld/Core/File.h | 2 | ||||
-rw-r--r-- | lld/include/lld/Core/Reference.h | 2 | ||||
-rw-r--r-- | lld/include/lld/ReaderWriter/MachOLinkingContext.h | 6 |
10 files changed, 68 insertions, 115 deletions
diff --git a/lld/include/lld/Common/DWARF.h b/lld/include/lld/Common/DWARF.h index f0d3d2fbda77..b77985a6919d 100644 --- a/lld/include/lld/Common/DWARF.h +++ b/lld/include/lld/Common/DWARF.h @@ -31,6 +31,8 @@ public: llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef name); + llvm::DWARFContext *getContext() { return dwarf.get(); } + private: std::unique_ptr<llvm::DWARFContext> dwarf; std::vector<const llvm::DWARFDebugLine::LineTable *> lineTables; diff --git a/lld/include/lld/Common/Driver.h b/lld/include/lld/Common/Driver.h index 0a358d8aff6b..6db3d234eb56 100644 --- a/lld/include/lld/Common/Driver.h +++ b/lld/include/lld/Common/Driver.h @@ -33,6 +33,11 @@ bool link(llvm::ArrayRef<const char *> args, bool canExitEarly, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS); } +namespace macho { +bool link(llvm::ArrayRef<const char *> args, bool canExitEarly, + llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS); +} + namespace wasm { bool link(llvm::ArrayRef<const char *> args, bool canExitEarly, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS); diff --git a/lld/include/lld/Common/Memory.h b/lld/include/lld/Common/Memory.h index 41d8f15d7b34..f516a327cfb2 100644 --- a/lld/include/lld/Common/Memory.h +++ b/lld/include/lld/Common/Memory.h @@ -47,11 +47,20 @@ template <class T> struct SpecificAlloc : public SpecificAllocBase { llvm::SpecificBumpPtrAllocator<T> alloc; }; +// Use a static local for these singletons so they are only registered if an +// object of this instance is ever constructed. Otherwise we will create and +// register ELF allocators for COFF and the reverse. +template <typename T> +inline llvm::SpecificBumpPtrAllocator<T> &getSpecificAllocSingleton() { + static SpecificAlloc<T> instance; + return instance.alloc; +} + // Use this arena if your object has a destructor. // Your destructor will be invoked from freeArena(). template <typename T, typename... U> T *make(U &&... args) { - static SpecificAlloc<T> alloc; - return new (alloc.alloc.Allocate()) T(std::forward<U>(args)...); + return new (getSpecificAllocSingleton<T>().Allocate()) + T(std::forward<U>(args)...); } } // namespace lld diff --git a/lld/include/lld/Common/Strings.h b/lld/include/lld/Common/Strings.h index 9d002bf336de..3940d2443cd4 100644 --- a/lld/include/lld/Common/Strings.h +++ b/lld/include/lld/Common/Strings.h @@ -27,16 +27,52 @@ bool isValidCIdentifier(llvm::StringRef s); // Write the contents of the a buffer to a file void saveBuffer(llvm::StringRef buffer, const llvm::Twine &path); -// This class represents multiple glob patterns. -class StringMatcher { +// A single pattern to match against. A pattern can either be double-quoted +// text that should be matched exactly after removing the quoting marks or a +// glob pattern in the sense of GlobPattern. +class SingleStringMatcher { public: - StringMatcher() = default; - explicit StringMatcher(llvm::ArrayRef<llvm::StringRef> pat); + // Create a StringPattern from Pattern to be matched exactly irregardless + // of globbing characters if ExactMatch is true. + SingleStringMatcher(llvm::StringRef Pattern); + // Match s against this pattern, exactly if ExactMatch is true. bool match(llvm::StringRef s) const; private: - std::vector<llvm::GlobPattern> patterns; + // Whether to do an exact match irregardless of the presence of wildcard + // character. + bool ExactMatch; + + // GlobPattern object if not doing an exact match. + llvm::GlobPattern GlobPatternMatcher; + + // StringRef to match exactly if doing an exact match. + llvm::StringRef ExactPattern; +}; + +// This class represents multiple patterns to match against. A pattern can +// either be a double-quoted text that should be matched exactly after removing +// the quoted marks or a glob pattern. +class StringMatcher { +private: + // Patterns to match against. + std::vector<SingleStringMatcher> patterns; + +public: + StringMatcher() = default; + + // Matcher for a single pattern. + StringMatcher(llvm::StringRef Pattern) + : patterns({SingleStringMatcher(Pattern)}) {} + + // Add a new pattern to the existing ones to match against. + void addPattern(SingleStringMatcher Matcher) { patterns.push_back(Matcher); } + + bool empty() { return patterns.empty(); } + + // Match s against the patterns. + bool match(llvm::StringRef s) const; }; } // namespace lld diff --git a/lld/include/lld/Common/Threads.h b/lld/include/lld/Common/Threads.h deleted file mode 100644 index 7834130fdf72..000000000000 --- a/lld/include/lld/Common/Threads.h +++ /dev/null @@ -1,92 +0,0 @@ -//===- Threads.h ------------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// LLD supports threads to distribute workloads to multiple cores. Using -// multicore is most effective when more than one core are idle. At the -// last step of a build, it is often the case that a linker is the only -// active process on a computer. So, we are naturally interested in using -// threads wisely to reduce latency to deliver results to users. -// -// That said, we don't want to do "too clever" things using threads. -// Complex multi-threaded algorithms are sometimes extremely hard to -// reason about and can easily mess up the entire design. -// -// Fortunately, when a linker links large programs (when the link time is -// most critical), it spends most of the time to work on massive number of -// small pieces of data of the same kind, and there are opportunities for -// large parallelism there. Here are examples: -// -// - We have hundreds of thousands of input sections that need to be -// copied to a result file at the last step of link. Once we fix a file -// layout, each section can be copied to its destination and its -// relocations can be applied independently. -// -// - We have tens of millions of small strings when constructing a -// mergeable string section. -// -// For the cases such as the former, we can just use parallelForEach -// instead of std::for_each (or a plain for loop). Because tasks are -// completely independent from each other, we can run them in parallel -// without any coordination between them. That's very easy to understand -// and reason about. -// -// For the cases such as the latter, we can use parallel algorithms to -// deal with massive data. We have to write code for a tailored algorithm -// for each problem, but the complexity of multi-threading is isolated in -// a single pass and doesn't affect the linker's overall design. -// -// The above approach seems to be working fairly well. As an example, when -// linking Chromium (output size 1.6 GB), using 4 cores reduces latency to -// 75% compared to single core (from 12.66 seconds to 9.55 seconds) on my -// Ivy Bridge Xeon 2.8 GHz machine. Using 40 cores reduces it to 63% (from -// 12.66 seconds to 7.95 seconds). Because of the Amdahl's law, the -// speedup is not linear, but as you add more cores, it gets faster. -// -// On a final note, if you are trying to optimize, keep the axiom "don't -// guess, measure!" in mind. Some important passes of the linker are not -// that slow. For example, resolving all symbols is not a very heavy pass, -// although it would be very hard to parallelize it. You want to first -// identify a slow pass and then optimize it. -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_COMMON_THREADS_H -#define LLD_COMMON_THREADS_H - -#include "llvm/Support/Parallel.h" -#include <functional> - -namespace lld { - -extern bool threadsEnabled; - -template <typename R, class FuncTy> void parallelForEach(R &&range, FuncTy fn) { - if (threadsEnabled) - for_each(llvm::parallel::par, std::begin(range), std::end(range), fn); - else - for_each(llvm::parallel::seq, std::begin(range), std::end(range), fn); -} - -inline void parallelForEachN(size_t begin, size_t end, - llvm::function_ref<void(size_t)> fn) { - if (threadsEnabled) - for_each_n(llvm::parallel::par, begin, end, fn); - else - for_each_n(llvm::parallel::seq, begin, end, fn); -} - -template <typename R, class FuncTy> void parallelSort(R &&range, FuncTy fn) { - if (threadsEnabled) - sort(llvm::parallel::par, std::begin(range), std::end(range), fn); - else - sort(llvm::parallel::seq, std::begin(range), std::end(range), fn); -} - -} // namespace lld - -#endif diff --git a/lld/include/lld/Common/Timer.h b/lld/include/lld/Common/Timer.h index 4a298b04a30b..95e811a2f9f0 100644 --- a/lld/include/lld/Common/Timer.h +++ b/lld/include/lld/Common/Timer.h @@ -12,6 +12,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include <assert.h> +#include <atomic> #include <chrono> #include <map> #include <memory> @@ -27,6 +28,8 @@ struct ScopedTimer { void stop(); + std::chrono::time_point<std::chrono::high_resolution_clock> startTime; + Timer *t = nullptr; }; @@ -36,8 +39,7 @@ public: static Timer &root(); - void start(); - void stop(); + void addToTotal(std::chrono::nanoseconds time) { total += time.count(); } void print(); double millis() const; @@ -46,11 +48,9 @@ private: explicit Timer(llvm::StringRef name); void print(int depth, double totalDuration, bool recurse = true) const; - std::chrono::time_point<std::chrono::high_resolution_clock> startTime; - std::chrono::nanoseconds total; + std::atomic<std::chrono::nanoseconds::rep> total; std::vector<Timer *> children; std::string name; - Timer *parent; }; } // namespace lld diff --git a/lld/include/lld/Common/Version.inc.in b/lld/include/lld/Common/Version.inc.in index 2789a5c46089..5cb48a546e11 100644 --- a/lld/include/lld/Common/Version.inc.in +++ b/lld/include/lld/Common/Version.inc.in @@ -1,6 +1 @@ -#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@" -#define LLD_REPOSITORY_STRING "@LLD_REPOSITORY@" diff --git a/lld/include/lld/Core/File.h b/lld/include/lld/Core/File.h index df014669eb62..bb4ca9cf5859 100644 --- a/lld/include/lld/Core/File.h +++ b/lld/include/lld/Core/File.h @@ -78,7 +78,7 @@ public: /// Returns the path of the archive file name if this file is instantiated /// from an archive file. Otherwise returns the empty string. StringRef archivePath() const { return _archivePath; } - void setArchivePath(StringRef path) { _archivePath = path; } + void setArchivePath(StringRef path) { _archivePath = std::string(path); } /// Returns the path name of this file. It doesn't include archive file name. StringRef memberPath() const { return _path; } diff --git a/lld/include/lld/Core/Reference.h b/lld/include/lld/Core/Reference.h index 4769882cde50..b104f8495474 100644 --- a/lld/include/lld/Core/Reference.h +++ b/lld/include/lld/Core/Reference.h @@ -91,7 +91,7 @@ public: /// Some relocations require a symbol and a value (e.g. foo + 4). virtual Addend addend() const = 0; - /// During linking, some optimzations may change addend value. + /// During linking, some optimizations may change addend value. virtual void setAddend(Addend) = 0; /// Returns target specific attributes of the reference. diff --git a/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/lld/include/lld/ReaderWriter/MachOLinkingContext.h index cd57604fa17d..974f323bc612 100644 --- a/lld/include/lld/ReaderWriter/MachOLinkingContext.h +++ b/lld/include/lld/ReaderWriter/MachOLinkingContext.h @@ -55,8 +55,8 @@ public: enum class ExportMode { globals, // Default, all global symbols exported. - whiteList, // -exported_symbol[s_list], only listed symbols exported. - blackList // -unexported_symbol[s_list], no listed symbol exported. + exported, // -exported_symbol[s_list], only listed symbols exported. + unexported // -unexported_symbol[s_list], no listed symbol exported. }; enum class DebugInfoMode { @@ -423,8 +423,6 @@ public: private: Writer &writer() const override; mach_o::MachODylibFile* loadIndirectDylib(StringRef path); - void checkExportWhiteList(const DefinedAtom *atom) const; - void checkExportBlackList(const DefinedAtom *atom) const; struct ArchInfo { StringRef archName; MachOLinkingContext::Arch arch; |