Timer.cpp revision 9f9f6d19dd67926446fb89a7b2dc0bda6353645b
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" 22a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner#include "llvm/ADT/StringMap.h" 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 55f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner// GetLibSupportInfoOutputFile - Return a file stream to print our output on. 56f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattnerraw_ostream *llvm::GetLibSupportInfoOutputFile() { 57f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner std::string &LibSupportInfoOutputFilename = getLibSupportInfoOutputFilename(); 58f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner if (LibSupportInfoOutputFilename.empty()) 59f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner return &errs(); 60f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner if (LibSupportInfoOutputFilename == "-") 61f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner return &outs(); 62f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner 63f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner std::string Error; 64f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner raw_ostream *Result = new raw_fd_ostream(LibSupportInfoOutputFilename.c_str(), 65f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner Error, raw_fd_ostream::F_Append); 66f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner if (Error.empty()) 67f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner return Result; 68f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner 69f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner errs() << "Error opening info-output-file '" 70f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner << LibSupportInfoOutputFilename << " for appending!\n"; 71f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner delete Result; 72f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner return &errs(); 73f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner} 74f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner 75f8df3e011c9b32f16bd6f3d4bb8d3d2e26280986Chris Lattner 76200aa6d89b75d2a4f630b85a4a785ae7d18d16bbOwen Andersonstatic TimerGroup *DefaultTimerGroup = 0; 776c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerstatic TimerGroup *getDefaultTimerGroup() { 789bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner TimerGroup *tmp = DefaultTimerGroup; 793b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson sys::MemoryFence(); 809bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (tmp) return tmp; 819bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 829bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner llvm_acquire_global_lock(); 839bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner tmp = DefaultTimerGroup; 843b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson if (!tmp) { 859bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner tmp = new TimerGroup("Miscellaneous Ungrouped Timers"); 869bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner sys::MemoryFence(); 879bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner DefaultTimerGroup = tmp; 883b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson } 899bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner llvm_release_global_lock(); 90c11e84d3e7a432449d453b51b567f2fc5db4e8c0Mikhail Glushenkov 913b8d135879bd045d63174064c6879eaa6581ec00Owen Anderson return tmp; 926c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 936c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 949bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner//===----------------------------------------------------------------------===// 959bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner// Timer Implementation 969bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner//===----------------------------------------------------------------------===// 979bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 98a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnervoid Timer::init(const std::string &N) { 99a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner assert(TG == 0 && "Timer already initialized"); 100a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Name = N; 101a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Started = false; 102a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner TG = getDefaultTimerGroup(); 103b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner TG->addTimer(*this); 1046c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1056c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 106a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnervoid Timer::init(const std::string &N, TimerGroup &tg) { 107a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner assert(TG == 0 && "Timer already initialized"); 108a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Name = N; 109a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Started = false; 110a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner TG = &tg; 111b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner TG->addTimer(*this); 1126c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1136c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1146c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::~Timer() { 115a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (!TG) return; // Never initialized. 116b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner TG->removeTimer(*this); 1176c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1186c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 119e269a1ac1cd795135e91e42527a9814f4807c75aJeff Cohenstatic inline size_t getMemUsage() { 120aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer if (TrackSpace) 121e269a1ac1cd795135e91e42527a9814f4807c75aJeff Cohen return sys::Process::GetMallocUsage(); 122aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer return 0; 123aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer} 124aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer 125a782e75d487006cafffdc256b3c623307fee4dcfChris LattnerTimeRecord TimeRecord::getCurrentTime(bool Start) { 126df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer TimeRecord Result; 127b4db5f3e4b24bfc515bc615b2b6256083c7ef508Chris Lattner 128df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer sys::TimeValue now(0,0); 129df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer sys::TimeValue user(0,0); 130df52c9aaf2ec6fbd0562e849cdba36e620537989Reid Spencer sys::TimeValue sys(0,0); 131b4db5f3e4b24bfc515bc615b2b6256083c7ef508Chris Lattner 1326f2c64d70aad5328a843a6f6a6547ada69ead33bOwen Anderson ssize_t MemUsed = 0; 1337d05563324e538a377ba12ca62b2b5b0fbbba547Reid Spencer if (Start) { 134aeb47b8db9246fc0d5d6e437225fe84524da9202Reid Spencer MemUsed = getMemUsage(); 1359bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner sys::Process::GetTimeUsage(now, user, sys); 1367d05563324e538a377ba12ca62b2b5b0fbbba547Reid Spencer } else { 1379bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner sys::Process::GetTimeUsage(now, user, sys); 138fed1b27d323001682e7cb1bd66bb5d603cabb9f8Chris Lattner MemUsed = getMemUsage(); 1397d05563324e538a377ba12ca62b2b5b0fbbba547Reid Spencer } 1408f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 141a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Result.WallTime = now.seconds() + now.microseconds() / 1000000.0; 1429bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Result.UserTime = user.seconds() + user.microseconds() / 1000000.0; 143a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Result.SystemTime = sys.seconds() + sys.microseconds() / 1000000.0; 1449bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner Result.MemUsed = MemUsed; 1456c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner return Result; 1466c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1476c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 14890aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattnerstatic ManagedStatic<std::vector<Timer*> > ActiveTimers; 1498f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1506c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::startTimer() { 1516c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started = true; 152153d28a414d087cbe20d17329fed358f7fa1258bDan Gohman ActiveTimers->push_back(this); 153a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Time -= TimeRecord::getCurrentTime(true); 1546c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1556c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1566c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::stopTimer() { 157a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Time += TimeRecord::getCurrentTime(false); 1588f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 15990aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner if (ActiveTimers->back() == this) { 16090aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner ActiveTimers->pop_back(); 1618f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } else { 1628f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner std::vector<Timer*>::iterator I = 16390aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner std::find(ActiveTimers->begin(), ActiveTimers->end(), this); 16490aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner assert(I != ActiveTimers->end() && "stop but no startTimer?"); 16590aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattner ActiveTimers->erase(I); 1668f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } 1676c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1686c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1699bb110f78efb6096e70336da83b2015f83fc6233Chris Lattnerstatic void printVal(double Val, double Total, raw_ostream &OS) { 1700613edc5cfe6a6c06db93436a024a265fde2a5abChris Lattner if (Total < 1e-7) // Avoid dividing by zero. 1719bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << " ----- "; 1729bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner else { 1739bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << " " << format("%7.4f", Val) << " ("; 1749bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << format("%5.1f", Val*100/Total) << "%)"; 1759bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner } 1769bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner} 1779bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 178a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnervoid TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const { 179a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (Total.getUserTime()) 180a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner printVal(getUserTime(), Total.getUserTime(), OS); 181a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (Total.getSystemTime()) 182a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner printVal(getSystemTime(), Total.getSystemTime(), OS); 1839bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner if (Total.getProcessTime()) 1849bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner printVal(getProcessTime(), Total.getProcessTime(), OS); 185a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner printVal(getWallTime(), Total.getWallTime(), OS); 1869bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 1879bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner OS << " "; 1889bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 189a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (Total.getMemUsed()) 190a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner OS << format("%9lld", (long long)getMemUsed()) << " "; 1919bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner} 1929bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 1939bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 194d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner//===----------------------------------------------------------------------===// 195d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner// NamedRegionTimer Implementation 196d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner//===----------------------------------------------------------------------===// 197d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 198a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnertypedef StringMap<Timer> Name2TimerMap; 199a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnertypedef StringMap<std::pair<TimerGroup, Name2TimerMap> > Name2PairMap; 2005e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 201a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnerstatic ManagedStatic<Name2TimerMap> NamedTimers; 202a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnerstatic ManagedStatic<Name2PairMap> NamedGroupedTimers; 203d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 20490aa839c88776e3dd0b3a798a98ea30d85b6b53cChris Lattnerstatic Timer &getNamedRegionTimer(const std::string &Name) { 205a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 206a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner 207a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Timer &T = (*NamedTimers)[Name]; 208a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (!T.isInitialized()) 209a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner T.init(Name); 210a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner return T; 211d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner} 212d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 2135e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohmanstatic Timer &getNamedRegionTimer(const std::string &Name, 2145e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman const std::string &GroupName) { 215a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 2165e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 217a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner std::pair<TimerGroup, Name2TimerMap> &GroupEntry = 218a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner (*NamedGroupedTimers)[GroupName]; 2195e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 220a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (GroupEntry.second.empty()) 221a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner GroupEntry.first.setName(GroupName); 2225e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 223a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Timer &T = GroupEntry.second[Name]; 224a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (!T.isInitialized()) 225a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner T.init(Name); 226a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner return T; 2275e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman} 2285e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman 229d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris LattnerNamedRegionTimer::NamedRegionTimer(const std::string &Name) 230d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner : TimeRegion(getNamedRegionTimer(Name)) {} 231d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 2325e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan GohmanNamedRegionTimer::NamedRegionTimer(const std::string &Name, 2335e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman const std::string &GroupName) 2345e84368b26415b3bb7f3f8d9cff3e05938dd82d0Dan Gohman : TimeRegion(getNamedRegionTimer(Name, GroupName)) {} 2358f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 2366c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 2376c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// TimerGroup Implementation 2386c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 2396c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 2409f9f6d19dd67926446fb89a7b2dc0bda6353645bChris LattnerTimerGroup::~TimerGroup() { 2419f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner // If the timer group is destroyed before the timers it owns, accumulate and 2429f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner // print the timing data. 2439f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner while (FirstTimer != 0) 2449f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner removeTimer(*FirstTimer); 2459f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner} 2469f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner 2479f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner 248b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattnervoid TimerGroup::removeTimer(Timer &T) { 249a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson sys::SmartScopedLock<true> L(*TimerLock); 2509bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 251b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner // If the timer was started, move its data to TimersToPrint. 2529f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner if (T.Started) 253b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner TimersToPrint.push_back(std::make_pair(T.Time, T.Name)); 2549f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner 2559f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner T.TG = 0; 256b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 257b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner // Unlink the timer from our list. 258b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner *T.Prev = T.Next; 259b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner if (T.Next) 260b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner T.Next->Prev = T.Prev; 261b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 262b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner // Print the report when all timers in this group are destroyed if some of 263b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner // them were started. 264b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner if (FirstTimer != 0 || TimersToPrint.empty()) 265b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner return; 266b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 267b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner raw_ostream *OutStream = GetLibSupportInfoOutputFile(); 2689f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner 269b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner PrintQueuedTimers(*OutStream); 2709f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner 271b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner if (OutStream != &errs() && OutStream != &outs()) 272b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner delete OutStream; // Close the file. 273b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner} 274b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 275b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattnervoid TimerGroup::addTimer(Timer &T) { 276b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner sys::SmartScopedLock<true> L(*TimerLock); 277b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 278b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner // Add the timer to our list. 279b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner if (FirstTimer) 280b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner FirstTimer->Prev = &T.Next; 281b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner T.Next = FirstTimer; 282b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner T.Prev = &FirstTimer; 283b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner FirstTimer = &T; 284b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner} 2859bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner 286b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattnervoid TimerGroup::PrintQueuedTimers(raw_ostream &OS) { 287b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner // Sort the timers in descending order by amount of time taken. 288b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner std::sort(TimersToPrint.begin(), TimersToPrint.end()); 289b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 290a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner TimeRecord Total; 291a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) 292a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner Total += TimersToPrint[i].first; 293b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 294a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner // Print out timing header. 295b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << "===" << std::string(73, '-') << "===\n"; 296b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner // Figure out how many spaces to indent TimerGroup name. 297b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner unsigned Padding = (80-Name.length())/2; 298b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner if (Padding > 80) Padding = 0; // Don't allow "negative" numbers 299b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS.indent(Padding) << Name << '\n'; 300b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << "===" << std::string(73, '-') << "===\n"; 301b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 302a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner // If this is not an collection of ungrouped times, print the total time. 303a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner // Ungrouped timers don't really make sense to add up. We still print the 304a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner // TOTAL line to make the percentages make sense. 305a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (this != DefaultTimerGroup) { 306b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << " Total Execution Time: "; 307b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << format("%5.4f", Total.getProcessTime()) << " seconds ("; 308b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << format("%5.4f", Total.getWallTime()) << " wall clock)\n"; 3099fa0eff30a0d4fcbc84ac3ada4c47620b5449043Chris Lattner } 310b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << '\n'; 311b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 312a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (Total.getUserTime()) 313b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << " ---User Time---"; 314a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (Total.getSystemTime()) 315b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << " --System Time--"; 316a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (Total.getProcessTime()) 317b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << " --User+System--"; 318b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << " ---Wall Time---"; 319a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner if (Total.getMemUsed()) 320b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << " ---Mem---"; 321b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << " --- Name ---\n"; 322b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 323a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner // Loop through all of the timing data, printing it out. 324a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) { 325a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner const std::pair<TimeRecord, std::string> &Entry = TimersToPrint[e-i-1]; 326b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner Entry.first.print(Total, OS); 327b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << Entry.second << '\n'; 328a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner } 329b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 330b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner Total.print(Total, OS); 331b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS << "Total\n\n"; 332b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner OS.flush(); 333b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner 3349bb110f78efb6096e70336da83b2015f83fc6233Chris Lattner TimersToPrint.clear(); 33546d9a6494496d215e850f337b5a723c484212f80Owen Anderson} 33646d9a6494496d215e850f337b5a723c484212f80Owen Anderson 337