Index: include/llvm/Support/DebugCounter.h =================================================================== --- include/llvm/Support/DebugCounter.h +++ include/llvm/Support/DebugCounter.h @@ -77,23 +77,19 @@ auto &Us = instance(); auto Result = Us.Counters.find(CounterName); if (Result != Us.Counters.end()) { - auto &CounterPair = Result->second; - // We only execute while the skip (first) is zero and the count (second) - // is non-zero. + auto &CounterInfo = Result->second; + ++CounterInfo.Count; + + // We only execute while the Skip is not smaller than Count, + // and the StopAfter + Skip is larger than Count. // Negative counters always execute. - if (CounterPair.first < 0) + if (CounterInfo.Skip < 0) return true; - if (CounterPair.first != 0) { - --CounterPair.first; + if (CounterInfo.Skip >= CounterInfo.Count) return false; - } - if (CounterPair.second < 0) - return true; - if (CounterPair.second != 0) { - --CounterPair.second; + if (CounterInfo.StopAfter < 0) return true; - } - return false; + return CounterInfo.StopAfter + CounterInfo.Skip >= CounterInfo.Count; } // Didn't find the counter, should we warn? return true; @@ -107,18 +103,18 @@ return instance().Counters.count(ID); } - // Return the skip and count for a counter. This only works for set counters. - static std::pair getCounterValue(unsigned ID) { + // Return the Count for a counter. This only works for set counters. + static int64_t getCounterValue(unsigned ID) { auto &Us = instance(); auto Result = Us.Counters.find(ID); assert(Result != Us.Counters.end() && "Asking about a non-set counter"); - return Result->second; + return Result->second.Count; } - // Set a registered counter to a given value. - static void setCounterValue(unsigned ID, const std::pair &Val) { + // Set a registered counter to a given Count value. + static void setCounterValue(unsigned ID, int64_t Count) { auto &Us = instance(); - Us.Counters[ID] = Val; + Us.Counters[ID].Count = Count; } // Dump or print the current counter set into llvm::dbgs(). @@ -136,7 +132,7 @@ // Return the name and description of the counter with the given ID. std::pair getCounterInfo(unsigned ID) const { - return std::make_pair(RegisteredCounters[ID], CounterDesc.lookup(ID)); + return std::make_pair(RegisteredCounters[ID], Counters.lookup(ID).Desc); } // Iterate through the registered counters @@ -149,11 +145,18 @@ private: unsigned addCounter(const std::string &Name, const std::string &Desc) { unsigned Result = RegisteredCounters.insert(Name); - CounterDesc[Result] = Desc; + Counters[Result] = {}; + Counters[Result].Desc = Desc; return Result; } - DenseMap> Counters; - DenseMap CounterDesc; + // Struct to store counter info. + struct CounterInfo { + int64_t Count = 0; + int64_t Skip = 0; + int64_t StopAfter = -1; + std::string Desc; + }; + DenseMap Counters; CounterVector RegisteredCounters; }; Index: lib/Support/DebugCounter.cpp =================================================================== --- lib/Support/DebugCounter.cpp +++ lib/Support/DebugCounter.cpp @@ -66,7 +66,7 @@ } // Now we have counter=value. // First, process value. - long CounterVal; + int64_t CounterVal; if (CounterPair.second.getAsInteger(0, CounterVal)) { errs() << "DebugCounter Error: " << CounterPair.second << " is not a number\n"; @@ -76,26 +76,22 @@ // add it to the counter values. if (CounterPair.first.endswith("-skip")) { auto CounterName = CounterPair.first.drop_back(5); - unsigned CounterID = RegisteredCounters.idFor(CounterName); + unsigned CounterID = getCounterId(CounterName); if (!CounterID) { errs() << "DebugCounter Error: " << CounterName << " is not a registered counter\n"; return; } - - auto Res = Counters.insert({CounterID, {0, -1}}); - Res.first->second.first = CounterVal; + Counters[CounterID].Skip = CounterVal; } else if (CounterPair.first.endswith("-count")) { auto CounterName = CounterPair.first.drop_back(6); - unsigned CounterID = RegisteredCounters.idFor(CounterName); + unsigned CounterID = getCounterId(CounterName); if (!CounterID) { errs() << "DebugCounter Error: " << CounterName << " is not a registered counter\n"; return; } - - auto Res = Counters.insert({CounterID, {0, -1}}); - Res.first->second.second = CounterVal; + Counters[CounterID].StopAfter = CounterVal; } else { errs() << "DebugCounter Error: " << CounterPair.first << " does not end with -skip or -count\n"; @@ -106,7 +102,8 @@ OS << "Counters and values:\n"; for (const auto &KV : Counters) OS << left_justify(RegisteredCounters[KV.first], 32) << ": {" - << KV.second.first << "," << KV.second.second << "}\n"; + << KV.second.Count << "," << KV.second.Skip << "," + << KV.second.StopAfter << "}\n"; } LLVM_DUMP_METHOD void DebugCounter::dump() const { Index: lib/Transforms/Scalar/NewGVN.cpp =================================================================== --- lib/Transforms/Scalar/NewGVN.cpp +++ lib/Transforms/Scalar/NewGVN.cpp @@ -861,7 +861,7 @@ // Debug counter info. When verifying, we have to reset the value numbering // debug counter to the same state it started in to get the same results. - std::pair StartingVNCounter; + int64_t StartingVNCounter; }; } // end anonymous namespace Index: unittests/Support/CMakeLists.txt =================================================================== --- unittests/Support/CMakeLists.txt +++ unittests/Support/CMakeLists.txt @@ -20,6 +20,7 @@ ConvertUTFTest.cpp DataExtractorTest.cpp DebugTest.cpp + DebugCounterTest.cpp DJBTest.cpp EndianStreamTest.cpp EndianTest.cpp Index: unittests/Support/DebugCounterTest.cpp =================================================================== --- /dev/null +++ unittests/Support/DebugCounterTest.cpp @@ -0,0 +1,38 @@ +//===- llvm/unittest/Support/DebugCounterTest.cpp -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/DebugCounter.h" +#include "gtest/gtest.h" + +#include +using namespace llvm; + +#ifndef NDEBUG +DEBUG_COUNTER(TestCounter, "test-counter", + "Counter used for unit test"); + +TEST(DebugCounterTest, CounterCheck) { + auto DC = &DebugCounter::instance(); + DC->push_back("test-counter-skip=1"); + DC->push_back("test-counter-count=3"); + + EXPECT_EQ(0, DebugCounter::getCounterValue(TestCounter)); + EXPECT_FALSE(DebugCounter::shouldExecute(TestCounter)); + + EXPECT_EQ(1, DebugCounter::getCounterValue(TestCounter)); + EXPECT_TRUE(DebugCounter::shouldExecute(TestCounter)); + + DebugCounter::setCounterValue(TestCounter, 3); + EXPECT_TRUE(DebugCounter::shouldExecute(TestCounter)); + EXPECT_FALSE(DebugCounter::shouldExecute(TestCounter)); + + DebugCounter::setCounterValue(TestCounter, 100); + EXPECT_FALSE(DebugCounter::shouldExecute(TestCounter)); +} +#endif