1ece8a530Spatrick //===- Timer.cpp ----------------------------------------------------------===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick
9ece8a530Spatrick #include "lld/Common/Timer.h"
10ece8a530Spatrick #include "lld/Common/ErrorHandler.h"
11ece8a530Spatrick #include "llvm/Support/Format.h"
12*dfe94b16Srobert #include <ratio>
13ece8a530Spatrick
14ece8a530Spatrick using namespace lld;
15ece8a530Spatrick using namespace llvm;
16ece8a530Spatrick
ScopedTimer(Timer & t)17bb684c34Spatrick ScopedTimer::ScopedTimer(Timer &t) : t(&t) {
18bb684c34Spatrick startTime = std::chrono::high_resolution_clock::now();
19bb684c34Spatrick }
20ece8a530Spatrick
stop()21ece8a530Spatrick void ScopedTimer::stop() {
22ece8a530Spatrick if (!t)
23ece8a530Spatrick return;
24bb684c34Spatrick t->addToTotal(std::chrono::high_resolution_clock::now() - startTime);
25ece8a530Spatrick t = nullptr;
26ece8a530Spatrick }
27ece8a530Spatrick
~ScopedTimer()28ece8a530Spatrick ScopedTimer::~ScopedTimer() { stop(); }
29ece8a530Spatrick
Timer(llvm::StringRef name)30*dfe94b16Srobert Timer::Timer(llvm::StringRef name) : total(0), name(std::string(name)) {}
Timer(llvm::StringRef name,Timer & parent)31*dfe94b16Srobert Timer::Timer(llvm::StringRef name, Timer &parent)
32*dfe94b16Srobert : total(0), name(std::string(name)) {
33bb684c34Spatrick parent.children.push_back(this);
34ece8a530Spatrick }
35ece8a530Spatrick
print()36ece8a530Spatrick void Timer::print() {
37*dfe94b16Srobert double totalDuration = static_cast<double>(millis());
38ece8a530Spatrick
39ece8a530Spatrick // We want to print the grand total under all the intermediate phases, so we
40ece8a530Spatrick // print all children first, then print the total under that.
41ece8a530Spatrick for (const auto &child : children)
42bb684c34Spatrick if (child->total > 0)
43ece8a530Spatrick child->print(1, totalDuration);
44ece8a530Spatrick
451cf9926bSpatrick message(std::string(50, '-'));
46ece8a530Spatrick
47*dfe94b16Srobert print(0, millis(), false);
48ece8a530Spatrick }
49ece8a530Spatrick
millis() const50ece8a530Spatrick double Timer::millis() const {
51ece8a530Spatrick return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
52bb684c34Spatrick std::chrono::nanoseconds(total))
53ece8a530Spatrick .count();
54ece8a530Spatrick }
55ece8a530Spatrick
print(int depth,double totalDuration,bool recurse) const56ece8a530Spatrick void Timer::print(int depth, double totalDuration, bool recurse) const {
57ece8a530Spatrick double p = 100.0 * millis() / totalDuration;
58ece8a530Spatrick
59ece8a530Spatrick SmallString<32> str;
60ece8a530Spatrick llvm::raw_svector_ostream stream(str);
61ece8a530Spatrick std::string s = std::string(depth * 2, ' ') + name + std::string(":");
621cf9926bSpatrick stream << format("%-30s%7d ms (%5.1f%%)", s.c_str(), (int)millis(), p);
63ece8a530Spatrick
64ece8a530Spatrick message(str);
65ece8a530Spatrick
66ece8a530Spatrick if (recurse) {
67ece8a530Spatrick for (const auto &child : children)
68bb684c34Spatrick if (child->total > 0)
69ece8a530Spatrick child->print(depth + 1, totalDuration);
70ece8a530Spatrick }
71ece8a530Spatrick }
72