Skip to content

Commit c94f7bb

Browse files
committed
Default DEBUG_TYPE to the current filename for logging
This makes it optional to define a debug type and uses the current FileName instead. This both reduced the size of the prefix printed by LDBG() and makes it possible to pass a filename to `--debug-only` to filter on.
1 parent 3e254ed commit c94f7bb

File tree

4 files changed

+128
-61
lines changed

4 files changed

+128
-61
lines changed

llvm/docs/ProgrammersManual.rst

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,8 @@ It also supports a `level` argument to control the verbosity of the output.
11691169

11701170
LDBG(2) << "I am here!";
11711171

1172-
A ``DEBUG_TYPE`` macro should be defined in the file before using ``LDBG()``.
1172+
A ``DEBUG_TYPE`` macro may optionally be defined in the file before using
1173+
``LDBG()``, otherwise the file name is used as the debug type.
11731174
The file name and line number are automatically added to the output, as well as
11741175
a terminating newline.
11751176

@@ -1180,7 +1181,7 @@ The debug output can be enabled by passing the ``-debug`` command line argument.
11801181
$ opt < a.bc > /dev/null -mypass
11811182
<no output>
11821183
$ opt < a.bc > /dev/null -mypass -debug
1183-
[my-pass:2] MyPass.cpp:123 I am here!
1184+
[my-pass MyPass.cpp:123 2] I am here!
11841185
11851186
While `LDBG()` is useful to add debug output to your code, there are cases
11861187
where you may need to guard a block of code with a debug check. The
@@ -1222,39 +1223,39 @@ Fine grained debug info with ``DEBUG_TYPE`` and the ``-debug-only`` option
12221223
Sometimes you may find yourself in a situation where enabling ``-debug`` just
12231224
turns on **too much** information (such as when working on the code generator).
12241225
If you want to enable debug information with more fine-grained control, you
1225-
should define the ``DEBUG_TYPE`` macro and use the ``-debug-only`` option as
1226-
follows:
1226+
can control the debug type and level with associate with each logging statement
1227+
as follows:
12271228

12281229
.. code-block:: c++
12291230

1230-
#define DEBUG_TYPE "foo"
1231+
#define DEBUG_TYPE "foo" // Optional: the file name is used instead if not defined
12311232
LDBG(2) << "Hello,";
12321233
// DEBUG_TYPE can be overridden locally, here with "bar"
12331234
LDBG("bar", 3) << "'bar' debug type";
12341235

12351236

1236-
A more fine-grained control can be achieved by passing the ``-debug-only``
1237-
command line argument:
1237+
A more fine-grained control of the output can be achieved by passing the
1238+
``-debug-only`` command line argument:
12381239

12391240
.. code-block:: none
12401241
12411242
$ opt < a.bc > /dev/null -mypass -debug-only=foo
1242-
[foo:2] MyPass.cpp:123 Hello,
1243+
[foo MyPass.cpp:123 2] Hello,
12431244
$ opt < a.bc > /dev/null -mypass -debug-only=foo,bar
1244-
[foo:2] MyPass.cpp:123 Hello,
1245-
[bar:3] MyPass.cpp:124 World!
1245+
[foo MyPass.cpp:123 2] Hello,
1246+
[bar MyPass.cpp:124 3] World!
12461247
$ opt < a.bc > /dev/null -mypass -debug-only=bar
1247-
[bar:3] MyPass.cpp:124 World!
1248+
[bar MyPass.cpp:124 3] World!
12481249
12491250
The debug-only argument is a comma separated list of debug types and levels.
12501251
The level is an optional integer setting the maximum debug level to enable:
12511252

12521253
.. code-block:: none
12531254
12541255
$ opt < a.bc > /dev/null -mypass -debug-only=foo:2,bar:2
1255-
[foo:2] MyPass.cpp:123 Hello,
1256+
[foo MyPass.cpp:123 2] Hello,
12561257
$ opt < a.bc > /dev/null -mypass -debug-only=foo:1,bar:3
1257-
[bar:3] MyPass.cpp:124 World!
1258+
[bar MyPass.cpp:124 3] World!
12581259
12591260
Instead of opting in specific debug types, the ``-debug-only`` option also
12601261
works to filter out debug output for specific debug types, by omitting the
@@ -1263,7 +1264,7 @@ level (or setting it to 0):
12631264
.. code-block:: none
12641265
12651266
$ opt < a.bc > /dev/null -mypass -debug-only=foo:
1266-
[bar:3] MyPass.cpp:124 World!
1267+
[bar MyPass.cpp:124 3] World!
12671268
$ opt < a.bc > /dev/null -mypass -debug-only=bar:0,foo:
12681269
12691270

llvm/include/llvm/Support/DebugLog.h

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -196,30 +196,18 @@ constexpr ::llvm::StringRef strip_quotes(const char *Str) {
196196
return S;
197197
}
198198

