Skip to content

Commit 1e6fe67

Browse files
committed
[DebugInfo] Print empty MDTuples wrapped in MetadataAsValue inline
This improves the readability of debugging intrinsics. Instead of: call void @llvm.dbg.value(metadata !2, ...) !2 = !{} We will see: call void @llvm.dbg.value(metadata !{}, ...) !2 = !{} Note that we still get a numbered metadata entry for the node even if it's not used elsewhere. This is to avoid adding more context to the print functions. This is already legal IR - LLVM can parse and understand it - so there is no need to update the parser. The next patches in this stack will make such empty metadata operands more common and semantically important. Related to https://discourse.llvm.org/t/auto-undef-debug-uses-of-a-deleted-value Reviewed By: StephenTozer Differential Revision: https://reviews.llvm.org/D140900
1 parent 4b1532a commit 1e6fe67

File tree

6 files changed

+69
-18
lines changed

6 files changed

+69
-18
lines changed

llvm/lib/IR/AsmWriter.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
13281328

13291329
static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
13301330
AsmWriterContext &WriterCtx,
1331-
bool FromValue = false);
1331+
bool FromValue = false,
1332+
bool AsOperand = false);
13321333

13331334
static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
13341335
if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U))
@@ -2447,7 +2448,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
24472448

24482449
if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
24492450
WriteAsOperandInternal(Out, MD->getMetadata(), WriterCtx,
2450-
/* FromValue */ true);
2451+
/* FromValue */ true, /* AsOperand */ true);
24512452
return;
24522453
}
24532454

@@ -2492,8 +2493,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
24922493
}
24932494

