diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lld/Common | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lld/Common')
-rw-r--r-- | lld/Common/ErrorHandler.cpp | 41 | ||||
-rw-r--r-- | lld/Common/Filesystem.cpp | 36 | ||||
-rw-r--r-- | lld/Common/Reproduce.cpp | 6 | ||||
-rw-r--r-- | lld/Common/Strings.cpp | 31 | ||||
-rw-r--r-- | lld/Common/TargetOptionsCommandFlags.cpp | 25 | ||||
-rw-r--r-- | lld/Common/Threads.cpp | 11 | ||||
-rw-r--r-- | lld/Common/Timer.cpp | 29 | ||||
-rw-r--r-- | lld/Common/Version.cpp | 11 |
8 files changed, 111 insertions, 79 deletions
diff --git a/lld/Common/ErrorHandler.cpp b/lld/Common/ErrorHandler.cpp index b6066b557cbf..94ff23173d69 100644 --- a/lld/Common/ErrorHandler.cpp +++ b/lld/Common/ErrorHandler.cpp @@ -8,7 +8,7 @@ #include "lld/Common/ErrorHandler.h" -#include "lld/Common/Threads.h" +#include "llvm/Support/Parallel.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/DiagnosticInfo.h" @@ -62,8 +62,11 @@ void lld::exitLld(int val) { // avoid intermittent crashes on Windows when exiting. llvm_shutdown(); - lld::outs().flush(); - lld::errs().flush(); + { + std::lock_guard<std::mutex> lock(mu); + lld::outs().flush(); + lld::errs().flush(); + } _exit(val); } @@ -114,7 +117,7 @@ void lld::checkError(Error e) { // extracted from an error message using regexps. std::string ErrorHandler::getLocation(const Twine &msg) { if (!vsDiagnostics) - return logName; + return std::string(logName); static std::regex regexes[] = { std::regex( @@ -146,7 +149,7 @@ std::string ErrorHandler::getLocation(const Twine &msg) { return m.str(1) + "(" + m.str(2) + ")"; } - return logName; + return std::string(logName); } void ErrorHandler::log(const Twine &msg) { @@ -191,20 +194,26 @@ void ErrorHandler::error(const Twine &msg) { } } - std::lock_guard<std::mutex> lock(mu); + bool exit = false; + { + std::lock_guard<std::mutex> lock(mu); + + if (errorLimit == 0 || errorCount < errorLimit) { + lld::errs() << sep << getLocation(msg) << ": " << Colors::RED + << "error: " << Colors::RESET << msg << "\n"; + } else if (errorCount == errorLimit) { + lld::errs() << sep << getLocation(msg) << ": " << Colors::RED + << "error: " << Colors::RESET << errorLimitExceededMsg + << "\n"; + exit = exitEarly; + } - if (errorLimit == 0 || errorCount < errorLimit) { - lld::errs() << sep << getLocation(msg) << ": " << Colors::RED - << "error: " << Colors::RESET << msg << "\n"; - } else if (errorCount == errorLimit) { - lld::errs() << sep << getLocation(msg) << ": " << Colors::RED - << "error: " << Colors::RESET << errorLimitExceededMsg << "\n"; - if (exitEarly) - exitLld(1); + sep = getSeparator(msg); + ++errorCount; } - sep = getSeparator(msg); - ++errorCount; + if (exit) + exitLld(1); } void ErrorHandler::fatal(const Twine &msg) { diff --git a/lld/Common/Filesystem.cpp b/lld/Common/Filesystem.cpp index 75e88dbce1ab..671b352a3f6b 100644 --- a/lld/Common/Filesystem.cpp +++ b/lld/Common/Filesystem.cpp @@ -11,10 +11,11 @@ //===----------------------------------------------------------------------===// #include "lld/Common/Filesystem.h" -#include "lld/Common/Threads.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Parallel.h" +#include "llvm/Support/Path.h" #if LLVM_ON_UNIX #include <unistd.h> #endif @@ -39,12 +40,41 @@ using namespace lld; // This function spawns a background thread to remove the file. // The calling thread returns almost immediately. void lld::unlinkAsync(StringRef path) { + if (!sys::fs::exists(path) || !sys::fs::is_regular_file(path)) + return; + // Removing a file is async on windows. #if defined(_WIN32) + // On Windows co-operative programs can be expected to open LLD's + // output in FILE_SHARE_DELETE mode. This allows us to delete the + // file (by moving it to a temporary filename and then deleting + // it) so that we can link another output file that overwrites + // the existing file, even if the current file is in use. + // + // This is done on a best effort basis - we do not error if the + // operation fails. The consequence is merely that the user + // experiences an inconvenient work-flow. + // + // The code here allows LLD to work on all versions of Windows. + // However, at Windows 10 1903 it seems that the behavior of + // Windows has changed, so that we could simply delete the output + // file. This code should be simplified once support for older + // versions of Windows is dropped. + // + // Warning: It seems that the WINVER and _WIN32_WINNT preprocessor + // defines affect the behavior of the Windows versions of the calls + // we are using here. If this code stops working this is worth + // bearing in mind. + SmallString<128> tmpName; + if (!sys::fs::createUniqueFile(path + "%%%%%%%%.tmp", tmpName)) { + if (!sys::fs::rename(path, tmpName)) + path = tmpName; + else + sys::fs::remove(tmpName); + } sys::fs::remove(path); #else - if (!threadsEnabled || !sys::fs::exists(path) || - !sys::fs::is_regular_file(path)) + if (parallel::strategy.ThreadsRequested == 1) return; // We cannot just remove path from a different thread because we are now going diff --git a/lld/Common/Reproduce.cpp b/lld/Common/Reproduce.cpp index 24210c420418..00309f58b93f 100644 --- a/lld/Common/Reproduce.cpp +++ b/lld/Common/Reproduce.cpp @@ -24,7 +24,7 @@ using namespace llvm::sys; std::string lld::relativeToRoot(StringRef path) { SmallString<128> abs = path; if (fs::make_absolute(abs)) - return path; + return std::string(path); path::remove_dots(abs, /*remove_dot_dot=*/true); // This is Windows specific. root_name() returns a drive letter @@ -45,13 +45,13 @@ std::string lld::relativeToRoot(StringRef path) { std::string lld::quote(StringRef s) { if (s.contains(' ')) return ("\"" + s + "\"").str(); - return s; + return std::string(s); } // Converts an Arg to a string representation suitable for a response file. // To show an Arg in a diagnostic, use Arg::getAsString() instead. std::string lld::toString(const opt::Arg &arg) { - std::string k = arg.getSpelling(); + std::string k = std::string(arg.getSpelling()); if (arg.getNumValues() == 0) return k; std::string v = quote(arg.getValue()); diff --git a/lld/Common/Strings.cpp b/lld/Common/Strings.cpp index 627435f141da..17c2c207491f 100644 --- a/lld/Common/Strings.cpp +++ b/lld/Common/Strings.cpp @@ -10,6 +10,7 @@ #include "lld/Common/ErrorHandler.h" #include "lld/Common/LLVM.h" #include "llvm/Demangle/Demangle.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/GlobPattern.h" #include <algorithm> #include <mutex> @@ -26,23 +27,33 @@ std::string lld::demangleItanium(StringRef name) { // does not look like a C++ symbol name to avoid getting unexpected // result for a C symbol that happens to match a mangled type name. if (!name.startswith("_Z")) - return name; + return std::string(name); - return demangle(name); + return demangle(std::string(name)); } -StringMatcher::StringMatcher(ArrayRef<StringRef> pat) { - for (StringRef s : pat) { - Expected<GlobPattern> pat = GlobPattern::create(s); - if (!pat) - error(toString(pat.takeError())); - else - patterns.push_back(*pat); +SingleStringMatcher::SingleStringMatcher(StringRef Pattern) { + if (Pattern.size() > 2 && Pattern.startswith("\"") && + Pattern.endswith("\"")) { + ExactMatch = true; + ExactPattern = Pattern.substr(1, Pattern.size() - 2); + } else { + Expected<GlobPattern> Glob = GlobPattern::create(Pattern); + if (!Glob) { + error(toString(Glob.takeError())); + return; + } + ExactMatch = false; + GlobPatternMatcher = *Glob; } } +bool SingleStringMatcher::match(StringRef s) const { + return ExactMatch ? (ExactPattern == s) : GlobPatternMatcher.match(s); +} + bool StringMatcher::match(StringRef s) const { - for (const GlobPattern &pat : patterns) + for (const SingleStringMatcher &pat : patterns) if (pat.match(s)) return true; return false; diff --git a/lld/Common/TargetOptionsCommandFlags.cpp b/lld/Common/TargetOptionsCommandFlags.cpp index 0137feb63f37..9b166a3e130a 100644 --- a/lld/Common/TargetOptionsCommandFlags.cpp +++ b/lld/Common/TargetOptionsCommandFlags.cpp @@ -5,35 +5,26 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// -// This file exists as a place for global variables defined in LLVM's -// CodeGen/CommandFlags.inc. By putting the resulting object file in -// an archive and linking with it, the definitions will automatically be -// included when needed and skipped when already present. -// -//===----------------------------------------------------------------------===// #include "lld/Common/TargetOptionsCommandFlags.h" -#include "llvm/CodeGen/CommandFlags.inc" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/Target/TargetOptions.h" -// Define an externally visible version of -// initTargetOptionsFromCodeGenFlags, so that its functionality can be -// used without having to include llvm/CodeGen/CommandFlags.inc, which -// would lead to multiple definitions of the command line flags. +static llvm::codegen::RegisterCodeGenFlags CGF; + llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() { - return ::InitTargetOptionsFromCodeGenFlags(); + return llvm::codegen::InitTargetOptionsFromCodeGenFlags(); } llvm::Optional<llvm::Reloc::Model> lld::getRelocModelFromCMModel() { - return getRelocModel(); + return llvm::codegen::getExplicitRelocModel(); } llvm::Optional<llvm::CodeModel::Model> lld::getCodeModelFromCMModel() { - return getCodeModel(); + return llvm::codegen::getExplicitCodeModel(); } -std::string lld::getCPUStr() { return ::getCPUStr(); } +std::string lld::getCPUStr() { return llvm::codegen::getCPUStr(); } -std::vector<std::string> lld::getMAttrs() { return ::MAttrs; } +std::vector<std::string> lld::getMAttrs() { return llvm::codegen::getMAttrs(); } diff --git a/lld/Common/Threads.cpp b/lld/Common/Threads.cpp deleted file mode 100644 index af04972a3760..000000000000 --- a/lld/Common/Threads.cpp +++ /dev/null @@ -1,11 +0,0 @@ -//===- Threads.cpp --------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "lld/Common/Threads.h" - -bool lld::threadsEnabled = true; diff --git a/lld/Common/Timer.cpp b/lld/Common/Timer.cpp index 4b7d11003b2c..ea221fd86f3e 100644 --- a/lld/Common/Timer.cpp +++ b/lld/Common/Timer.cpp @@ -13,29 +13,22 @@ using namespace lld; using namespace llvm; -ScopedTimer::ScopedTimer(Timer &t) : t(&t) { t.start(); } +ScopedTimer::ScopedTimer(Timer &t) : t(&t) { + startTime = std::chrono::high_resolution_clock::now(); +} void ScopedTimer::stop() { if (!t) return; - t->stop(); + t->addToTotal(std::chrono::high_resolution_clock::now() - startTime); t = nullptr; } ScopedTimer::~ScopedTimer() { stop(); } -Timer::Timer(llvm::StringRef name) : name(name), parent(nullptr) {} -Timer::Timer(llvm::StringRef name, Timer &parent) - : name(name), parent(&parent) {} - -void Timer::start() { - if (parent && total.count() == 0) - parent->children.push_back(this); - startTime = std::chrono::high_resolution_clock::now(); -} - -void Timer::stop() { - total += (std::chrono::high_resolution_clock::now() - startTime); +Timer::Timer(llvm::StringRef name) : name(std::string(name)) {} +Timer::Timer(llvm::StringRef name, Timer &parent) : name(std::string(name)) { + parent.children.push_back(this); } Timer &Timer::root() { @@ -49,7 +42,8 @@ void Timer::print() { // We want to print the grand total under all the intermediate phases, so we // print all children first, then print the total under that. for (const auto &child : children) - child->print(1, totalDuration); + if (child->total > 0) + child->print(1, totalDuration); message(std::string(49, '-')); @@ -58,7 +52,7 @@ void Timer::print() { double Timer::millis() const { return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>( - total) + std::chrono::nanoseconds(total)) .count(); } @@ -74,6 +68,7 @@ void Timer::print(int depth, double totalDuration, bool recurse) const { if (recurse) { for (const auto &child : children) - child->print(depth + 1, totalDuration); + if (child->total > 0) + child->print(depth + 1, totalDuration); } } diff --git a/lld/Common/Version.cpp b/lld/Common/Version.cpp index ae10f2f28b22..cd9fcd4f4059 100644 --- a/lld/Common/Version.cpp +++ b/lld/Common/Version.cpp @@ -19,9 +19,16 @@ // Returns a version string, e.g.: // lld 9.0.0 (https://github.com/llvm/llvm-project.git 9efdd7ac5e914d3c9fa1ef) std::string lld::getLLDVersion() { +#ifdef LLD_VENDOR +#define LLD_VENDOR_DISPLAY LLD_VENDOR " " +#else +#define LLD_VENDOR_DISPLAY +#endif #if defined(LLD_REPOSITORY) && defined(LLD_REVISION) - return "LLD " LLD_VERSION_STRING " (" LLD_REPOSITORY " " LLD_REVISION ")"; + return LLD_VENDOR_DISPLAY "LLD " LLD_VERSION_STRING " (" LLD_REPOSITORY + " " LLD_REVISION ")"; #else - return "LLD " LLD_VERSION_STRING; + return LLD_VENDOR_DISPLAY "LLD " LLD_VERSION_STRING; #endif +#undef LLD_VENDOR_DISPLAY } |