199-
/// Fail compilation if DEBUG_TYPE is not defined.
200-
/// This is a workaround for GCC <=12 and clang <=16 which do not support
201-
/// static_assert in templated constexpr functions.
202-
#if (defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 12) || \
203-
(defined(__clang__) && __clang_major__ <= 16)
204-
#define MISSING_DEBUG_TYPE() \
205-
extern void missing_DEBUG_TYPE(void); \
206-
missing_DEBUG_TYPE();
207-
#else
208-
#define MISSING_DEBUG_TYPE() static_assert(false, "DEBUG_TYPE is not defined");
209-
#endif
210-
211199
/// Helper to provide the default level (=1) or type (=DEBUG_TYPE). This is used
212200
/// when a single argument is passed to LDBG() (or LDBG_OS()), if it is an
213-
/// integer we return DEBUG_TYPE and if it is a string we return 1. This fails
214-
/// with a static_assert if we pass an integer and DEBUG_TYPE is not defined.
201+
/// integer we return DEBUG_TYPE and if it is a string we return 1.
202+
/// When DEBUG_TYPE is not defined, we return the current file name instead.
215203
#define LDBG_GET_DEFAULT_TYPE_OR_LEVEL(LEVEL_OR_TYPE) \
216204
[](auto LevelOrType) { \
217205
if constexpr (std::is_integral_v<decltype(LevelOrType)>) { \
218206
constexpr const char *DebugType = LDBG_GET_DEBUG_TYPE_STR(); \
219207
if constexpr (DebugType[0] == '"') { \
220208
return ::llvm::impl::strip_quotes(DebugType); \
221209
} else { \
222-
MISSING_DEBUG_TYPE(); \
210+
return __LLVM_FILE_NAME__; \
223211
} \
224212
} else { \
225213
return 1; \
@@ -331,9 +319,10 @@ static LLVM_ATTRIBUTE_UNUSED std::string
331319
computePrefix(StringRef DebugType, const char *File, int Line, int Level) {
332320
std::string Prefix;
333321
raw_string_ostream OsPrefix(Prefix);
334-
if (!DebugType.empty())
335-
OsPrefix << "[" << DebugType << ":" << Level << "] ";
336-
OsPrefix << File << ":" << Line << " ";
322+
OsPrefix << "[";
323+
if (!DebugType.empty() && DebugType != File)
324+
OsPrefix << DebugType << " ";
325+
OsPrefix << File << ":" << Line << " " << Level << "] ";
337326
return OsPrefix.str();
338327
}
339328
/// Overload allowing to swap the order of the DebugType and Level arguments.

llvm/unittests/Support/DebugLogTest.cpp

Lines changed: 97 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ TEST(DebugLogTest, Basic) {
2828
std::string str;
2929
raw_string_ostream os(str);
3030
LDGB_STREAM_LEVEL_AND_TYPE(os, "", 0) << "NoType";
31-
EXPECT_FALSE(StringRef(os.str()).starts_with('['));
31+
EXPECT_TRUE(StringRef(os.str()).starts_with('['));
3232
EXPECT_TRUE(StringRef(os.str()).ends_with("NoType\n"));
3333
}
3434

@@ -77,8 +77,8 @@ TEST(DebugLogTest, BasicWithLevel) {
7777
for (int level : llvm::seq<int>(0, 4))
7878
LDBG_STREAM_LEVEL_TYPE_FILE_AND_LINE(os, level, type, type, level)
7979
<< level;
80-
EXPECT_EQ(os.str(), "[A:0] A:0 0\n[A:1] A:1 1\n[A:2] A:2 2\n[A:3] A:3 "
81-
"3\n[B:0] B:0 0\n[B:1] B:1 1\n[C:0] C:0 0\n");
80+
EXPECT_EQ(os.str(), "[A:0 0] 0\n[A:1 1] 1\n[A:2 2] 2\n[A:3 3] 3\n[B:0 0] "
81+
"0\n[B:1 1] 1\n[C:0 0] 0\n");
8282
}
8383

8484
TEST(DebugLogTest, NegativeLevel) {
@@ -92,9 +92,10 @@ TEST(DebugLogTest, NegativeLevel) {
9292
raw_string_ostream os(str);
9393
for (auto type : {"A", "B"})
9494
for (int level : llvm::seq<int>(0, 2))
95-
LDBG_STREAM_LEVEL_TYPE_FILE_AND_LINE(os, level, type, type, level)
95+
LDBG_STREAM_LEVEL_TYPE_FILE_AND_LINE(
96+
os, level, type, (std::string(type) + ".cpp").c_str(), level)
9697
<< level;
97-
EXPECT_EQ(os.str(), "[A:0] A:0 0\n[B:0] B:0 0\n[B:1] B:1 1\n");
98+
EXPECT_EQ(os.str(), "[A A.cpp:0 0] 0\n[B B.cpp:0 0] 0\n[B B.cpp:1 1] 1\n");
9899
}
99100

100101
TEST(DebugLogTest, StreamPrefix) {
@@ -141,35 +142,71 @@ TEST(DebugLogTest, LDBG_MACROS) {
141142
#define LDBG_STREAM DebugOs
142143
#define DEBUG_TYPE "A"
143144
LDBG() << "Hello, world!";
144-
ExpectedOs << "[A:1] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
145-
<< " Hello, world!\n";
145+
ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
146+
<< " 1] Hello, world!\n";
146147
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
147148
Str.clear();
148149
StrExpected.clear();
149150

150151
// Test with a level, no type.
151152
LDBG(2) << "Hello, world!";
152-
ExpectedOs << "[A:2] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
153-
<< " Hello, world!\n";
153+
ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
154+
<< " 2] Hello, world!\n";
154155
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
155156
Str.clear();
156157
StrExpected.clear();
157158

158-
// Now the type will be explicit, check we don't use DEBUG_TYPE.
159+
// Now check when we don't use DEBUG_TYPE, the file name is implicitly used
160+
// instead.
159161
#undef DEBUG_TYPE
160162

163+
// Repeat the tests above, they won't match since the debug types defined
164+
// above don't match the file name.
165+
LDBG() << "Hello, world!";
166+
EXPECT_EQ(DebugOs.str(), "");
167+
Str.clear();
168+
StrExpected.clear();
169+
170+
// Test with a level, no type.
171+
LDBG(2) << "Hello, world!";
172+
EXPECT_EQ(DebugOs.str(), "");
173+
Str.clear();
174+
StrExpected.clear();
175+
176+
// Now enable the debug types that match the file name.
177+
auto fileNameAndLevel = std::string(__LLVM_FILE_NAME__) + ":3";
178+
static const char *DT2[] = {fileNameAndLevel.c_str(), "B:2"};
179+
setCurrentDebugTypes(DT2, sizeof(DT2) / sizeof(DT2[0]));
180+
181+
// Repeat the tests above, they should match now.
182+
183+
LDBG() << "Hello, world!";
184+
ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
185+
<< " 1] Hello, world!\n";
186+
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
187+
Str.clear();
188+
StrExpected.clear();
189+
190+
// Test with a level, no type.
191+
LDBG(2) << "Hello, world!";
192+
ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
193+
<< " 2] Hello, world!\n";
194+
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
195+
Str.clear();
196+
StrExpected.clear();
197+
161198
// Test with a type
162199
LDBG("B") << "Hello, world!";
163-
ExpectedOs << "[B:1] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
164-
<< " Hello, world!\n";
200+
ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
201+
<< " 1] Hello, world!\n";
165202
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
166203
Str.clear();
167204
StrExpected.clear();
168205

169206
// Test with a type and a level
170207
LDBG("B", 2) << "Hello, world!";
171-
ExpectedOs << "[B:2] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
172-
<< " Hello, world!\n";
208+
ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
209+
<< " 2] Hello, world!\n";
173210
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
174211
Str.clear();
175212
StrExpected.clear();
@@ -181,6 +218,8 @@ TEST(DebugLogTest, LDBG_MACROS) {
181218
// Test with a level not enabled.
182219
LDBG("B", 3) << "Hello, world!";
183220
EXPECT_EQ(DebugOs.str(), "");
221+
LDBG(__LLVM_FILE_NAME__, 4) << "Hello, world!";
222+
EXPECT_EQ(DebugOs.str(), "");
184223
}
185224

186225
TEST(DebugLogTest, LDBG_OS_MACROS) {
@@ -195,35 +234,70 @@ TEST(DebugLogTest, LDBG_OS_MACROS) {
195234
#define LDBG_STREAM DebugOs
196235
#define DEBUG_TYPE "A"
197236
LDBG_OS([](raw_ostream &Os) { Os << "Hello, world!"; });
198-
ExpectedOs << "[A:1] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
199-
<< " Hello, world!\n";
237+
ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
238+
<< " 1] Hello, world!\n";
200239
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
201240
Str.clear();
202241
StrExpected.clear();
203242

204243
// Test with a level, no type.
205244
LDBG_OS(2, [](raw_ostream &Os) { Os << "Hello, world!"; });
206-
ExpectedOs << "[A:2] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
207-
<< " Hello, world!\n";
245+
ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
246+
<< " 2] Hello, world!\n";
208247
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
209248
Str.clear();
210249
StrExpected.clear();
211250

212-
// Now the type will be explicit, check we don't use DEBUG_TYPE.
251+
// Now check when we don't use DEBUG_TYPE, the file name is implicitly used
252+
// instead.
213253
#undef DEBUG_TYPE
214254

255+
// Repeat the tests above, they won't match since the debug types defined
256+
// above don't match the file name.
257+
LDBG_OS([](raw_ostream &Os) { Os << "Hello, world!"; });
258+
EXPECT_EQ(DebugOs.str(), "");
259+
Str.clear();
260+
StrExpected.clear();
261+
262+
// Test with a level, no type.
263+
LDBG_OS(2, [](raw_ostream &Os) { Os << "Hello, world!"; });
264+
EXPECT_EQ(DebugOs.str(), "");
265+
Str.clear();
266+
StrExpected.clear();
267+
268+
// Now enable the debug types that match the file name.
269+
auto fileNameAndLevel = std::string(__LLVM_FILE_NAME__) + ":3";
270+
static const char *DT2[] = {fileNameAndLevel.c_str(), "B:2"};
271+
setCurrentDebugTypes(DT2, sizeof(DT2) / sizeof(DT2[0]));
272+
273+
// Repeat the tests above, they should match now.
274+
LDBG_OS([](raw_ostream &Os) { Os << "Hello, world!"; });
275+
ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
276+
<< " 1] Hello, world!\n";
277+
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
278+
Str.clear();
279+
StrExpected.clear();
280+
281+
// Test with a level, no type.
282+
LDBG_OS(2, [](raw_ostream &Os) { Os << "Hello, world!"; });
283+
ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
284+
<< " 2] Hello, world!\n";
285+
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
286+
Str.clear();
287+
StrExpected.clear();
288+
215289
// Test with a type.
216290
LDBG_OS("B", [](raw_ostream &Os) { Os << "Hello, world!"; });
217-
ExpectedOs << "[B:1] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
218-
<< " Hello, world!\n";
291+
ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
292+
<< " 1] Hello, world!\n";
219293
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
220294
Str.clear();
221295
StrExpected.clear();
222296

223297
// Test with a type and a level
224298
LDBG_OS("B", 2, [](raw_ostream &Os) { Os << "Hello, world!"; });
225-
ExpectedOs << "[B:2] " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
226-
<< " Hello, world!\n";
299+
ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)
300+
<< " 2] Hello, world!\n";
227301
EXPECT_EQ(DebugOs.str(), ExpectedOs.str());
228302
Str.clear();
229303
StrExpected.clear();

mlir/test/IR/test-pattern-logging-listener.mlir

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
// REQUIRES: asserts
22
// RUN: mlir-opt %s --test-walk-pattern-rewrite-driver \
3-
// RUN: --allow-unregistered-dialect --debug-only=pattern-logging-listener 2>&1 | FileCheck %s
3+
// RUN: --debug-only=pattern-logging-listener 2>&1 | FileCheck %s
44

55
// Check that when replacing an op with a new op, we get appropriate
66
// pattern-logging lines. The use of check same is to avoid the complexity of
77
// matching the anonymous namespace prefix, which can be one of {anonymous} vs
88
// {anonymous_namespace} vs `anonymous_namespace` (and maybe others?) on the
99
// various platforms.
1010

11-
// CHECK: [pattern-logging-listener:1]
11+
// Changing the reference output here need to also plan on updating the post-processing
12+
// script here: https://github.com/llvm/mlir-www/blob/main/.github%2Fworkflows%2Fmain.yml#L71-L72
13+
14+
// CHECK: [pattern-logging-listener PatternLoggingListener.cpp:10 1]
1215
// CHECK-SAME: ::ReplaceWithNewOp | notifyOperationInserted | test.new_op
13-
// CHECK: [pattern-logging-listener:1]
16+
// CHECK: [pattern-logging-listener PatternLoggingListener.cpp:31 1]
1417
// CHECK-SAME: ::ReplaceWithNewOp | notifyOperationReplaced (with values) | test.replace_with_new_op
15-
// CHECK: [pattern-logging-listener:1]
18+
// CHECK: [pattern-logging-listener PatternLoggingListener.cpp:17 1]
1619
// CHECK-SAME: ::ReplaceWithNewOp | notifyOperationModified | arith.addi
17-
// CHECK: [pattern-logging-listener:1]
20+
// CHECK: [pattern-logging-listener PatternLoggingListener.cpp:17 1]
1821
// CHECK-SAME: ::ReplaceWithNewOp | notifyOperationModified | arith.addi
19-
// CHECK: [pattern-logging-listener:1]
22+
// CHECK: [pattern-logging-listener PatternLoggingListener.cpp:38 1]
2023
// CHECK-SAME: ::ReplaceWithNewOp | notifyOperationErased | test.replace_with_new_op
2124
func.func @replace_with_new_op() -> i32 {
2225
%a = "test.replace_with_new_op"() : () -> (i32)

0 commit comments

Comments
 (0)