summaryrefslogtreecommitdiff
path: root/lld/Common
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /lld/Common
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'lld/Common')
-rw-r--r--lld/Common/ErrorHandler.cpp41
-rw-r--r--lld/Common/Filesystem.cpp36
-rw-r--r--lld/Common/Reproduce.cpp6
-rw-r--r--lld/Common/Strings.cpp31
-rw-r--r--lld/Common/TargetOptionsCommandFlags.cpp25
-rw-r--r--lld/Common/Threads.cpp11
-rw-r--r--lld/Common/Timer.cpp29
-rw-r--r--lld/Common/Version.cpp11
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
}