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"
11727f153bSZachary Turner #include "llvm/Support/Format.h"
12*54ba376dSAdrian Prantl #include <ratio>
13727f153bSZachary Turner
14727f153bSZachary Turner using namespace lld;
15727f153bSZachary Turner using namespace llvm;
16727f153bSZachary Turner
ScopedTimer(Timer & t)173508c1d8SReid Kleckner ScopedTimer::ScopedTimer(Timer &t) : t(&t) {
183508c1d8SReid Kleckner startTime = std::chrono::high_resolution_clock::now();
193508c1d8SReid Kleckner }
20727f153bSZachary Turner
stop()21727f153bSZachary Turner void ScopedTimer::stop() {
22136d27abSRui Ueyama if (!t)
23727f153bSZachary Turner return;
243508c1d8SReid Kleckner t->addToTotal(std::chrono::high_resolution_clock::now() - startTime);
25136d27abSRui Ueyama t = nullptr;
26727f153bSZachary Turner }
27727f153bSZachary Turner
~ScopedTimer()28727f153bSZachary Turner ScopedTimer::~ScopedTimer() { stop(); }
29727f153bSZachary Turner
Timer(llvm::StringRef name)30724a1dffSAmy Huang Timer::Timer(llvm::StringRef name) : total(0), name(std::string(name)) {}
Timer(llvm::StringRef name,Timer & parent)31724a1dffSAmy Huang Timer::Timer(llvm::StringRef name, Timer &parent)
32724a1dffSAmy Huang : total(0), name(std::string(name)) {
333508c1d8SReid Kleckner parent.children.push_back(this);
34727f153bSZachary Turner }
35727f153bSZachary Turner
print()36727f153bSZachary Turner void Timer::print() {
376f7483b1SAmy Huang double totalDuration = static_cast<double>(millis());
38727f153bSZachary Turner
39727f153bSZachary Turner // We want to print the grand total under all the intermediate phases, so we
40727f153bSZachary Turner // print all children first, then print the total under that.
41136d27abSRui Ueyama for (const auto &child : children)
423508c1d8SReid Kleckner if (child->total > 0)
43136d27abSRui Ueyama child->print(1, totalDuration);
44727f153bSZachary Turner
45fe1f0a1aSAlexandre Ganea message(std::string(50, '-'));
46727f153bSZachary Turner
476f7483b1SAmy Huang print(0, millis(), false);
48727f153bSZachary Turner }
49727f153bSZachary Turner
millis() const50727f153bSZachary Turner double Timer::millis() const {
51727f153bSZachary Turner return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
523508c1d8SReid Kleckner std::chrono::nanoseconds(total))
53727f153bSZachary Turner .count();
54727f153bSZachary Turner }
55727f153bSZachary Turner
print(int depth,double totalDuration,bool recurse) const56136d27abSRui Ueyama void Timer::print(int depth, double totalDuration, bool recurse) const {
57136d27abSRui Ueyama double p = 100.0 * millis() / totalDuration;
58727f153bSZachary Turner
59136d27abSRui Ueyama SmallString<32> str;
60136d27abSRui Ueyama llvm::raw_svector_ostream stream(str);
61136d27abSRui Ueyama std::string s = std::string(depth * 2, ' ') + name + std::string(":");
62fe1f0a1aSAlexandre Ganea stream << format("%-30s%7d ms (%5.1f%%)", s.c_str(), (int)millis(), p);
63727f153bSZachary Turner
64136d27abSRui Ueyama message(str);
65727f153bSZachary Turner
66136d27abSRui Ueyama if (recurse) {
67136d27abSRui Ueyama for (const auto &child : children)
683508c1d8SReid Kleckner if (child->total > 0)
69136d27abSRui Ueyama child->print(depth + 1, totalDuration);
70727f153bSZachary Turner }
71727f153bSZachary Turner }
72