summaryrefslogtreecommitdiff
path: root/lld/Common
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2021-09-09 09:27:14 -0700
committerFangrui Song <i@maskray.me>2021-09-09 09:27:14 -0700
commit0db402c5b4ef60ca8d20dda8bb59c7288a534e2a (patch)
tree93e760672d597379d475b037382ebad27e5e0450 /lld/Common
parent0782e55c26bf56cd28c26793920fa37883bcf689 (diff)
downloadllvm-0db402c5b4ef60ca8d20dda8bb59c7288a534e2a.tar.gz
[lld] Buffer writes when composing a single diagnostic
llvm::errs() is unbuffered. On a POSIX platform, composing a diagnostic string may invoke the ::write syscall multiple times, which can be slow. Buffer writes to a temporary SmallString when composing a single diagnostic to reduce the number of ::write syscalls to one (also easier to read under strace/truss). For an invocation of ld.lld with 62000+ lines of `ld.lld: warning: symbol ordering file: no such symbol: ` warnings (D87121), the buffering decreases the write time from 1s to 0.4s (for /dev/tty) and from 0.4s to 0.1s (for a tmpfs file). This can speed up `relocation R_X86_64_PC32 out of range` diagnostic printing as well with `--noinhibit-exec --no-fatal-warnings`. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D87272
Diffstat (limited to 'lld/Common')
-rw-r--r--lld/Common/ErrorHandler.cpp29
1 files changed, 21 insertions, 8 deletions
diff --git a/lld/Common/ErrorHandler.cpp b/lld/Common/ErrorHandler.cpp
index 269a0f62ec65..c8c5ffed7126 100644
--- a/lld/Common/ErrorHandler.cpp
+++ b/lld/Common/ErrorHandler.cpp
@@ -168,11 +168,28 @@ std::string ErrorHandler::getLocation(const Twine &msg) {
return std::string(logName);
}
+void ErrorHandler::reportDiagnostic(StringRef location, Colors c,
+ StringRef diagKind, const Twine &msg) {
+ SmallString<256> buf;
+ raw_svector_ostream os(buf);
+ os << sep << location << ": ";
+ if (!diagKind.empty()) {
+ if (lld::errs().colors_enabled()) {
+ os.enable_colors(true);
+ os << c << diagKind << ": " << Colors::RESET;
+ } else {
+ os << diagKind << ": ";
+ }
+ }
+ os << msg << '\n';
+ lld::errs() << buf;
+}
+
void ErrorHandler::log(const Twine &msg) {
if (!verbose || disableOutput)
return;
std::lock_guard<std::mutex> lock(mu);
- lld::errs() << logName << ": " << msg << "\n";
+ reportDiagnostic(logName, Colors::RESET, "", msg);
}
void ErrorHandler::message(const Twine &msg) {
@@ -190,8 +207,7 @@ void ErrorHandler::warn(const Twine &msg) {
}
std::lock_guard<std::mutex> lock(mu);
- lld::errs() << sep << getLocation(msg) << ": " << Colors::MAGENTA
- << "warning: " << Colors::RESET << msg << "\n";
+ reportDiagnostic(getLocation(msg), Colors::MAGENTA, "warning", msg);
sep = getSeparator(msg);
}
@@ -217,12 +233,9 @@ void ErrorHandler::error(const Twine &msg) {
std::lock_guard<std::mutex> lock(mu);
if (errorLimit == 0 || errorCount < errorLimit) {
- lld::errs() << sep << getLocation(msg) << ": " << Colors::RED
- << "error: " << Colors::RESET << msg << "\n";
+ reportDiagnostic(getLocation(msg), Colors::RED, "error", msg);
} else if (errorCount == errorLimit) {
- lld::errs() << sep << getLocation(msg) << ": " << Colors::RED
- << "error: " << Colors::RESET << errorLimitExceededMsg
- << "\n";
+ reportDiagnostic(logName, Colors::RED, "error", errorLimitExceededMsg);
exit = exitEarly;
}