xref: /src/contrib/llvm-project/lld/Common/Timer.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
120d35e67SDimitry Andric //===- Timer.cpp ----------------------------------------------------------===//
220d35e67SDimitry Andric //
3f1e1c239SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f1e1c239SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5f1e1c239SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
620d35e67SDimitry Andric //
720d35e67SDimitry Andric //===----------------------------------------------------------------------===//
820d35e67SDimitry Andric 
920d35e67SDimitry Andric #include "lld/Common/Timer.h"
1020d35e67SDimitry Andric #include "lld/Common/ErrorHandler.h"
117fa27ce4SDimitry Andric #include "llvm/ADT/SmallString.h"
1220d35e67SDimitry Andric #include "llvm/Support/Format.h"
136f8fc217SDimitry Andric #include <ratio>
1420d35e67SDimitry Andric 
1520d35e67SDimitry Andric using namespace lld;
1620d35e67SDimitry Andric using namespace llvm;
1720d35e67SDimitry Andric 
ScopedTimer(Timer & t)18cfca06d7SDimitry Andric ScopedTimer::ScopedTimer(Timer &t) : t(&t) {
19cfca06d7SDimitry Andric   startTime = std::chrono::high_resolution_clock::now();
20cfca06d7SDimitry Andric }
2120d35e67SDimitry Andric 
stop()2220d35e67SDimitry Andric void ScopedTimer::stop() {
23f1e1c239SDimitry Andric   if (!t)
2420d35e67SDimitry Andric     return;
25cfca06d7SDimitry Andric   t->addToTotal(std::chrono::high_resolution_clock::now() - startTime);
26f1e1c239SDimitry Andric   t = nullptr;
2720d35e67SDimitry Andric }
2820d35e67SDimitry Andric 
~ScopedTimer()2920d35e67SDimitry Andric ScopedTimer::~ScopedTimer() { stop(); }
3020d35e67SDimitry Andric 
Timer(llvm::StringRef name)31c0981da4SDimitry Andric Timer::Timer(llvm::StringRef name) : total(0), name(std::string(name)) {}
Timer(llvm::StringRef name,Timer & parent)32c0981da4SDimitry Andric Timer::Timer(llvm::StringRef name, Timer &parent)
33c0981da4SDimitry Andric     : total(0), name(std::string(name)) {
34cfca06d7SDimitry Andric   parent.children.push_back(this);
3520d35e67SDimitry Andric }
3620d35e67SDimitry Andric 
print()3720d35e67SDimitry Andric void Timer::print() {
38c0981da4SDimitry Andric   double totalDuration = static_cast<double>(millis());
3920d35e67SDimitry Andric 
4020d35e67SDimitry Andric   // We want to print the grand total under all the intermediate phases, so we
4120d35e67SDimitry Andric   // print all children first, then print the total under that.
42f1e1c239SDimitry Andric   for (const auto &child : children)
43cfca06d7SDimitry Andric     if (child->total > 0)
44f1e1c239SDimitry Andric       child->print(1, totalDuration);
4520d35e67SDimitry Andric 
46b60736ecSDimitry Andric   message(std::string(50, '-'));
4720d35e67SDimitry Andric 
48c0981da4SDimitry Andric   print(0, millis(), false);
4920d35e67SDimitry Andric }
5020d35e67SDimitry Andric 
millis() const5120d35e67SDimitry Andric double Timer::millis() const {
5220d35e67SDimitry Andric   return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
53cfca06d7SDimitry Andric              std::chrono::nanoseconds(total))
5420d35e67SDimitry Andric       .count();
5520d35e67SDimitry Andric }
5620d35e67SDimitry Andric 
print(int depth,double totalDuration,bool recurse) const57f1e1c239SDimitry Andric void Timer::print(int depth, double totalDuration, bool recurse) const {
58f1e1c239SDimitry Andric   double p = 100.0 * millis() / totalDuration;
5920d35e67SDimitry Andric 
60f1e1c239SDimitry Andric   SmallString<32> str;
61f1e1c239SDimitry Andric   llvm::raw_svector_ostream stream(str);
62f1e1c239SDimitry Andric   std::string s = std::string(depth * 2, ' ') + name + std::string(":");
63b60736ecSDimitry Andric   stream << format("%-30s%7d ms (%5.1f%%)", s.c_str(), (int)millis(), p);
6420d35e67SDimitry Andric 
65f1e1c239SDimitry Andric   message(str);
6620d35e67SDimitry Andric 
67f1e1c239SDimitry Andric   if (recurse) {
68f1e1c239SDimitry Andric     for (const auto &child : children)
69cfca06d7SDimitry Andric       if (child->total > 0)
70f1e1c239SDimitry Andric         child->print(depth + 1, totalDuration);
7120d35e67SDimitry Andric   }
7220d35e67SDimitry Andric }
73