Skip to content

Commit ee2d608

Browse files
committed
[DebugCounter] Add support for non-continous ranges.
+ Script for bisecting though a build
1 parent adc11b3 commit ee2d608

File tree

10 files changed

+514
-83
lines changed

10 files changed

+514
-83
lines changed

llvm/docs/ProgrammersManual.rst

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,16 +1362,14 @@ Whatever code you want that control, use ``DebugCounter::shouldExecute`` to cont
13621362
if (DebugCounter::shouldExecute(DeleteAnInstruction))
13631363
I->eraseFromParent();
13641364

1365-
That's all you have to do. Now, using opt, you can control when this code triggers using
1366-
the '``--debug-counter``' option. There are two counters provided, ``skip`` and ``count``.
1367-
``skip`` is the number of times to skip execution of the codepath. ``count`` is the number
1368-
of times, once we are done skipping, to execute the codepath.
1365+
That's all you have to do. Now, using opt, you can control when this code triggers using
1366+
the '``--debug-counter``' Options.To specify when to execute the codepath.
13691367

13701368
.. code-block:: none
13711369
1372-
$ opt --debug-counter=passname-delete-instruction-skip=1,passname-delete-instruction-count=2 -passname
1370+
$ opt --debug-counter=passname-delete-instruction=2-3 -passname
13731371
1374-
This will skip the above code the first time we hit it, then execute it twice, then skip the rest of the executions.
1372+
This will skip the above code the first two times we hit it, then execute it 2 times, then skip the rest of the executions.
13751373

13761374
So if executed on the following code:
13771375

@@ -1384,9 +1382,28 @@ So if executed on the following code:
13841382
13851383
It would delete number ``%2`` and ``%3``.
13861384

1387-
A utility is provided in `utils/bisect-skip-count` to binary search
1388-
skip and count arguments. It can be used to automatically minimize the
1389-
skip and count for a debug-counter variable.
1385+
A utility is provided in `llvm/tools/delta-driver/delta-driver.cpp` to drive the automated delta debugging.
1386+
How to use delta-driver:
1387+
First, Figure out the number of calls to the debug counter you want to minimize.
1388+
To do so, run the compilation command causing issue with `-print-debug-counter` adding a `-mllvm` if needed.
1389+
Than find the line with the counter of interest. it should look like:
1390+
.. code-block:: none
1391+
1392+
my-counter : {5678,empty}
1393+
1394+
The number of calls to `my-counter` is 5678
1395+
1396+
Than Find the minimum set of chunks that reproduce an issue, with `delta-driver`.
1397+
Build a reproducer script like:
1398+
.. code-block:: bash
1399+
1400+
#! /bin/bash
1401+
opt -debug-counter=my-counter=$1
1402+
# ... Test result of the command. Failure of the script is considered interesting
1403+
1404+
Than run `delta-driver my-script.sh 0-5678 2>&1 | tee dump_bisect`
1405+
This command may take some time.
1406+
but when it is done, it will print the result like: `Minimal Chunks = 0:1:5:11-12:33-34`
13901407

13911408
.. _ViewGraph:
13921409

llvm/include/llvm/IR/PassManager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
6464

