190792Sgshapiro//===- Timer.cpp ----------------------------------------------------------===// 2363466Sgshapiro// 390792Sgshapiro// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 490792Sgshapiro// See https://llvm.org/LICENSE.txt for license information. 590792Sgshapiro// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 690792Sgshapiro// 790792Sgshapiro//===----------------------------------------------------------------------===// 890792Sgshapiro 990792Sgshapiro#include "lld/Common/Timer.h" 1090792Sgshapiro#include "lld/Common/ErrorHandler.h" 1190792Sgshapiro#include "llvm/Support/Format.h" 1290792Sgshapiro 1390792Sgshapirousing namespace lld; 1490792Sgshapirousing namespace llvm; 1590792Sgshapiro 1690792SgshapiroScopedTimer::ScopedTimer(Timer &t) : t(&t) { t.start(); } 1790792Sgshapiro 1890792Sgshapirovoid ScopedTimer::stop() { 1990792Sgshapiro if (!t) 2090792Sgshapiro return; 2190792Sgshapiro t->stop(); 2290792Sgshapiro t = nullptr; 2390792Sgshapiro} 2490792Sgshapiro 2590792SgshapiroScopedTimer::~ScopedTimer() { stop(); } 2690792Sgshapiro 2790792SgshapiroTimer::Timer(llvm::StringRef name) : name(name), parent(nullptr) {} 2890792SgshapiroTimer::Timer(llvm::StringRef name, Timer &parent) 2990792Sgshapiro : name(name), parent(&parent) {} 3090792Sgshapiro 3190792Sgshapirovoid Timer::start() { 3290792Sgshapiro if (parent && total.count() == 0) 3390792Sgshapiro parent->children.push_back(this); 3490792Sgshapiro startTime = std::chrono::high_resolution_clock::now(); 3590792Sgshapiro} 3690792Sgshapiro 3790792Sgshapirovoid Timer::stop() { 3890792Sgshapiro total += (std::chrono::high_resolution_clock::now() - startTime); 3990792Sgshapiro} 4090792Sgshapiro 4190792SgshapiroTimer &Timer::root() { 4290792Sgshapiro static Timer rootTimer("Total Link Time"); 4390792Sgshapiro return rootTimer; 4490792Sgshapiro} 45363466Sgshapiro 4690792Sgshapirovoid Timer::print() { 47223067Sgshapiro double totalDuration = static_cast<double>(root().millis()); 48223067Sgshapiro 49223067Sgshapiro // We want to print the grand total under all the intermediate phases, so we 50363466Sgshapiro // print all children first, then print the total under that. 51363466Sgshapiro for (const auto &child : children) 5290792Sgshapiro child->print(1, totalDuration); 5390792Sgshapiro 54363466Sgshapiro message(std::string(49, '-')); 55363466Sgshapiro 56266527Sgshapiro root().print(0, root().millis(), false); 5790792Sgshapiro} 5890792Sgshapiro 5990792Sgshapirodouble Timer::millis() const { 6090792Sgshapiro return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>( 6190792Sgshapiro total) 6290792Sgshapiro .count(); 6390792Sgshapiro} 6490792Sgshapiro 6590792Sgshapirovoid Timer::print(int depth, double totalDuration, bool recurse) const { 66363466Sgshapiro double p = 100.0 * millis() / totalDuration; 6790792Sgshapiro 6890792Sgshapiro SmallString<32> str; 69363466Sgshapiro llvm::raw_svector_ostream stream(str); 7090792Sgshapiro std::string s = std::string(depth * 2, ' ') + name + std::string(":"); 7190792Sgshapiro stream << format("%-30s%5d ms (%5.1f%%)", s.c_str(), (int)millis(), p); 7290792Sgshapiro 7390792Sgshapiro message(str); 7490792Sgshapiro 7590792Sgshapiro if (recurse) { 7690792Sgshapiro for (const auto &child : children) 77363466Sgshapiro child->print(depth + 1, totalDuration); 78363466Sgshapiro } 79363466Sgshapiro} 80363466Sgshapiro