Skip to content

Commit

Permalink
[DebugCounters] Keep track of total counts
Browse files Browse the repository at this point in the history
This patch makes debug counters keep track of the total number of times
we've called `shouldExecute` for each counter, so it's easier to build
automated tooling on top of these.

A patch to print these counts is coming soon.

Patch by Zhizhou Yang!

Differential Revision: https://reviews.llvm.org/D49560

llvm-svn: 337748
  • Loading branch information
gburgessiv committed Jul 23, 2018
1 parent d9c2547 commit b00fb46
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 35 deletions.
52 changes: 28 additions & 24 deletions llvm/include/llvm/Support/DebugCounter.h
Expand Up @@ -77,23 +77,19 @@ class DebugCounter {
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;
Expand All @@ -104,21 +100,21 @@ class DebugCounter {
// the command line). This will return true even if those values are
// currently in a state where the counter will always execute.
static bool isCounterSet(unsigned ID) {
return instance().Counters.count(ID);
return instance().Counters[ID].IsSet;
}

// Return the skip and count for a counter. This only works for set counters.
static std::pair<int, int> 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<int, int> &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().
Expand All @@ -136,7 +132,7 @@ class DebugCounter {

// Return the name and description of the counter with the given ID.
std::pair<std::string, std::string> 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
Expand All @@ -149,11 +145,19 @@ class DebugCounter {
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<unsigned, std::pair<long, long>> Counters;
DenseMap<unsigned, std::string> CounterDesc;
// Struct to store counter info.
struct CounterInfo {
int64_t Count = 0;
int64_t Skip = 0;
int64_t StopAfter = -1;
bool IsSet = false;
std::string Desc;
};
DenseMap<unsigned, CounterInfo> Counters;
CounterVector RegisteredCounters;
};

Expand Down
19 changes: 9 additions & 10 deletions llvm/lib/Support/DebugCounter.cpp
Expand Up @@ -66,7 +66,7 @@ void DebugCounter::push_back(const std::string &Val) {
}
// 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";
Expand All @@ -76,26 +76,24 @@ void DebugCounter::push_back(const std::string &Val) {
// 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;
Counters[CounterID].IsSet = true;
} 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;
Counters[CounterID].IsSet = true;
} else {
errs() << "DebugCounter Error: " << CounterPair.first
<< " does not end with -skip or -count\n";
Expand All @@ -106,7 +104,8 @@ void DebugCounter::print(raw_ostream &OS) const {
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 {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/NewGVN.cpp
Expand Up @@ -861,7 +861,7 @@ class NewGVN {

// 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<int, int> StartingVNCounter;
int64_t StartingVNCounter;
};

} // end anonymous namespace
Expand Down
1 change: 1 addition & 0 deletions llvm/unittests/Support/CMakeLists.txt
Expand Up @@ -20,6 +20,7 @@ add_llvm_unittest(SupportTests
ConvertUTFTest.cpp
DataExtractorTest.cpp
DebugTest.cpp
DebugCounterTest.cpp
DJBTest.cpp
EndianStreamTest.cpp
EndianTest.cpp
Expand Down
42 changes: 42 additions & 0 deletions llvm/unittests/Support/DebugCounterTest.cpp
@@ -0,0 +1,42 @@
//===- 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 <string>
using namespace llvm;

#ifndef NDEBUG
DEBUG_COUNTER(TestCounter, "test-counter",
"Counter used for unit test");

TEST(DebugCounterTest, CounterCheck) {
EXPECT_FALSE(DebugCounter::isCounterSet(TestCounter));

auto DC = &DebugCounter::instance();
DC->push_back("test-counter-skip=1");
DC->push_back("test-counter-count=3");

EXPECT_TRUE(DebugCounter::isCounterSet(TestCounter));

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

0 comments on commit b00fb46

Please sign in to comment.