Revert create_symbolic_link and both depending changes
[oota-llvm.git] / lib / Support / Timer.cpp
index ace9158f6c027eb5ef60c6031e85598621c4ac20..7cf4d372a55e4e92746204b95856a4b7e1239d3c 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Timer.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Format.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/Process.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringMap.h"
 using namespace llvm;
 
 // CreateInfoOutputFile - Return a file stream to print our output on.
@@ -55,20 +54,24 @@ namespace {
 
 // CreateInfoOutputFile - Return a file stream to print our output on.
 raw_ostream *llvm::CreateInfoOutputFile() {
-  std::string &LibSupportInfoOutputFilename = getLibSupportInfoOutputFilename();
-  if (LibSupportInfoOutputFilename.empty())
+  const std::string &OutputFilename = getLibSupportInfoOutputFilename();
+  if (OutputFilename.empty())
     return new raw_fd_ostream(2, false); // stderr.
-  if (LibSupportInfoOutputFilename == "-")
+  if (OutputFilename == "-")
     return new raw_fd_ostream(1, false); // stdout.
   
+  // Append mode is used because the info output file is opened and closed
+  // each time -stats or -time-passes wants to print output to it. To
+  // compensate for this, the test-suite Makefiles have code to delete the
+  // info output file before running commands which write to it.
   std::string Error;
-  raw_ostream *Result = new raw_fd_ostream(LibSupportInfoOutputFilename.c_str(),
-                                           Error, raw_fd_ostream::F_Append);
+  raw_ostream *Result = new raw_fd_ostream(
+      OutputFilename.c_str(), Error, sys::fs::F_Append | sys::fs::F_Text);
   if (Error.empty())
     return Result;
   
   errs() << "Error opening info-output-file '"
-    << LibSupportInfoOutputFilename << " for appending!\n";
+    << OutputFilename << " for appending!\n";
   delete Result;
   return new raw_fd_ostream(2, false); // stderr.
 }
@@ -96,17 +99,17 @@ static TimerGroup *getDefaultTimerGroup() {
 // Timer Implementation
 //===----------------------------------------------------------------------===//
 
-void Timer::init(const std::string &N) {
+void Timer::init(StringRef N) {
   assert(TG == 0 && "Timer already initialized");
-  Name = N;
+  Name.assign(N.begin(), N.end());
   Started = false;
   TG = getDefaultTimerGroup();
   TG->addTimer(*this);
 }
 
-void Timer::init(const std::string &N, TimerGroup &tg) {
+void Timer::init(StringRef N, TimerGroup &tg) {
   assert(TG == 0 && "Timer already initialized");
-  Name = N;
+  Name.assign(N.begin(), N.end());
   Started = false;
   TG = &tg;
   TG->addTimer(*this);
@@ -164,10 +167,8 @@ void Timer::stopTimer() {
 static void printVal(double Val, double Total, raw_ostream &OS) {
   if (Total < 1e-7)   // Avoid dividing by zero.
     OS << "        -----     ";
-  else {
-    OS << "  " << format("%7.4f", Val) << " (";
-    OS << format("%5.1f", Val*100/Total) << "%)";
-  }
+  else
+    OS << format("  %7.4f (%5.1f%%)", Val, Val*100/Total);
 }
 
 void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const {
@@ -182,7 +183,7 @@ void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const {
   OS << "  ";
   
   if (Total.getMemUsed())
-    OS << format("%9lld", (long long)getMemUsed()) << "  ";
+    OS << format("%9" PRId64 "  ", (int64_t)getMemUsed());
 }
 
 
@@ -190,6 +191,8 @@ void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const {
 //   NamedRegionTimer Implementation
 //===----------------------------------------------------------------------===//
 
+namespace {
+
 typedef StringMap<Timer> Name2TimerMap;
 
 class Name2PairMap {
@@ -201,7 +204,7 @@ public:
       delete I->second.first;
   }
   
-  Timer &get(const std::string &Name, const std::string &GroupName) {
+  Timer &get(StringRef Name, StringRef GroupName) {
     sys::SmartScopedLock<true> L(*TimerLock);
     
     std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
@@ -216,10 +219,12 @@ public:
   }
 };
 
+}
+
 static ManagedStatic<Name2TimerMap> NamedTimers;
 static ManagedStatic<Name2PairMap> NamedGroupedTimers;
 
-static Timer &getNamedRegionTimer(const std::string &Name) {
+static Timer &getNamedRegionTimer(StringRef Name) {
   sys::SmartScopedLock<true> L(*TimerLock);
   
   Timer &T = (*NamedTimers)[Name];
@@ -228,22 +233,45 @@ static Timer &getNamedRegionTimer(const std::string &Name) {
   return T;
 }
 
-NamedRegionTimer::NamedRegionTimer(const std::string &Name)
-  : TimeRegion(getNamedRegionTimer(Name)) {}
+NamedRegionTimer::NamedRegionTimer(StringRef Name,
+                                   bool Enabled)
+  : TimeRegion(!Enabled ? 0 : &getNamedRegionTimer(Name)) {}
 
-NamedRegionTimer::NamedRegionTimer(const std::string &Name,
-                                   const std::string &GroupName)
-  : TimeRegion(NamedGroupedTimers->get(Name, GroupName)) {}
+NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef GroupName,
+                                   bool Enabled)
+  : TimeRegion(!Enabled ? 0 : &NamedGroupedTimers->get(Name, GroupName)) {}
 
 //===----------------------------------------------------------------------===//
 //   TimerGroup Implementation
 //===----------------------------------------------------------------------===//
 
+/// TimerGroupList - This is the global list of TimerGroups, maintained by the
+/// TimerGroup ctor/dtor and is protected by the TimerLock lock.
+static TimerGroup *TimerGroupList = 0;
+
+TimerGroup::TimerGroup(StringRef name)
+  : Name(name.begin(), name.end()), FirstTimer(0) {
+    
+  // Add the group to TimerGroupList.
+  sys::SmartScopedLock<true> L(*TimerLock);
+  if (TimerGroupList)
+    TimerGroupList->Prev = &Next;
+  Next = TimerGroupList;
+  Prev = &TimerGroupList;
+  TimerGroupList = this;
+}
+
 TimerGroup::~TimerGroup() {
   // If the timer group is destroyed before the timers it owns, accumulate and
   // print the timing data.
   while (FirstTimer != 0)
     removeTimer(*FirstTimer);
+  
+  // Remove the group from the TimerGroupList.
+  sys::SmartScopedLock<true> L(*TimerLock);
+  *Prev = Next;
+  if (Next)
+    Next->Prev = Prev;
 }
 
 
@@ -301,11 +329,9 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
   // If this is not an collection of ungrouped times, print the total time.
   // Ungrouped timers don't really make sense to add up.  We still print the
   // TOTAL line to make the percentages make sense.
-  if (this != DefaultTimerGroup) {
-    OS << "  Total Execution Time: ";
-    OS << format("%5.4f", Total.getProcessTime()) << " seconds (";
-    OS << format("%5.4f", Total.getWallTime()) << " wall clock)\n";
-  }
+  if (this != DefaultTimerGroup)
+    OS << format("  Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
+                 Total.getProcessTime(), Total.getWallTime());
   OS << '\n';
   
   if (Total.getUserTime())
@@ -352,3 +378,11 @@ void TimerGroup::print(raw_ostream &OS) {
   if (!TimersToPrint.empty())
     PrintQueuedTimers(OS);
 }
+
+/// printAll - This static method prints all timers and clears them all out.
+void TimerGroup::printAll(raw_ostream &OS) {
+  sys::SmartScopedLock<true> L(*TimerLock);
+
+  for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
+    TG->print(OS);
+}