diff --git a/llvm/include/llvm/IR/PassTimingInfo.h b/llvm/include/llvm/IR/PassTimingInfo.h --- a/llvm/include/llvm/IR/PassTimingInfo.h +++ b/llvm/include/llvm/IR/PassTimingInfo.h @@ -55,11 +55,9 @@ /// A group of all pass-timing timers. TimerGroup TG; + using TimerVector = llvm::SmallVector, 4>; /// Map of timers for pass invocations - DenseMap> TimingData; - - /// Map that counts invocations of passes, for use in UniqPassID construction. - StringMap PassIDCountMap; + StringMap TimingData; /// Stack of currently active timers. SmallVector TimerStack; @@ -96,9 +94,6 @@ /// Returns the new timer for each new run of the pass. Timer &getPassTimer(StringRef PassID); - /// Returns the incremented counter for the next invocation of \p PassID. - unsigned nextPassID(StringRef PassID) { return ++PassIDCountMap[PassID]; } - void startTimer(StringRef PassID); void stopTimer(StringRef PassID); diff --git a/llvm/lib/IR/PassTimingInfo.cpp b/llvm/lib/IR/PassTimingInfo.cpp --- a/llvm/lib/IR/PassTimingInfo.cpp +++ b/llvm/lib/IR/PassTimingInfo.cpp @@ -168,17 +168,18 @@ /// Returns the timer for the specified pass invocation of \p PassID. /// Each time it creates a new timer. Timer &TimePassesHandler::getPassTimer(StringRef PassID) { - // Bump counts for each request of the timer. - unsigned Count = nextPassID(PassID); + // Take a vector of Timers created for this \p PassID and append + // one more timer to it. + TimerVector &Timers = TimingData[PassID]; + unsigned Count = Timers.size() + 1; - // Unconditionally appending description with a pass-invocation number. std::string FullDesc = formatv("{0} #{1}", PassID, Count).str(); - PassInvocationID UID{PassID, Count}; Timer *T = new Timer(PassID, FullDesc, TG); - auto Pair = TimingData.try_emplace(UID, T); - assert(Pair.second && "should always create a new timer"); - return *(Pair.first->second.get()); + Timers.emplace_back(T); + assert(Count == Timers.size() && "sanity check"); + + return *T; } TimePassesHandler::TimePassesHandler(bool Enabled) @@ -198,17 +199,23 @@ dbgs() << "Dumping timers for " << getTypeName() << ":\n\tRunning:\n"; for (auto &I : TimingData) { - const Timer *MyTimer = I.second.get(); - if (!MyTimer || MyTimer->isRunning()) - dbgs() << "\tTimer " << MyTimer << " for pass " << I.first.first << "(" - << I.first.second << ")\n"; + StringRef PassID = I.getKey(); + const TimerVector& MyTimers = I.getValue(); + for (unsigned idx = 0; idx < MyTimers.size(); idx++) { + const Timer* MyTimer = MyTimers[idx].get(); + if (MyTimer && MyTimer->isRunning()) + dbgs() << "\tTimer " << MyTimer << " for pass " << PassID << "(" << idx << ")\n"; + } } dbgs() << "\tTriggered:\n"; for (auto &I : TimingData) { - const Timer *MyTimer = I.second.get(); - if (!MyTimer || (MyTimer->hasTriggered() && !MyTimer->isRunning())) - dbgs() << "\tTimer " << MyTimer << " for pass " << I.first.first << "(" - << I.first.second << ")\n"; + StringRef PassID = I.getKey(); + const TimerVector& MyTimers = I.getValue(); + for (unsigned idx = 0; idx < MyTimers.size(); idx++) { + const Timer* MyTimer = MyTimers[idx].get(); + if (MyTimer && MyTimer->hasTriggered() && !MyTimer->isRunning()) + dbgs() << "\tTimer " << MyTimer << " for pass " << PassID << "(" << idx << ")\n"; + } } }