14b7cf160SRui Ueyama //===- Timer.cpp ----------------------------------------------------------===//
24b7cf160SRui Ueyama //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64b7cf160SRui Ueyama //
74b7cf160SRui Ueyama //===----------------------------------------------------------------------===//
84b7cf160SRui Ueyama
9727f153bSZachary Turner #include "lld/Common/Timer.h"
10727f153bSZachary Turner #include "lld/Common/ErrorHandler.h"
11*b0abd489SElliot Goodrich #include "llvm/ADT/SmallString.h"
12727f153bSZachary Turner #include "llvm/Support/Format.h"
1354ba376dSAdrian Prantl #include <ratio>
14727f153bSZachary Turner
15727f153bSZachary Turner using namespace lld;
16727f153bSZachary Turner using namespace llvm;
17727f153bSZachary Turner
ScopedTimer(Timer & t)183508c1d8SReid Kleckner ScopedTimer::ScopedTimer(Timer &t) : t(&t) {
193508c1d8SReid Kleckner startTime = std::chrono::high_resolution_clock::now();
203508c1d8SReid Kleckner }
21727f153bSZachary Turner
stop()22727f153bSZachary Turner void ScopedTimer::stop() {
23136d27abSRui Ueyama if (!t)
24727f153bSZachary Turner return;
253508c1d8SReid Kleckner t->addToTotal(std::chrono::high_resolution_clock::now() - startTime);
26136d27abSRui Ueyama t = nullptr;
27727f153bSZachary Turner }
28727f153bSZachary Turner
~ScopedTimer()29727f153bSZachary Turner ScopedTimer::~ScopedTimer() { stop(); }
30727f153bSZachary Turner
Timer(llvm::StringRef name)31724a1dffSAmy Huang Timer::Timer(llvm::StringRef name) : total(0), name(std::string(name)) {}
Timer(llvm::StringRef name,Timer & parent)32724a1dffSAmy Huang Timer::Timer(llvm::StringRef name, Timer &parent)
33724a1dffSAmy Huang : total(0), name(std::string(name)) {
343508c1d8SReid Kleckner parent.children.push_back(this);
35727f153bSZachary Turner }
36727f153bSZachary Turner
print()37727f153bSZachary Turner void Timer::print() {
386f7483b1SAmy Huang double totalDuration = static_cast<double>(millis());
39727f153bSZachary Turner
40727f153bSZachary Turner // We want to print the grand total under all the intermediate phases, so we
41727f153bSZachary Turner // print all children first, then print the total under that.
42136d27abSRui Ueyama for (const auto &child : children)
433508c1d8SReid Kleckner if (child->total > 0)
44136d27abSRui Ueyama child->print(1, totalDuration);
45727f153bSZachary Turner
46fe1f0a1aSAlexandre Ganea message(std::string(50, '-'));
47727f153bSZachary Turner
486f7483b1SAmy Huang print(0, millis(), false);
49727f153bSZachary Turner }
50727f153bSZachary Turner
millis() const51727f153bSZachary Turner double Timer::millis() const {
52727f153bSZachary Turner return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
533508c1d8SReid Kleckner std::chrono::nanoseconds(total))
54727f153bSZachary Turner .count();
55727f153bSZachary Turner }
56727f153bSZachary Turner
print(int depth,double totalDuration,bool recurse) const57136d27abSRui Ueyama void Timer::print(int depth, double totalDuration, bool recurse) const {
58136d27abSRui Ueyama double p = 100.0 * millis() / totalDuration;
59727f153bSZachary Turner
60136d27abSRui Ueyama SmallString<32> str;
61136d27abSRui Ueyama llvm::raw_svector_ostream stream(str);
62136d27abSRui Ueyama std::string s = std::string(depth * 2, ' ') + name + std::string(":");
63fe1f0a1aSAlexandre Ganea stream << format("%-30s%7d ms (%5.1f%%)", s.c_str(), (int)millis(), p);
64727f153bSZachary Turner
65136d27abSRui Ueyama message(str);
66727f153bSZachary Turner
67136d27abSRui Ueyama if (recurse) {
68136d27abSRui Ueyama for (const auto &child : children)
693508c1d8SReid Kleckner if (child->total > 0)
70136d27abSRui Ueyama child->print(depth + 1, totalDuration);
71727f153bSZachary Turner }
72727f153bSZachary Turner }
73