Timer.cpp revision fc86c3cfd6e81113722f17bebc54bc0b63389b58
16c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===-- Timer.cpp - Interval Timing Support -------------------------------===// 2f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 96c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// 106c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// Interval Timing implementation. 116c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// 126c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 136c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 14551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Timer.h" 15551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 16fc86c3cfd6e81113722f17bebc54bc0b63389b58Chris Lattner#include "llvm/Support/Debug.h" 1790aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner#include "llvm/Support/ManagedStatic.h" 18d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner#include "llvm/Support/raw_ostream.h" 19d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner#include "llvm/Support/Format.h" 20fc86c3cfd6e81113722f17bebc54bc0b63389b58Chris Lattner#include "llvm/System/Mutex.h" 21df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer#include "llvm/System/Process.h" 22d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner#include <map> 23b6d465f8131f5fb0b8e565685fb3395ed9aecbdbChris Lattnerusing namespace llvm; 24f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 25b4db5f3e4b24bfc515bc615b2b6256083c7ef508Chris Lattner// GetLibSupportInfoOutputFile - Return a file stream to print our output on. 26d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattnernamespace llvm { extern raw_ostream *GetLibSupportInfoOutputFile(); } 27d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 2871336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner// getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy 2971336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner// of constructor/destructor ordering being unspecified by C++. Basically the 30ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner// problem is that a Statistic object gets destroyed, which ends up calling 3171336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner// 'GetLibSupportInfoOutputFile()' (below), which calls this function. 3271336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner// LibSupportInfoOutputFilename used to be a global variable, but sometimes it 33f6e5a25f3a57a225c8545e453045f3ae220e3286Reid Spencer// would get destroyed before the Statistic, causing havoc to ensue. We "fix" 34f6e5a25f3a57a225c8545e453045f3ae220e3286Reid Spencer// this by creating the string the first time it is needed and never destroying 35f6e5a25f3a57a225c8545e453045f3ae220e3286Reid Spencer// it. 3690aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattnerstatic ManagedStatic<std::string> LibSupportInfoOutputFilename; 3771336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattnerstatic std::string &getLibSupportInfoOutputFilename() { 38f6e5a25f3a57a225c8545e453045f3ae220e3286Reid Spencer return *LibSupportInfoOutputFilename; 3971336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner} 406c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 4146d9a6494496d215e850f337b5a723c484212f80Owen Andersonstatic ManagedStatic<sys::SmartMutex<true> > TimerLock; 4246d9a6494496d215e850f337b5a723c484212f80Owen Anderson 433f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattnernamespace { 443c02aca2380bc95a3ce5799929354612c67cc105Dan Gohman static cl::opt<bool> 453f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner TrackSpace("track-memory", cl::desc("Enable -time-passes memory " 463f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner "tracking (this may be slow)"), 473f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner cl::Hidden); 48f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 493c02aca2380bc95a3ce5799929354612c67cc105Dan Gohman static cl::opt<std::string, true> 5096a54db5e763c19f556a1b54ad2956cc91b81cb8Chris Lattner InfoOutputFilename("info-output-file", cl::value_desc("filename"), 51f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner cl::desc("File to append -stats and -timer output to"), 5271336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner cl::Hidden, cl::location(getLibSupportInfoOutputFilename())); 533f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner} 543f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner 55200aa6d89b75d2a4f630b85a4a785ae7d18d16bbOwen Andersonstatic TimerGroup *DefaultTimerGroup = 0; 566c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerstatic TimerGroup *getDefaultTimerGroup() { 579bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner TimerGroup *tmp = DefaultTimerGroup; 583b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson sys::MemoryFence(); 599bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (tmp) return tmp; 609bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 619bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner llvm_acquire_global_lock(); 629bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner tmp = DefaultTimerGroup; 633b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson if (!tmp) { 649bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner tmp = new TimerGroup("Miscellaneous Ungrouped Timers"); 659bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner sys::MemoryFence(); 669bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner DefaultTimerGroup = tmp; 673b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson } 689bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner llvm_release_global_lock(); 69c11e84d3e7a432449d453b51b567f2fc5db4e8c0Mikhail Glushenkov 703b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson return tmp; 716c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 726c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 739bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner//===----------------------------------------------------------------------===// 749bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner// Timer Implementation 759bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner//===----------------------------------------------------------------------===// 769bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 776c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(const std::string &N) 78fc86c3cfd6e81113722f17bebc54bc0b63389b58Chris Lattner : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), Name(N), 796c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started(false), TG(getDefaultTimerGroup()) { 806c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG->addTimer(); 816c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 826c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 836c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(const std::string &N, TimerGroup &tg) 84fc86c3cfd6e81113722f17bebc54bc0b63389b58Chris Lattner : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), Name(N), 856c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started(false), TG(&tg) { 866c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG->addTimer(); 876c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 886c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 896c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(const Timer &T) { 906c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG = T.TG; 916c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (TG) TG->addTimer(); 926c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner operator=(T); 936c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 946c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 956c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// Copy ctor, initialize with no TG member. 966c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(bool, const Timer &T) { 976c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG = T.TG; // Avoid assertion in operator= 986c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner operator=(T); // Copy contents 996c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG = 0; 1006c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1016c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1026c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::~Timer() { 1039bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (!TG) return; 1049bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 1059bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Started) { 1069bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Started = false; 1079bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner TG->addTimerToPrint(*this); 1086c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 1099bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner TG->removeTimer(); 1106c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1116c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 112e269a1ac1cd795135e91e42527a9814f4807c75aJeff Cohenstatic inline size_t getMemUsage() { 113aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer if (TrackSpace) 114e269a1ac1cd795135e91e42527a9814f4807c75aJeff Cohen return sys::Process::GetMallocUsage(); 115aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer return 0; 116aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer} 117aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer 1186c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerstruct TimeRecord { 1196f2c64d70aad5328a843a6f6a6547ada69ead33bOwen Anderson double Elapsed, UserTime, SystemTime; 1206f2c64d70aad5328a843a6f6a6547ada69ead33bOwen Anderson ssize_t MemUsed; 1216c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner}; 1226c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1238f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattnerstatic TimeRecord getTimeRecord(bool Start) { 124df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer TimeRecord Result; 125b4db5f3e4b24bfc515bc615b2b6256083c7ef508Chris Lattner 126df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer sys::TimeValue now(0,0); 127df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer sys::TimeValue user(0,0); 128df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer sys::TimeValue sys(0,0); 129b4db5f3e4b24bfc515bc615b2b6256083c7ef508Chris Lattner 1306f2c64d70aad5328a843a6f6a6547ada69ead33bOwen Anderson ssize_t MemUsed = 0; 1317d05563324e538a377ba12ca62b2b5b0fbbba547Reid Spencer if (Start) { 132aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer MemUsed = getMemUsage(); 1339bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner sys::Process::GetTimeUsage(now, user, sys); 1347d05563324e538a377ba12ca62b2b5b0fbbba547Reid Spencer } else { 1359bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner sys::Process::GetTimeUsage(now, user, sys); 136fed1b27d323001682e7cb1bd66bb5d603cabb9f8Chris Lattner MemUsed = getMemUsage(); 1377d05563324e538a377ba12ca62b2b5b0fbbba547Reid Spencer } 1388f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1399bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Result.Elapsed = now.seconds() + now.microseconds() / 1000000.0; 1409bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Result.UserTime = user.seconds() + user.microseconds() / 1000000.0; 1419bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Result.SystemTime = sys.seconds() + sys.microseconds() / 1000000.0; 1429bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Result.MemUsed = MemUsed; 1436c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner return Result; 1446c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1456c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 14690aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattnerstatic ManagedStatic<std::vector<Timer*> > ActiveTimers; 1478f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1486c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::startTimer() { 1496c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started = true; 150153d28a414d087cbe20d17329fed358f7fa1258bDan Gohman ActiveTimers->push_back(this); 1518f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner TimeRecord TR = getTimeRecord(true); 1526c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Elapsed -= TR.Elapsed; 1536c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner UserTime -= TR.UserTime; 1546c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner SystemTime -= TR.SystemTime; 15518eba91a05ccff184820f8afddfddada15e35e65Chris Lattner MemUsed -= TR.MemUsed; 1566c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1576c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1586c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::stopTimer() { 1598f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner TimeRecord TR = getTimeRecord(false); 1606c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Elapsed += TR.Elapsed; 1616c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner UserTime += TR.UserTime; 1626c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner SystemTime += TR.SystemTime; 16318eba91a05ccff184820f8afddfddada15e35e65Chris Lattner MemUsed += TR.MemUsed; 1648f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 16590aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner if (ActiveTimers->back() == this) { 16690aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner ActiveTimers->pop_back(); 1678f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } else { 1688f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner std::vector<Timer*>::iterator I = 16990aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner std::find(ActiveTimers->begin(), ActiveTimers->end(), this); 17090aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner assert(I != ActiveTimers->end() && "stop but no startTimer?"); 17190aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner ActiveTimers->erase(I); 1728f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } 1736c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1746c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1756c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::sum(const Timer &T) { 1766c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Elapsed += T.Elapsed; 1776c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner UserTime += T.UserTime; 1786c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner SystemTime += T.SystemTime; 17918eba91a05ccff184820f8afddfddada15e35e65Chris Lattner MemUsed += T.MemUsed; 1806c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1816c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1820ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattnerconst Timer &Timer::operator=(const Timer &T) { 1830ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner Elapsed = T.Elapsed; 1840ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner UserTime = T.UserTime; 1850ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner SystemTime = T.SystemTime; 1860ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner MemUsed = T.MemUsed; 1870ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner Name = T.Name; 1880ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner Started = T.Started; 1890ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner assert(TG == T.TG && "Can only assign timers in the same TimerGroup!"); 1900ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner return *this; 1910ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner} 1920ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner 1930ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner 1949bb110f78efb6096e70336da83b2015f83fc6233Chris Lattnerstatic void printVal(double Val, double Total, raw_ostream &OS) { 1950613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner if (Total < 1e-7) // Avoid dividing by zero. 1969bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << " ----- "; 1979bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner else { 1989bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << " " << format("%7.4f", Val) << " ("; 1999bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << format("%5.1f", Val*100/Total) << "%)"; 2009bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner } 2019bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner} 2029bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 2039bb110f78efb6096e70336da83b2015f83fc6233Chris Lattnervoid Timer::print(const Timer &Total, raw_ostream &OS) { 2049bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.UserTime) 2059bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner printVal(UserTime, Total.UserTime, OS); 2069bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.SystemTime) 2079bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner printVal(SystemTime, Total.SystemTime, OS); 2089bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.getProcessTime()) 2099bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner printVal(getProcessTime(), Total.getProcessTime(), OS); 2109bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner printVal(Elapsed, Total.Elapsed, OS); 2119bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 2129bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << " "; 2139bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 2140ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner if (Total.MemUsed) 2159bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << format("%9lld", (long long)MemUsed) << " "; 2160ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner 2179bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << Name << "\n"; 2189bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 2199bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Started = false; // Once printed, don't print again 2209bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner} 2219bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 2229bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 223d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner//===----------------------------------------------------------------------===// 224d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner// NamedRegionTimer Implementation 225d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner//===----------------------------------------------------------------------===// 226d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 2275e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohmantypedef std::map<std::string, Timer> Name2Timer; 2285e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohmantypedef std::map<std::string, std::pair<TimerGroup, Name2Timer> > Name2Pair; 2295e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 2305e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohmanstatic ManagedStatic<Name2Timer> NamedTimers; 2315e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohmanstatic ManagedStatic<Name2Pair> NamedGroupedTimers; 232d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 23390aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattnerstatic Timer &getNamedRegionTimer(const std::string &Name) { 234a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 2355e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman Name2Timer::iterator I = NamedTimers->find(Name); 236c418bf3dd593b5b2fe2f978930f6d0d6b17e344eDan Gohman if (I != NamedTimers->end()) 237d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner return I->second; 238d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 23990aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner return NamedTimers->insert(I, std::make_pair(Name, Timer(Name)))->second; 240d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner} 241d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 2425e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohmanstatic Timer &getNamedRegionTimer(const std::string &Name, 2435e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman const std::string &GroupName) { 244a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 2455e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 2465e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman Name2Pair::iterator I = NamedGroupedTimers->find(GroupName); 2475e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman if (I == NamedGroupedTimers->end()) { 2485e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman TimerGroup TG(GroupName); 2495e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman std::pair<TimerGroup, Name2Timer> Pair(TG, Name2Timer()); 2505e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman I = NamedGroupedTimers->insert(I, std::make_pair(GroupName, Pair)); 2515e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman } 2525e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 2535e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman Name2Timer::iterator J = I->second.second.find(Name); 2545e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman if (J == I->second.second.end()) 2555e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman J = I->second.second.insert(J, 2565e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman std::make_pair(Name, 2575e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman Timer(Name, 2585e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman I->second.first))); 2595e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 2605e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman return J->second; 2615e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman} 2625e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 263d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris LattnerNamedRegionTimer::NamedRegionTimer(const std::string &Name) 264d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner : TimeRegion(getNamedRegionTimer(Name)) {} 265d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 2665e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan GohmanNamedRegionTimer::NamedRegionTimer(const std::string &Name, 2675e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman const std::string &GroupName) 2685e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman : TimeRegion(getNamedRegionTimer(Name, GroupName)) {} 2698f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 2706c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 2716c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// TimerGroup Implementation 2726c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 2736c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 2740613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner// GetLibSupportInfoOutputFile - Return a file stream to print our output on. 2750ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattnerraw_ostream *llvm::GetLibSupportInfoOutputFile() { 27671336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner std::string &LibSupportInfoOutputFilename = getLibSupportInfoOutputFilename(); 277f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (LibSupportInfoOutputFilename.empty()) 278d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner return &errs(); 279f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (LibSupportInfoOutputFilename == "-") 280d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner return &outs(); 281f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 282d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner std::string Error; 283d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner raw_ostream *Result = new raw_fd_ostream(LibSupportInfoOutputFilename.c_str(), 284d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner Error, raw_fd_ostream::F_Append); 285d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner if (Error.empty()) 286d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner return Result; 287c11e84d3e7a432449d453b51b567f2fc5db4e8c0Mikhail Glushenkov 288d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner errs() << "Error opening info-output-file '" 289bcd2498f4f1682dbdc41452add5b9bc72cbd6b3fBill Wendling << LibSupportInfoOutputFilename << " for appending!\n"; 290d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner delete Result; 291d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattner return &errs(); 292f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner} 293f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 2946c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 2956c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid TimerGroup::removeTimer() { 296a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 2979bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (--NumTimers != 0 || TimersToPrint.empty()) 2989bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner return; // Don't print timing report. 2999bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3009bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner // Sort the timers in descending order by amount of time taken. 3019bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner std::sort(TimersToPrint.begin(), TimersToPrint.end(), 3029bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner std::greater<Timer>()); 3036c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 3049bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner // Figure out how many spaces to indent TimerGroup name. 3059bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner unsigned Padding = (80-Name.length())/2; 3069bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Padding > 80) Padding = 0; // Don't allow "negative" numbers 307f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 3089bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner raw_ostream *OutStream = GetLibSupportInfoOutputFile(); 3099bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3109bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner ++NumTimers; 3110613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner { // Scope to contain Total timer: don't allow total timer to drop us to 3120613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner // zero timers. 3139bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Timer Total("TOTAL"); 3149bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3159bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) 3169bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Total.sum(TimersToPrint[i]); 3179bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3180613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner // Print out timing header. 3199bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << "===" << std::string(73, '-') << "===\n" 3209bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner << std::string(Padding, ' ') << Name << "\n" 3219bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner << "===" << std::string(73, '-') 3229bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner << "===\n"; 3239bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3249bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner // If this is not an collection of ungrouped times, print the total time. 3259bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner // Ungrouped timers don't really make sense to add up. We still print the 3269bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner // TOTAL line to make the percentages make sense. 3279bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (this != DefaultTimerGroup) { 3289bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << " Total Execution Time: "; 3299bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3309bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << format("%5.4f", Total.getProcessTime()) << " seconds ("; 3319bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << format("%5.4f", Total.getWallTime()) << " wall clock)\n"; 3329bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner } 3339bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << "\n"; 3349bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3359bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.UserTime) 3369bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << " ---User Time---"; 3379bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.SystemTime) 3389bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << " --System Time--"; 3399bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.getProcessTime()) 3409bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << " --User+System--"; 3419bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << " ---Wall Time---"; 3429bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.getMemUsed()) 3439bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << " ---Mem---"; 3449bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << " --- Name ---\n"; 3459bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3460613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner // Loop through all of the timing data, printing it out. 3479bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) 3489bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner TimersToPrint[i].print(Total, *OutStream); 3499bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3509bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Total.print(Total, *OutStream); 3519bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner *OutStream << '\n'; 3529bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OutStream->flush(); 3536c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 3549bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner --NumTimers; 3559bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3569bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner TimersToPrint.clear(); 3579bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 3580ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner if (OutStream != &errs() && OutStream != &outs()) 3590613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner delete OutStream; // Close the file. 3606c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 361d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 36246d9a6494496d215e850f337b5a723c484212f80Owen Andersonvoid TimerGroup::addTimer() { 363a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 36446d9a6494496d215e850f337b5a723c484212f80Owen Anderson ++NumTimers; 36546d9a6494496d215e850f337b5a723c484212f80Owen Anderson} 36646d9a6494496d215e850f337b5a723c484212f80Owen Anderson 36746d9a6494496d215e850f337b5a723c484212f80Owen Andersonvoid TimerGroup::addTimerToPrint(const Timer &T) { 368a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 36946d9a6494496d215e850f337b5a723c484212f80Owen Anderson TimersToPrint.push_back(Timer(true, T)); 37046d9a6494496d215e850f337b5a723c484212f80Owen Anderson} 37146d9a6494496d215e850f337b5a723c484212f80Owen Anderson 372