6565
namespace llvm {
6666

67+
// Used for debug counter of adding a pass to the pipeline
68+
bool shouldAddNewPMPass();
69+
6770
// Forward declare the analysis manager template.
6871
template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
6972

@@ -247,6 +250,8 @@ class PassManager : public PassInfoMixin<
247250

248251
// FIXME: Revert to enable_if style when gcc >= 11.1
249252
template <typename PassT> LLVM_ATTRIBUTE_MINSIZE void addPass(PassT &&Pass) {
253+
if (!shouldAddNewPMPass())
254+
return;
250255
using PassModelT =
251256
detail::PassModel<IRUnitT, PassT, AnalysisManagerT, ExtraArgTs...>;
252257
if constexpr (!std::is_same_v<PassT, PassManager>) {

llvm/include/llvm/Support/DebugCounter.h

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#ifndef LLVM_SUPPORT_DEBUGCOUNTER_H
4444
#define LLVM_SUPPORT_DEBUGCOUNTER_H
4545

46+
#include "llvm/ADT/ArrayRef.h"
4647
#include "llvm/ADT/DenseMap.h"
4748
#include "llvm/ADT/StringRef.h"
4849
#include "llvm/ADT/UniqueVector.h"
@@ -53,6 +54,18 @@ namespace llvm {
5354

5455
class raw_ostream;
5556

57+
struct Chunk {
58+
int64_t Begin;
59+
int64_t End;
60+
void print(llvm::raw_ostream &OS);
61+
bool contains(int64_t Idx) { return Idx >= Begin && Idx <= End; }
62+
};
63+
64+
void printChunks(raw_ostream &OS, ArrayRef<Chunk>);
65+
66+
/// Return true on parsing error and print the error message on the llvm::errs()
67+
bool parseChunks(StringRef Str, SmallVector<Chunk> &Res);
68+
5669
class DebugCounter {
5770
public:
5871
/// Returns a reference to the singleton instance.
@@ -77,18 +90,28 @@ class DebugCounter {
7790
auto Result = Us.Counters.find(CounterName);
7891
if (Result != Us.Counters.end()) {
7992
auto &CounterInfo = Result->second;
80-
++CounterInfo.Count;
93+
int64_t CurrCount = CounterInfo.Count++;
94+
uint64_t CurrIdx = CounterInfo.CurrChunkIdx;
8195

82-
// We only execute while the Skip is not smaller than Count,
83-
// and the StopAfter + Skip is larger than Count.
84-
// Negative counters always execute.
85-
if (CounterInfo.Skip < 0)
96+
if (CounterInfo.Chunks.empty())
8697
return true;
87-
if (CounterInfo.Skip >= CounterInfo.Count)
98+
if (CurrIdx >= CounterInfo.Chunks.size())
8899
return false;
89-
if (CounterInfo.StopAfter < 0)
90-
return true;
91-
return CounterInfo.StopAfter + CounterInfo.Skip >= CounterInfo.Count;
100+
101+
bool Res = CounterInfo.Chunks[CurrIdx].contains(CurrCount);
102+
if (Us.BreakOnLast && CurrIdx == (CounterInfo.Chunks.size() - 1) &&
103+
CurrCount == CounterInfo.Chunks[CurrIdx].End) {
104+
LLVM_BUILTIN_DEBUGTRAP;
105+
}
106+
if (CurrCount > CounterInfo.Chunks[CurrIdx].End) {
107+
CounterInfo.CurrChunkIdx++;
108+
109+
/// Handle consecutive blocks.
110+
if (CounterInfo.CurrChunkIdx < CounterInfo.Chunks.size() &&
111+
CurrCount == CounterInfo.Chunks[CounterInfo.CurrChunkIdx].Begin)
112+
return true;
113+
}
114+
return Res;
92115
}
93116
// Didn't find the counter, should we warn?
94117
return true;
@@ -152,11 +175,11 @@ class DebugCounter {
152175
#ifdef NDEBUG
153176
return false;
154177
#else
155-
return instance().Enabled;
178+
return instance().Enabled || instance().ShouldPrintCounter;
156179
#endif
157180
}
158181

159-
private:
182+
protected:
160183
unsigned addCounter(const std::string &Name, const std::string &Desc) {
161184
unsigned Result = RegisteredCounters.insert(Name);
162185
Counters[Result] = {};
@@ -166,17 +189,22 @@ class DebugCounter {
166189
// Struct to store counter info.
167190
struct CounterInfo {
168191
int64_t Count = 0;
169-
int64_t Skip = 0;
170-
int64_t StopAfter = -1;
192+
uint64_t CurrChunkIdx = 0;
171193
bool IsSet = false;
172194
std::string Desc;
195+
SmallVector<Chunk> Chunks;
173196
};
197+
174198
DenseMap<unsigned, CounterInfo> Counters;
175199
CounterVector RegisteredCounters;
176200

177201
// Whether we should do DebugCounting at all. DebugCounters aren't
178202
// thread-safe, so this should always be false in multithreaded scenarios.
179203
bool Enabled = false;
204+
205+
bool ShouldPrintCounter = false;
206+
207+
bool BreakOnLast = false;
180208
};
181209

182210
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC) \

llvm/lib/IR/PassManager.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,20 @@
88

99
#include "llvm/IR/PassManager.h"
1010
#include "llvm/IR/PassManagerImpl.h"
11+
#include "llvm/Support/DebugCounter.h"
1112
#include <optional>
1213

1314
using namespace llvm;
1415

1516
namespace llvm {
17+
18+
DEBUG_COUNTER(AddNewPMPassCounter, "new-pm-pass-counter",
19+
"Control what passes get run");
20+
21+
bool shouldAddNewPMPass() {
22+
return DebugCounter::shouldExecute(AddNewPMPassCounter);
23+
}
24+
1625
// Explicit template instantiations and specialization defininitions for core
1726
// template typedefs.
1827
template class AllAnalysesOn<Module>;

0 commit comments

Comments
 (0)