| Index: src/IceTimerTree.cpp
|
| diff --git a/src/IceTimerTree.cpp b/src/IceTimerTree.cpp
|
| index cfe3ca5cbaf358a78bf0deea5496c55d72300610..1fb098d69537be48709c252da0d3f97956cea3d4 100644
|
| --- a/src/IceTimerTree.cpp
|
| +++ b/src/IceTimerTree.cpp
|
| @@ -45,7 +45,8 @@ TimerIdT TimerStack::getTimerID(const IceString &Name) {
|
|
|
| // Pushes a new marker onto the timer stack.
|
| void TimerStack::push(TimerIdT ID) {
|
| - update();
|
| + const bool UpdateCounts = false;
|
| + update(UpdateCounts);
|
| if (Nodes[StackTop].Children.size() <= ID)
|
| Nodes[StackTop].Children.resize(ID + 1);
|
| if (Nodes[StackTop].Children[ID] == 0) {
|
| @@ -61,7 +62,8 @@ void TimerStack::push(TimerIdT ID) {
|
| // Pop the top marker from the timer stack. Validates via assert()
|
| // that the expected marker is popped.
|
| void TimerStack::pop(TimerIdT ID) {
|
| - update();
|
| + const bool UpdateCounts = true;
|
| + update(UpdateCounts);
|
| assert(StackTop);
|
| assert(Nodes[StackTop].Parent < StackTop);
|
| // Verify that the expected ID is being popped.
|
| @@ -74,7 +76,7 @@ void TimerStack::pop(TimerIdT ID) {
|
|
|
| // At a state change (e.g. push or pop), updates the flat and
|
| // cumulative timings for everything on the timer stack.
|
| -void TimerStack::update() {
|
| +void TimerStack::update(bool UpdateCounts) {
|
| ++StateChangeCount;
|
| // Whenever the stack is about to change, we grab the time delta
|
| // since the last change and add it to all active cumulative
|
| @@ -83,13 +85,20 @@ void TimerStack::update() {
|
| double Delta = Current - LastTimestamp;
|
| if (StackTop) {
|
| TimerIdT Leaf = Nodes[StackTop].Interior;
|
| - if (Leaf >= LeafTimes.size())
|
| + if (Leaf >= LeafTimes.size()) {
|
| LeafTimes.resize(Leaf + 1);
|
| + LeafCounts.resize(Leaf + 1);
|
| + }
|
| LeafTimes[Leaf] += Delta;
|
| + if (UpdateCounts)
|
| + ++LeafCounts[Leaf];
|
| }
|
| TTindex Prefix = StackTop;
|
| while (Prefix) {
|
| Nodes[Prefix].Time += Delta;
|
| + // Only update a leaf node count, not the internal node counts.
|
| + if (UpdateCounts && Prefix == StackTop)
|
| + ++Nodes[Prefix].UpdateCount;
|
| TTindex Next = Nodes[Prefix].Parent;
|
| assert(Next < Prefix);
|
| Prefix = Next;
|
| @@ -105,8 +114,10 @@ void TimerStack::reset() {
|
| StateChangeCount = 0;
|
| FirstTimestamp = LastTimestamp = timestamp();
|
| LeafTimes.assign(LeafTimes.size(), 0);
|
| + LeafCounts.assign(LeafCounts.size(), 0);
|
| for (TimerTreeNode &Node : Nodes) {
|
| Node.Time = 0;
|
| + Node.UpdateCount = 0;
|
| }
|
| }
|
|
|
| @@ -125,14 +136,36 @@ void dumpHelper(Ostream &Str, const DumpMapType &Map, double TotalTime) {
|
| }
|
| }
|
|
|
| +// Write a printf() format string into Buf[], in the format "[%5lu] ",
|
| +// where "5" is actually the number of digits in MaxVal. E.g.,
|
| +// MaxVal=0 ==> "[%1lu] "
|
| +// MaxVal=5 ==> "[%1lu] "
|
| +// MaxVal=9876 ==> "[%4lu] "
|
| +void makePrintfFormatString(char *Buf, size_t BufLen, size_t MaxVal) {
|
| + int NumDigits = 0;
|
| + do {
|
| + ++NumDigits;
|
| + MaxVal /= 10;
|
| + } while (MaxVal);
|
| + snprintf(Buf, BufLen, "[%%%dlu] ", NumDigits);
|
| +}
|
| +
|
| } // end of anonymous namespace
|
|
|
| void TimerStack::dump(Ostream &Str, bool DumpCumulative) {
|
| - update();
|
| + const bool UpdateCounts = true;
|
| + update(UpdateCounts);
|
| double TotalTime = LastTimestamp - FirstTimestamp;
|
| assert(TotalTime);
|
| + char FmtString[30], PrefixStr[30];
|
| if (DumpCumulative) {
|
| Str << Name << " - Cumulative times:\n";
|
| + size_t MaxInternalCount = 0;
|
| + for (TimerTreeNode &Node : Nodes)
|
| + MaxInternalCount = std::max(MaxInternalCount, Node.UpdateCount);
|
| + makePrintfFormatString(FmtString, llvm::array_lengthof(FmtString),
|
| + MaxInternalCount);
|
| +
|
| DumpMapType CumulativeMap;
|
| for (TTindex i = 1; i < Nodes.size(); ++i) {
|
| TTindex Prefix = i;
|
| @@ -145,14 +178,25 @@ void TimerStack::dump(Ostream &Str, bool DumpCumulative) {
|
| assert(Nodes[Prefix].Parent < Prefix);
|
| Prefix = Nodes[Prefix].Parent;
|
| }
|
| - CumulativeMap.insert(std::make_pair(Nodes[i].Time, Suffix));
|
| + snprintf(PrefixStr, llvm::array_lengthof(PrefixStr), FmtString,
|
| + Nodes[i].UpdateCount);
|
| + CumulativeMap.insert(std::make_pair(Nodes[i].Time, PrefixStr + Suffix));
|
| }
|
| dumpHelper(Str, CumulativeMap, TotalTime);
|
| }
|
| Str << Name << " - Flat times:\n";
|
| + size_t MaxLeafCount = 0;
|
| + for (size_t Count : LeafCounts)
|
| + MaxLeafCount = std::max(MaxLeafCount, Count);
|
| + makePrintfFormatString(FmtString, llvm::array_lengthof(FmtString),
|
| + MaxLeafCount);
|
| DumpMapType FlatMap;
|
| for (TimerIdT i = 0; i < LeafTimes.size(); ++i) {
|
| - FlatMap.insert(std::make_pair(LeafTimes[i], IDs[i]));
|
| + if (LeafCounts[i]) {
|
| + snprintf(PrefixStr, llvm::array_lengthof(PrefixStr), FmtString,
|
| + LeafCounts[i]);
|
| + FlatMap.insert(std::make_pair(LeafTimes[i], PrefixStr + IDs[i]));
|
| + }
|
| }
|
| dumpHelper(Str, FlatMap, TotalTime);
|
| Str << "Number of timer updates: " << StateChangeCount << "\n";
|
|
|