Skip to content

Commit a9a11aa

Browse files
committed
[DebugInfo][DAG] Limit special-casing of dbg.values for Arguments
SelectionDAGBuilder has special handling for dbg.value intrinsics that are understood to define the location of function parameters on entry to the function. To enable this, we avoid recording a dbg.value as a virtual register reference if it might be such a parameter, so that it later hits EmitFuncArgumentDbgValue. This patch reduces the set of circumstances where we avoid recording a dbg.value as a virtual register reference, to allow more "normal" variables to be recorded that way. We now only bypass for potential parameters if: * The dbg.value operand is an Argument, * The Variable is a parameter, and * The Variable is not inlined. meaning it's very likely that the dbg.value is a function-entry parameter location. Differential Revision: https://reviews.llvm.org/D57584 llvm-svn: 353948
1 parent 76e9612 commit a9a11aa

File tree

2 files changed

+114
-4
lines changed

2 files changed

+114
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5492,10 +5492,16 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
54925492
return nullptr;
54935493
}
54945494

5495-
// The value is not used in this block yet (or it would have an SDNode).
5496-
// We still want the value to appear for the user if possible -- if it has
5497-
// an associated VReg, we can refer to that instead.
5498-
if (!isa<Argument>(V)) {
5495+
// Special rules apply for the first dbg.values of parameter variables in a
5496+
// function. Identify them by the fact they reference Argument Values, that
5497+
// they're parameters, and they are parameters of the current function. We
5498+
// need to let them dangle until they get an SDNode.
5499+
bool IsParamOfFunc = isa<Argument>(V) && Variable->isParameter() &&
5500+
!DI.getDebugLoc()->getInlinedAt();
5501+
if (!IsParamOfFunc) {
5502+
// The value is not used in this block yet (or it would have an SDNode).
5503+
// We still want the value to appear for the user if possible -- if it has
5504+
// an associated VReg, we can refer to that instead.
54995505
auto VMI = FuncInfo.ValueMap.find(V);
55005506
if (VMI != FuncInfo.ValueMap.end()) {
55015507
unsigned Reg = VMI->second;
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare -stop-before=expand-isel-pseudos %s -o - | FileCheck %s
2+
3+
; Test the movement of dbg.values of arguments. SelectionDAG tries to be
4+
; helpful and places DBG_VALUEs of Arguments at the start of functions.
5+
; Unfortunately, this doesn't necessarily make sense, as one can specify an
6+
; Argument IR Value as a variable location anywhere in the program.
7+
;
8+
; Distinguish cases where we want to hoist DBG_VALUEs, and those where we
9+
; don't, by whether the referred to variable is a parameter to the current
10+
; function. In the test below, 'xyzzy' is a parameter to an inlined function,
11+
; but should not be hoisted to the start of the function.
12+
;
13+
; Original test case, in which 'xyzzy' became unavailable because its DBG_VALUE
14+
; landed far from any uses, compiled "clang -O2 -g" with inlining,
15+
;
16+
; int ext(void);
17+
;
18+
; int
19+
; foo(int xyzzy)
20+
; {
21+
; xyzzy = ext() * xyzzy;
22+
; xyzzy += 1;
23+
; ext();
24+
; return xyzzy;
25+
; }
26+
;
27+
; int
28+
; bar(int baz, int qux)
29+
; {
30+
; int fish;
31+
; switch (qux) {
32+
; case 12: fish = 8; break;
33+
; case 848: fish = 0; break;
34+
; case 99999: fish = -1; break;
35+
; default: fish = 12;
36+
; }
37+
; qux %= fish;
38+
; qux += foo(baz);
39+
; return qux;
40+
; }
41+
42+
; CHECK: [[BAZVAR:![0-9]+]] = !DILocalVariable(name: "baz",
43+
; CHECK: [[XYZVAR:![0-9]+]] = !DILocalVariable(name: "xyzzy",
44+
45+
; Start of MIR function block,
46+
; CHECK-LABEL: body
47+
; Expect DBG_VALUE of physreg,
48+
; CHECK: DBG_VALUE $edi, $noreg, [[BAZVAR]]
49+
; Expect DBG_VALUE of virtreg,
50+
; CHECK: DBG_VALUE [[ARGREG:%[0-9]+]], $noreg, [[BAZVAR]]
51+
; Label for next block,
52+
; CHECK-LABEL: bb.1.next
53+
; Correctly place dbg.value in the 'next' block.
54+
; CHECK: DBG_VALUE [[ARGREG]], $noreg, [[XYZVAR]]
55+
56+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
57+
target triple = "x86_64-unknown-linux-gnu"
58+
59+
declare i32 @ext()
60+
61+
define dso_local i32 @bar(i32, i32) local_unnamed_addr !dbg !7 {
62+
%3 = srem i32 %1, %0, !dbg !15
63+
call void @llvm.dbg.value(metadata i32 %0, metadata !12, metadata !DIExpression()), !dbg !16
64+
br label %next
65+
66+
next: ; preds = %2
67+
call void @llvm.dbg.value(metadata i32 %0, metadata !17, metadata !DIExpression()), !dbg !22
68+
%4 = tail call i32 @ext(), !dbg !24
69+
%5 = mul nsw i32 %3, %4, !dbg !25
70+
%6 = add i32 %5, %0, !dbg !25
71+
ret i32 %6, !dbg !25
72+
}
73+
74+
; Function Attrs: nounwind readnone speculatable
75+
declare void @llvm.dbg.value(metadata, metadata, metadata)
76+
77+
!llvm.dbg.cu = !{!0}
78+
!llvm.module.flags = !{!3, !4, !5}
79+
!llvm.ident = !{!6}
80+
81+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2, nameTableKind: None)
82+
!1 = !DIFile(filename: "test.c", directory: ".")
83+
!2 = !{}
84+
!3 = !{i32 2, !"Dwarf Version", i32 4}
85+
!4 = !{i32 2, !"Debug Info Version", i32 3}
86+
!5 = !{i32 1, !"wchar_size", i32 4}
87+
!6 = !{!"clang version 8.0.0"}
88+
!7 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 19, type: !8, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
89+
!8 = !DISubroutineType(types: !9)
90+
!9 = !{!10, !10, !10}
91+
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
92+
!11 = !{!12}
93+
!12 = !DILocalVariable(name: "baz", arg: 1, scope: !7, file: !1, line: 19, type: !10)
94+
!15 = !DILocation(line: 35, column: 7, scope: !7)
95+
!16 = !DILocation(line: 19, column: 9, scope: !7)
96+
!17 = !DILocalVariable(name: "xyzzy", arg: 1, scope: !18, file: !1, line: 10, type: !10)
97+
!18 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !19, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !21)
98+
!19 = !DISubroutineType(types: !20)
99+
!20 = !{!10, !10}
100+
!21 = !{!17}
101+
!22 = !DILocation(line: 10, column: 9, scope: !18, inlinedAt: !23)
102+
!23 = distinct !DILocation(line: 36, column: 10, scope: !7)
103+
!24 = !DILocation(line: 12, column: 11, scope: !18, inlinedAt: !23)
104+
!25 = !DILocation(line: 37, column: 3, scope: !7)

0 commit comments

Comments
 (0)