| OLD | NEW | 
|    1 //===- subzero/src/IceTimerTree.cpp - Pass timer defs ---------------------===// |    1 //===- subzero/src/IceTimerTree.cpp - Pass timer defs ---------------------===// | 
|    2 // |    2 // | 
|    3 //                        The Subzero Code Generator |    3 //                        The Subzero Code Generator | 
|    4 // |    4 // | 
|    5 // This file is distributed under the University of Illinois Open Source |    5 // This file is distributed under the University of Illinois Open Source | 
|    6 // License. See LICENSE.TXT for details. |    6 // License. See LICENSE.TXT for details. | 
|    7 // |    7 // | 
|    8 //===----------------------------------------------------------------------===// |    8 //===----------------------------------------------------------------------===// | 
|    9 // |    9 // | 
|   10 // This file defines the TimerTree class, which tracks flat and |   10 // This file defines the TimerTree class, which tracks flat and | 
|   11 // cumulative execution time collection of call chains. |   11 // cumulative execution time collection of call chains. | 
|   12 // |   12 // | 
|   13 //===----------------------------------------------------------------------===// |   13 //===----------------------------------------------------------------------===// | 
|   14  |   14  | 
|   15 #include "llvm/Support/Timer.h" |   15 #include "llvm/Support/Timer.h" | 
|   16  |   16  | 
|   17 #include "IceDefs.h" |   17 #include "IceDefs.h" | 
|   18 #include "IceTimerTree.h" |   18 #include "IceTimerTree.h" | 
|   19  |   19  | 
|   20 namespace Ice { |   20 namespace Ice { | 
|   21  |   21  | 
|   22 std::vector<IceString> TimerStack::IDs; |   22 TimerStack::TimerStack(const IceString &Name) | 
|   23  |   23     : Name(Name), FirstTimestamp(timestamp()), LastTimestamp(FirstTimestamp), | 
|   24 TimerStack::TimerStack(const IceString &TopLevelName) |  | 
|   25     : FirstTimestamp(timestamp()), LastTimestamp(FirstTimestamp), |  | 
|   26       StateChangeCount(0), StackTop(0) { |   24       StateChangeCount(0), StackTop(0) { | 
|   27   Nodes.resize(1); // Reserve Nodes[0] for the root node. |   25   Nodes.resize(1); // Reserve Nodes[0] for the root node. | 
|   28   push(getTimerID(TopLevelName)); |   26   IDs.resize(TT__num); | 
 |   27 #define STR(s) #s | 
 |   28 #define X(tag)                                                                 \ | 
 |   29   IDs[TT_##tag] = STR(tag);                                                    \ | 
 |   30   IDsIndex[STR(tag)] = TT_##tag; | 
 |   31   TIMERTREE_TABLE; | 
 |   32 #undef X | 
 |   33 #undef STR | 
|   29 } |   34 } | 
|   30  |   35  | 
|   31 // Returns the unique timer ID for the given Name, creating a new ID |   36 // Returns the unique timer ID for the given Name, creating a new ID | 
|   32 // if needed.  For performance reasons, it's best to make only one |   37 // if needed. | 
|   33 // call per Name and cache the result, e.g. via a static initializer. |  | 
|   34 TimerIdT TimerStack::getTimerID(const IceString &Name) { |   38 TimerIdT TimerStack::getTimerID(const IceString &Name) { | 
|   35   TimerIdT Size = IDs.size(); |   39   if (IDsIndex.find(Name) == IDsIndex.end()) { | 
|   36   for (TimerIdT i = 0; i < Size; ++i) { |   40     IDsIndex[Name] = IDs.size(); | 
|   37     if (IDs[i] == Name) |   41     IDs.push_back(Name); | 
|   38       return i; |  | 
|   39   } |   42   } | 
|   40   IDs.push_back(Name); |   43   return IDsIndex[Name]; | 
|   41   return Size; |  | 
|   42 } |   44 } | 
|   43  |   45  | 
|   44 // Pushes a new marker onto the timer stack. |   46 // Pushes a new marker onto the timer stack. | 
|   45 void TimerStack::push(TimerIdT ID) { |   47 void TimerStack::push(TimerIdT ID) { | 
|   46   update(); |   48   update(); | 
|   47   if (Nodes[StackTop].Children.size() <= ID) |   49   if (Nodes[StackTop].Children.size() <= ID) | 
|   48     Nodes[StackTop].Children.resize(ID + 1); |   50     Nodes[StackTop].Children.resize(ID + 1); | 
|   49   if (Nodes[StackTop].Children[ID] == 0) { |   51   if (Nodes[StackTop].Children[ID] == 0) { | 
|   50     TTindex Size = Nodes.size(); |   52     TTindex Size = Nodes.size(); | 
|   51     Nodes[StackTop].Children[ID] = Size; |   53     Nodes[StackTop].Children[ID] = Size; | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  105   for (auto I = Map.rbegin(), E = Map.rend(); I != E; ++I) { |  107   for (auto I = Map.rbegin(), E = Map.rend(); I != E; ++I) { | 
|  106     char buf[80]; |  108     char buf[80]; | 
|  107     snprintf(buf, llvm::array_lengthof(buf), "  %10.6f (%4.1f%%): ", I->first, |  109     snprintf(buf, llvm::array_lengthof(buf), "  %10.6f (%4.1f%%): ", I->first, | 
|  108              I->first * 100 / TotalTime); |  110              I->first * 100 / TotalTime); | 
|  109     Str << buf << I->second << "\n"; |  111     Str << buf << I->second << "\n"; | 
|  110   } |  112   } | 
|  111 } |  113 } | 
|  112  |  114  | 
|  113 } // end of anonymous namespace |  115 } // end of anonymous namespace | 
|  114  |  116  | 
|  115 void TimerStack::dump(Ostream &Str) { |  117 void TimerStack::dump(Ostream &Str, bool DumpCumulative) { | 
|  116   update(); |  118   update(); | 
|  117   double TotalTime = LastTimestamp - FirstTimestamp; |  119   double TotalTime = LastTimestamp - FirstTimestamp; | 
|  118   assert(TotalTime); |  120   assert(TotalTime); | 
|  119   Str << "Cumulative function times:\n"; |  121   if (DumpCumulative) { | 
|  120   DumpMapType CumulativeMap; |  122     Str << Name << " - Cumulative times:\n"; | 
|  121   for (TTindex i = 1; i < Nodes.size(); ++i) { |  123     DumpMapType CumulativeMap; | 
|  122     TTindex Prefix = i; |  124     for (TTindex i = 1; i < Nodes.size(); ++i) { | 
|  123     IceString Suffix = ""; |  125       TTindex Prefix = i; | 
|  124     while (Prefix) { |  126       IceString Suffix = ""; | 
|  125       if (Suffix.empty()) |  127       while (Prefix) { | 
|  126         Suffix = IDs[Nodes[Prefix].Interior]; |  128         if (Suffix.empty()) | 
|  127       else |  129           Suffix = IDs[Nodes[Prefix].Interior]; | 
|  128         Suffix = IDs[Nodes[Prefix].Interior] + "." + Suffix; |  130         else | 
|  129       assert(Nodes[Prefix].Parent < Prefix); |  131           Suffix = IDs[Nodes[Prefix].Interior] + "." + Suffix; | 
|  130       Prefix = Nodes[Prefix].Parent; |  132         assert(Nodes[Prefix].Parent < Prefix); | 
 |  133         Prefix = Nodes[Prefix].Parent; | 
 |  134       } | 
 |  135       CumulativeMap.insert(std::make_pair(Nodes[i].Time, Suffix)); | 
|  131     } |  136     } | 
|  132     CumulativeMap.insert(std::make_pair(Nodes[i].Time, Suffix)); |  137     dumpHelper(Str, CumulativeMap, TotalTime); | 
|  133   } |  138   } | 
|  134   dumpHelper(Str, CumulativeMap, TotalTime); |  139   Str << Name << " - Flat times:\n"; | 
|  135   Str << "Flat function times:\n"; |  | 
|  136   DumpMapType FlatMap; |  140   DumpMapType FlatMap; | 
|  137   for (TimerIdT i = 0; i < LeafTimes.size(); ++i) { |  141   for (TimerIdT i = 0; i < LeafTimes.size(); ++i) { | 
|  138     FlatMap.insert(std::make_pair(LeafTimes[i], IDs[i])); |  142     FlatMap.insert(std::make_pair(LeafTimes[i], IDs[i])); | 
|  139   } |  143   } | 
|  140   dumpHelper(Str, FlatMap, TotalTime); |  144   dumpHelper(Str, FlatMap, TotalTime); | 
|  141   Str << "Number of timer updates: " << StateChangeCount << "\n"; |  145   Str << "Number of timer updates: " << StateChangeCount << "\n"; | 
|  142 } |  146 } | 
|  143  |  147  | 
|  144 double TimerStack::timestamp() { |  148 double TimerStack::timestamp() { | 
|  145   // TODO: Implement in terms of std::chrono for C++11. |  149   // TODO: Implement in terms of std::chrono for C++11. | 
|  146   return llvm::TimeRecord::getCurrentTime(false).getWallTime(); |  150   return llvm::TimeRecord::getCurrentTime(false).getWallTime(); | 
|  147 } |  151 } | 
|  148  |  152  | 
|  149 } // end of namespace Ice |  153 } // end of namespace Ice | 
| OLD | NEW |