Timer.cpp revision d0fde30ce850b78371fd1386338350591f9ff494
16c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===-- Timer.cpp - Interval Timing Support -------------------------------===// 2b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 5b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// This file was developed by the LLVM research group and is distributed under 6b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 7b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 96c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// 106c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// Interval Timing implementation. 116c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// 126c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 136c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 146c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner#include "Support/Timer.h" 153f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner#include "Support/CommandLine.h" 167a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#include "Config/sys/resource.h" 177a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#include "Config/sys/time.h" 187a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#include "Config/unistd.h" 197a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#include "Config/malloc.h" 206c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner#include <iostream> 216c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner#include <algorithm> 229550dc2df2aad33e92febc0e3a15aca372639a10Chris Lattner#include <functional> 23f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner#include <fstream> 24d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner#include <map> 25f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm { 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 3071336a9c14d2da7fd9ab094eed8c6f3695b864eeChris 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 3371336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner// would get destroyed before the Statistic, causing havoc to ensue. We "fix" 3471336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner// this by creating the string the first time it is needed and never destroying 3571336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner// it. 3671336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattnerstatic std::string &getLibSupportInfoOutputFilename() { 3771336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner static std::string *LibSupportInfoOutputFilename = new std::string(); 3871336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner return *LibSupportInfoOutputFilename; 3971336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner} 406c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 413f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattnernamespace { 427a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#ifdef HAVE_MALLINFO 433f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner cl::opt<bool> 443f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner TrackSpace("track-memory", cl::desc("Enable -time-passes memory " 453f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner "tracking (this may be slow)"), 463f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner cl::Hidden); 477a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#endif 48f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 49f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 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 556c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerstatic TimerGroup *DefaultTimerGroup = 0; 566c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerstatic TimerGroup *getDefaultTimerGroup() { 576c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (DefaultTimerGroup) return DefaultTimerGroup; 586c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner return DefaultTimerGroup = new TimerGroup("Miscellaneous Ungrouped Timers"); 596c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 606c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 616c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(const std::string &N) 628f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N), 636c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started(false), TG(getDefaultTimerGroup()) { 646c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG->addTimer(); 656c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 666c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 676c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(const std::string &N, TimerGroup &tg) 688f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N), 696c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started(false), TG(&tg) { 706c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG->addTimer(); 716c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 726c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 736c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(const Timer &T) { 746c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG = T.TG; 756c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (TG) TG->addTimer(); 766c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner operator=(T); 776c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 786c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 796c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 806c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// Copy ctor, initialize with no TG member. 816c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::Timer(bool, const Timer &T) { 826c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG = T.TG; // Avoid assertion in operator= 836c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner operator=(T); // Copy contents 846c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG = 0; 856c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 866c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 876c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 886c38a79d770f3f0eaa11694ad84ca729b75272c4Chris LattnerTimer::~Timer() { 896c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (TG) { 906c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Started) { 916c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started = false; 926c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG->addTimerToPrint(*this); 936c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 946c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TG->removeTimer(); 956c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 966c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 976c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 988f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattnerstatic long getMemUsage() { 997a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#ifdef HAVE_MALLINFO 1003f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner if (TrackSpace) { 1013f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner struct mallinfo MI = mallinfo(); 102e040f9706697b786a1288971b6d5ab96107bb799Chris Lattner return MI.uordblks/*+MI.hblkhd*/; 1033f39849003689a4d33aecdc744d4d27fd93a8f68Chris Lattner } 1047a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#endif 1058c63883f1ff72191becfda8506e3919a50af20d8Brian Gaeke return 0; 1068f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner} 1078f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1086c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerstruct TimeRecord { 1096c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner double Elapsed, UserTime, SystemTime; 11018eba91a05ccff184820f8afddfddada15e35e65Chris Lattner long MemUsed; 1116c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner}; 1126c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1138f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattnerstatic TimeRecord getTimeRecord(bool Start) { 1146c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner struct rusage RU; 1156c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner struct timeval T; 116bbe5ac1458f3719fd51785f086e9166ccbb0c464Chris Lattner long MemUsed = 0; 1178f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner if (Start) { 1188f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner MemUsed = getMemUsage(); 1198f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner if (getrusage(RUSAGE_SELF, &RU)) 1208f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner perror("getrusage call failed: -time-passes info incorrect!"); 1218f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } 1226c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner gettimeofday(&T, 0); 1238f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1248f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner if (!Start) { 1258f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner MemUsed = getMemUsage(); 1268f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner if (getrusage(RUSAGE_SELF, &RU)) 1278f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner perror("getrusage call failed: -time-passes info incorrect!"); 1286c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 1296c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1306c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TimeRecord Result; 1316c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Result.Elapsed = T.tv_sec + T.tv_usec/1000000.0; 1326c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Result.UserTime = RU.ru_utime.tv_sec + RU.ru_utime.tv_usec/1000000.0; 1336c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Result.SystemTime = RU.ru_stime.tv_sec + RU.ru_stime.tv_usec/1000000.0; 1348f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner Result.MemUsed = MemUsed; 1358f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1366c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner return Result; 1376c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1386c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1398f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattnerstatic std::vector<Timer*> ActiveTimers; 1408f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1416c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::startTimer() { 1426c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started = true; 1438f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner TimeRecord TR = getTimeRecord(true); 1446c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Elapsed -= TR.Elapsed; 1456c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner UserTime -= TR.UserTime; 1466c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner SystemTime -= TR.SystemTime; 14718eba91a05ccff184820f8afddfddada15e35e65Chris Lattner MemUsed -= TR.MemUsed; 1488f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner PeakMemBase = TR.MemUsed; 1498f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner ActiveTimers.push_back(this); 1506c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1516c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1526c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::stopTimer() { 1538f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner TimeRecord TR = getTimeRecord(false); 1546c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Elapsed += TR.Elapsed; 1556c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner UserTime += TR.UserTime; 1566c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner SystemTime += TR.SystemTime; 15718eba91a05ccff184820f8afddfddada15e35e65Chris Lattner MemUsed += TR.MemUsed; 1588f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1598f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner if (ActiveTimers.back() == this) { 1608f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner ActiveTimers.pop_back(); 1618f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } else { 1628f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner std::vector<Timer*>::iterator I = 1638f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner std::find(ActiveTimers.begin(), ActiveTimers.end(), this); 1648f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner assert(I != ActiveTimers.end() && "stop but no startTimer?"); 1658f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner ActiveTimers.erase(I); 1668f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } 1676c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1686c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1696c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid Timer::sum(const Timer &T) { 1706c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Elapsed += T.Elapsed; 1716c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner UserTime += T.UserTime; 1726c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner SystemTime += T.SystemTime; 17318eba91a05ccff184820f8afddfddada15e35e65Chris Lattner MemUsed += T.MemUsed; 1748f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner PeakMem += T.PeakMem; 1756c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 1766c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 1778f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner/// addPeakMemoryMeasurement - This method should be called whenever memory 1788f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner/// usage needs to be checked. It adds a peak memory measurement to the 1798f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner/// currently active timers, which will be printed when the timer group prints 1808f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner/// 1818f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattnervoid Timer::addPeakMemoryMeasurement() { 1828f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner long MemUsed = getMemUsage(); 1838f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 1848f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner for (std::vector<Timer*>::iterator I = ActiveTimers.begin(), 1858f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner E = ActiveTimers.end(); I != E; ++I) 1868f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner (*I)->PeakMem = std::max((*I)->PeakMem, MemUsed-(*I)->PeakMemBase); 1878f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner} 1888f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 189d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner//===----------------------------------------------------------------------===// 190d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner// NamedRegionTimer Implementation 191d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner//===----------------------------------------------------------------------===// 192d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 193d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattnerstatic Timer &getNamedRegionTimer(const std::string &Name) { 194d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner static std::map<std::string, Timer> NamedTimers; 195d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 196d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner std::map<std::string, Timer>::iterator I = NamedTimers.lower_bound(Name); 197d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner if (I != NamedTimers.end() && I->first == Name) 198d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner return I->second; 199d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 200d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner return NamedTimers.insert(I, std::make_pair(Name, Timer(Name)))->second; 201d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner} 202d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 203d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris LattnerNamedRegionTimer::NamedRegionTimer(const std::string &Name) 204d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner : TimeRegion(getNamedRegionTimer(Name)) {} 205d5a310e4b3251410d4afd58ccea5ec7f0cb13d5fChris Lattner 2068f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner 2076c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 2086c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner// TimerGroup Implementation 2096c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===// 2106c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 211f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner// printAlignedFP - Simulate the printf "%A.Bf" format, where A is the 212f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner// TotalWidth size, and B is the AfterDec size. 213f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner// 214f205fec78ae79707464d568bad297bc69fd1db78Chris Lattnerstatic void printAlignedFP(double Val, unsigned AfterDec, unsigned TotalWidth, 215f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner std::ostream &OS) { 216f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner assert(TotalWidth >= AfterDec+1 && "Bad FP Format!"); 217f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS.width(TotalWidth-AfterDec-1); 218f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner char OldFill = OS.fill(); 219f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS.fill(' '); 220f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << (int)Val; // Integer part; 221f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << "."; 222f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS.width(AfterDec); 223f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS.fill('0'); 224f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner unsigned ResultFieldSize = 1; 225f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner while (AfterDec--) ResultFieldSize *= 10; 226f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << (int)(Val*ResultFieldSize) % ResultFieldSize; 227f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS.fill(OldFill); 228f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner} 229f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 230f205fec78ae79707464d568bad297bc69fd1db78Chris Lattnerstatic void printVal(double Val, double Total, std::ostream &OS) { 2316c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Total < 1e-7) // Avoid dividing by zero... 232f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << " ----- "; 233f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner else { 234f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << " "; 235f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printAlignedFP(Val, 4, 7, OS); 236f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << " ("; 237f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printAlignedFP(Val*100/Total, 1, 5, OS); 238f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << "%)"; 239f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner } 2406c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 2416c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 242f205fec78ae79707464d568bad297bc69fd1db78Chris Lattnervoid Timer::print(const Timer &Total, std::ostream &OS) { 2436c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Total.UserTime) 244f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printVal(UserTime, Total.UserTime, OS); 2456c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Total.SystemTime) 246f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printVal(SystemTime, Total.SystemTime, OS); 2476c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Total.getProcessTime()) 248f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printVal(getProcessTime(), Total.getProcessTime(), OS); 249f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printVal(Elapsed, Total.Elapsed, OS); 2506c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 251f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << " "; 2526c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 253f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (Total.MemUsed) { 254f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS.width(9); 255f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << MemUsed << " "; 256f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner } 2578f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner if (Total.PeakMem) { 258f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (PeakMem) { 259f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS.width(9); 260f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << PeakMem << " "; 261f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner } else 262f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << " "; 2638f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner } 264f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner OS << Name << "\n"; 2656c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 2666c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Started = false; // Once printed, don't print again 2676c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 2686c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 269f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner// GetLibSupportInfoOutputFile - Return a file stream to print our output on... 270d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekestd::ostream * 271d0fde30ce850b78371fd1386338350591f9ff494Brian GaekeGetLibSupportInfoOutputFile() { 27271336a9c14d2da7fd9ab094eed8c6f3695b864eeChris Lattner std::string &LibSupportInfoOutputFilename = getLibSupportInfoOutputFilename(); 273f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (LibSupportInfoOutputFilename.empty()) 274f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner return &std::cerr; 275f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (LibSupportInfoOutputFilename == "-") 276f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner return &std::cout; 277f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 278f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner std::ostream *Result = new std::ofstream(LibSupportInfoOutputFilename.c_str(), 279903c2d11e2dfadaaa7c04c2e46bac62d82e7ed15Chris Lattner std::ios::app); 280f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (!Result->good()) { 281f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner std::cerr << "Error opening info-output-file '" 282f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner << LibSupportInfoOutputFilename << " for appending!\n"; 283f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner delete Result; 284f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner return &std::cerr; 285f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner } 286f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner return Result; 287f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner} 288f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 2896c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 2906c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnervoid TimerGroup::removeTimer() { 2916c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (--NumTimers == 0 && !TimersToPrint.empty()) { // Print timing report... 2926c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner // Sort the timers in descending order by amount of time taken... 2936c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner std::sort(TimersToPrint.begin(), TimersToPrint.end(), 2946c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner std::greater<Timer>()); 2956c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 2966c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner // Figure out how many spaces to indent TimerGroup name... 2976c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner unsigned Padding = (80-Name.length())/2; 2986c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Padding > 80) Padding = 0; // Don't allow "negative" numbers 2996c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 300f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner std::ostream *OutStream = GetLibSupportInfoOutputFile(); 301f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 3026c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner ++NumTimers; 3036c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner { // Scope to contain Total timer... don't allow total timer to drop us to 3046c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner // zero timers... 3056c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Timer Total("TOTAL"); 3066c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 3076c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) 3086c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner Total.sum(TimersToPrint[i]); 3096c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 3106c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner // Print out timing header... 311f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << "===" << std::string(73, '-') << "===\n" 312f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner << std::string(Padding, ' ') << Name << "\n" 313f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner << "===" << std::string(73, '-') 314f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner << "===\n Total Execution Time: "; 3158166b7cdb891e0d3c5789260248211a8b6e99787Chris Lattner 316f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printAlignedFP(Total.getProcessTime(), 4, 5, *OutStream); 317f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " seconds ("; 318f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner printAlignedFP(Total.getWallTime(), 4, 5, *OutStream); 319f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " wall clock)\n\n"; 3206c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 3216c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Total.UserTime) 322f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " ---User Time---"; 3236c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Total.SystemTime) 324f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " --System Time--"; 3256c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (Total.getProcessTime()) 326f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " --User+System--"; 327f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " ---Wall Time---"; 32818eba91a05ccff184820f8afddfddada15e35e65Chris Lattner if (Total.getMemUsed()) 329f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " ---Mem---"; 3308f0d824dd7d3ad72ce2212556f306a69310dff3eChris Lattner if (Total.getPeakMem()) 331f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " -PeakMem-"; 332f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << " --- Name ---\n"; 3336c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 3346c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner // Loop through all of the timing data, printing it out... 3356c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) 336f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner TimersToPrint[i].print(Total, *OutStream); 3376c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 338f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner Total.print(Total, *OutStream); 339f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner *OutStream << std::endl; // Flush output 3406c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 3416c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner --NumTimers; 3426c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 3436c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner TimersToPrint.clear(); 344f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner 345f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner if (OutStream != &std::cerr && OutStream != &std::cout) 346f205fec78ae79707464d568bad297bc69fd1db78Chris Lattner delete OutStream; // Close the file... 3476c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 3486c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner 3496c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner // Delete default timer group! 3506c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner if (NumTimers == 0 && this == DefaultTimerGroup) { 3516c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner delete DefaultTimerGroup; 3526c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner DefaultTimerGroup = 0; 3536c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner } 3546c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner} 355d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 356d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace 357