I’m wondering if there’s appetite for a flag that tells LLVM to print a brief version of debug info metadata nodes inline when printing IR.
The two cases that stand out to me are:
a) printing DILocation
line, col, file, and inlinedAt fields inline after !dbg
attachments,
b) printing DILocalVariable
variable names inline in debug intrinsics.
This would make it easier to understand debug info in IR test cases. It would be especially useful for looking at -print-after-all
traces because the metadata number for a given node may change after an optimisation pass, so following specific debug intrinsics can become quite a laborious task.
I am specifically proposing that this is a write-only option, printing illegal IR. Though I suppose we could consider using comments if it’s not too difficult to accommodate option (b) above?
Here’s a source code example and output sketch (note: inlining f0
into f1
and f1
into f2
).
__attribute__((always_inline))
static void f0() { int a = 0; }
__attribute__((always_inline))
static void f1() {
int a = 1;
f0();
}
void f2() {
int a = 2;
f1();
}
Instead of what we have now:
clang -O0 -g -emit-llvm -S test.cpp -o -
...
define dso_local void @_Z2f2v() #0 !dbg !8 {
entry:
%a.i1 = alloca i32, align 4
%a.i = alloca i32, align 4
%a = alloca i32, align 4
call void @llvm.dbg.declare(metadata ptr %a, metadata !12, metadata !DIExpression()), !dbg !14
store i32 2, ptr %a, align 4, !dbg !14
call void @llvm.dbg.declare(metadata ptr %a.i, metadata !15, metadata !DIExpression()), !dbg !17
store i32 1, ptr %a.i, align 4, !dbg !17
call void @llvm.dbg.declare(metadata ptr %a.i1, metadata !19, metadata !DIExpression()), !dbg !21
store i32 0, ptr %a.i1, align 4, !dbg !21
ret void, !dbg !23
}
...
We’d get something like this:
clang -O0 -g -emit-llvm -S test.cpp -o - -mllvm -expand-dbg-metadata
...
define dso_local void @_Z2f2v() #0 !dbg !8 {
entry:
%a.i1 = alloca i32, align 4
%a.i = alloca i32, align 4
%a = alloca i32, align 4
call void @llvm.dbg.declare(metadata ptr %a, metadata !12 ('a'), metadata !DIExpression()), !dbg !14 (11: 7, test.cpp)
store i32 2, ptr %a, align 4, !dbg !14 (11: 7, test.cpp)
call void @llvm.dbg.declare(metadata ptr %a.i, metadata !15 ('a'), metadata !DIExpression()), !dbg !17 (6: 7, test.cpp) -> (12: 3, test.cpp)
store i32 1, ptr %a.i, align 4, !dbg !17 (6: 7, test.cpp) -> (12: 3, test.cpp)
call void @llvm.dbg.declare(metadata ptr %a.i1, metadata !19 ('a'), metadata !DIExpression()), !dbg !21 (2: 24, test.cpp) -> (7: 3, test.cpp) -> (12: 3, test.cpp)
store i32 0, ptr %a.i1, align 4, !dbg !21 (2: 24, test.cpp) -> (7: 3, test.cpp) -> (12: 3, test.cpp)
ret void, !dbg !23 (13: 1, test.cpp)
}
...
I’ve had a patch hanging around locally for a long time that essentially does, and I find it really useful.
Would anyone else find this useful? And, does anyone have any strong opinions on this proposed output format (including whether printing illegal IR is OK, even behind a flag).
Thanks,
Orlando