24942495
static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
2495-
AsmWriterContext &WriterCtx,
2496-
bool FromValue) {
2496+
AsmWriterContext &WriterCtx, bool FromValue,
2497+
bool AsOperand) {
24972498
// Write DIExpressions and DIArgLists inline when used as a value. Improves
24982499
// readability of debug info intrinsics.
24992500
if (const DIExpression *Expr = dyn_cast<DIExpression>(MD)) {
@@ -2506,6 +2507,12 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
25062507
}
25072508

25082509
if (const MDNode *N = dyn_cast<MDNode>(MD)) {
2510+
// Write empty metadata tuples wrapped in MetadataAsValue inline.
2511+
if (isa<MDTuple>(N) && !N->getNumOperands() && AsOperand) {
2512+
WriteMDNodeBodyInternal(Out, N, WriterCtx);
2513+
return;
2514+
}
2515+
25092516
std::unique_ptr<SlotTracker> MachineStorage;
25102517
SaveAndRestore SARMachine(WriterCtx.Machine);
25112518
if (!WriterCtx.Machine) {
@@ -4874,7 +4881,8 @@ static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
48744881
WriterCtx =
48754882
std::make_unique<AsmWriterContext>(&TypePrinter, MST.getMachine(), M);
48764883

4877-
WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true);
4884+
WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true,
4885+
OnlyAsOperand);
48784886

48794887
auto *N = dyn_cast<MDNode>(&MD);
48804888
if (OnlyAsOperand || !N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; RUN: opt -passes=verify %s -o - | opt -S -o - | FileCheck %s
2+
3+
;; Check that an empty metadata node is printed inline when wrapped in
4+
;; MetadataAsValue.
5+
;; We still get a numbered metadata entry for the node even though it's not
6+
;; used elsewhere. This is a purely cosmetic result of reducing the complexity
7+
;; of the printing functions; it's not a requirement so it is okay to update
8+
;; this part of the test if that changes in the future.
9+
10+
; CHECK: call void @llvm.dbg.declare(metadata !{},
11+
; CHECK: ![[#]] = !{}
12+
13+
define dso_local void @fun() local_unnamed_addr #0 !dbg !9 {
14+
entry:
15+
call void @llvm.dbg.declare(metadata !{}, metadata !13, metadata !DIExpression()), !dbg !15
16+
ret void, !dbg !16
17+
}
18+
19+
declare void @llvm.dbg.declare(metadata, metadata, metadata)
20+
21+
!llvm.dbg.cu = !{!0}
22+
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
23+
!llvm.ident = !{!8}
24+
25+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 16.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
26+
!1 = !DIFile(filename: "test.c", directory: "/")
27+
!2 = !{i32 7, !"Dwarf Version", i32 5}
28+
!3 = !{i32 2, !"Debug Info Version", i32 3}
29+
!4 = !{i32 1, !"wchar_size", i32 4}
30+
!5 = !{i32 8, !"PIC Level", i32 2}
31+
!6 = !{i32 7, !"PIE Level", i32 2}
32+
!7 = !{i32 7, !"uwtable", i32 2}
33+
!8 = !{!"clang version 16.0.0"}
34+
!9 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
35+
!10 = !DISubroutineType(types: !11)
36+
!11 = !{null}
37+
!12 = !{!13}
38+
!13 = !DILocalVariable(name: "a", scope: !9, file: !1, line: 1, type: !14)
39+
!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
40+
!15 = !DILocation(line: 1, column: 18, scope: !9)
41+
!16 = !DILocation(line: 1, column: 21, scope: !9)
42+

llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ define i32 @main(i32 %argc, ptr %argv) norecurse !dbg !18 {
1111
; CHECK: alloca ptr
1212
; Make sure the metadata is sane. Currently, we just drop the metadata,
1313
; so it points to nothing.
14-
; CHECK: call void @llvm.dbg.value(metadata !2,
15-
; CHECK: !2 = !{}
14+
; CHECK: call void @llvm.dbg.value(metadata !{},
15+
1616
entry:
1717
call void @llvm.dbg.value(metadata i32 %argc, metadata !22, metadata !23), !dbg !24
1818
call void @llvm.dbg.value(metadata ptr %argv, metadata !25, metadata !23), !dbg !26

llvm/test/Transforms/GlobalOpt/metadata.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ define void @foo(i32 %x) {
1818
; null, the ValueAsMetadata instance gets replaced by metadata !{}, or
1919
; MDNode::get({}).
2020
call void @llvm.foo(metadata ptr @G, metadata i32 %x)
21-
; CHECK: call void @llvm.foo(metadata ![[EMPTY:[0-9]+]], metadata i32 %x)
21+
; CHECK: call void @llvm.foo(metadata !{}, metadata i32 %x)
2222
ret void
2323
}
2424

@@ -29,4 +29,3 @@ declare void @llvm.foo(metadata, metadata) nounwind readnone
2929

3030
!0 = !{ptr @G}
3131
; CHECK-DAG: ![[NULL]] = distinct !{null}
32-
; CHECK-DAG: ![[EMPTY]] = !{}

llvm/test/Transforms/LoopIdiom/debug-line.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ define void @foo(ptr nocapture %a) nounwind ssp !dbg !0 {
1818
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVAR_NEXT]], 1000
1919
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]], !dbg [[DBG15]]
2020
; CHECK: for.end:
21-
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata [[META3:![0-9]+]], metadata [[META11]], metadata !DIExpression()), !dbg [[DBG17:![0-9]+]]
21+
; CHECK-NEXT: tail call void @llvm.dbg.value(metadata !{}, metadata [[META11]], metadata !DIExpression()), !dbg [[DBG17:![0-9]+]]
2222
; CHECK-NEXT: ret void, !dbg [[DBG18:![0-9]+]]
2323
;
2424
entry:

llvm/unittests/IR/MetadataTest.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -390,18 +390,20 @@ TEST_F(MDNodeTest, PrintFromMetadataAsValue) {
390390

391391
EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS));
392392
EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS));
393-
EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false));
394-
EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false));
395-
EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true));
396-
EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true));
393+
EXPECT_PRINTER_EQ("distinct !{}", MAV0->printAsOperand(OS, false));
394+
EXPECT_PRINTER_EQ("distinct !{}", MAV1->printAsOperand(OS, false));
395+
EXPECT_PRINTER_EQ("metadata distinct !{}", MAV0->printAsOperand(OS, true));
396+
EXPECT_PRINTER_EQ("metadata distinct !{}", MAV1->printAsOperand(OS, true));
397397

398398
ModuleSlotTracker MST(&M);
399399
EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS, MST));
400400
EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS, MST));
401-
EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false, MST));
402-
EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false, MST));
403-
EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true, MST));
404-
EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true, MST));
401+
EXPECT_PRINTER_EQ("distinct !{}", MAV0->printAsOperand(OS, false, MST));
402+
EXPECT_PRINTER_EQ("distinct !{}", MAV1->printAsOperand(OS, false, MST));
403+
EXPECT_PRINTER_EQ("metadata distinct !{}",
404+
MAV0->printAsOperand(OS, true, MST));
405+
EXPECT_PRINTER_EQ("metadata distinct !{}",
406+
MAV1->printAsOperand(OS, true, MST));
405407
}
406408

407409
TEST_F(MDNodeTest, PrintWithDroppedCallOperand) {

0 commit comments

Comments
 (0)