[DebugCounters] Keep track of total counts
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
This commit is contained in:
parent
d9c254771d
commit
b00fb46479
|
@ -77,23 +77,19 @@ public:
|
|||
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)
|
||||
if (CounterInfo.StopAfter < 0)
|
||||
return true;
|
||||
if (CounterPair.second != 0) {
|
||||
--CounterPair.second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return CounterInfo.StopAfter + CounterInfo.Skip >= CounterInfo.Count;
|
||||
}
|
||||
// Didn't find the counter, should we warn?
|
||||
return true;
|
||||
|
@ -104,21 +100,21 @@ public:
|
|||
// 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().
|
||||
|
@ -136,7 +132,7 @@ public:
|
|||
|
||||
// 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
|
||||
|
@ -149,11 +145,19 @@ public:
|
|||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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 {
|
||||
|
|
|
@ -861,7 +861,7 @@ private:
|
|||
|
||||
// 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
|
||||
|
|
|
@ -20,6 +20,7 @@ add_llvm_unittest(SupportTests
|
|||
ConvertUTFTest.cpp
|
||||
DataExtractorTest.cpp
|
||||
DebugTest.cpp
|
||||
DebugCounterTest.cpp
|
||||
DJBTest.cpp
|
||||
EndianStreamTest.cpp
|
||||
EndianTest.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
|
Loading…
Reference in New Issue