Skip to content

Commit 291713a

Browse files
committed
[DebugInfo][DAG] Either salvage dangling debug info or emit Undef DBG_VALUEs
In this patch SelectionDAG tries to salvage any dbg.values that are going to be dropped, in case they can be recovered from Values in the current BB. It also strengthens SelectionDAGs handling of dangling debug data, so that dbg.values are *always* emitted (as Undef or otherwise) instead of dangling forever. The motivation behind this patch exists in the new test case: a memory address (here a bitcast and GEP) exist in one basic block, and a dbg.value referring to the address is left in the 'next' block. The base pointer is live across all basic blocks. In current llvm trunk the dbg.value cannot be encoded, and it isn't even emitted as an Undef DBG_VALUE. The change is simply: if we're definitely going to drop a dbg.value, repeatedly apply salvageDebugInfo to its operand until either we find something that can be encoded, or we can't salvage any further in which case we produce an Undef DBG_VALUE. To know when we're "definitely going to drop a dbg.value", SelectionDAG signals SelectionDAGBuilder when all IR instructions have been encoded to force salvaging. This ensures that any dbg.value that's dangling after DAG creation will have a corresponding DBG_VALUE encoded. Differential Revision: https://reviews.llvm.org/D57694 llvm-svn: 353954
1 parent 48d27e8 commit 291713a

File tree

5 files changed

+154
-19
lines changed

5 files changed

+154
-19
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
#include "llvm/Target/TargetIntrinsicInfo.h"
109109
#include "llvm/Target/TargetMachine.h"
110110
#include "llvm/Target/TargetOptions.h"
111+
#include "llvm/Transforms/Utils/Local.h"
111112
#include <algorithm>
112113
#include <cassert>
113114
#include <cstddef>
@@ -1131,6 +1132,13 @@ void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable,
11311132

11321133
for (auto &DDIMI : DanglingDebugInfoMap) {
11331134
DanglingDebugInfoVector &DDIV = DDIMI.second;
1135+
1136+
// If debug info is to be dropped, run it through final checks to see
1137+
// whether it can be salvaged.
1138+
for (auto &DDI : DDIV)
1139+
if (isMatchingDbgValue(DDI))
1140+
salvageUnresolvedDbgValue(DDI);
1141+
11341142
DDIV.erase(remove_if(DDIV, isMatchingDbgValue), DDIV.end());
11351143
}
11361144
}
@@ -1179,12 +1187,73 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
11791187
} else
11801188
LLVM_DEBUG(dbgs() << "Resolved dangling debug info for " << *DI
11811189
<< "in EmitFuncArgumentDbgValue\n");
1182-
} else
1190+
} else {
11831191
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
1192+
auto Undef =
1193+
UndefValue::get(DDI.getDI()->getVariableLocation()->getType());
1194+
auto SDV =
1195+
DAG.getConstantDbgValue(Variable, Expr, Undef, dl, DbgSDNodeOrder);
1196+
DAG.AddDbgValue(SDV, nullptr, false);
1197+
}
11841198
}
11851199
DDIV.clear();
11861200
}
11871201

1202+
void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
1203+
Value *V = DDI.getDI()->getValue();
1204+
DILocalVariable *Var = DDI.getDI()->getVariable();
1205+
DIExpression *Expr = DDI.getDI()->getExpression();
1206+
DebugLoc DL = DDI.getdl();
1207+
DebugLoc InstDL = DDI.getDI()->getDebugLoc();
1208+
unsigned SDOrder = DDI.getSDNodeOrder();
1209+
1210+
// Currently we consider only dbg.value intrinsics -- we tell the salvager
1211+
// that DW_OP_stack_value is desired.
1212+
assert(isa<DbgValueInst>(DDI.getDI()));
1213+
bool StackValue = true;
1214+
1215+
// Can this Value can be encoded without any further work?
1216+
if (handleDebugValue(V, Var, Expr, DL, InstDL, SDOrder))
1217+
return;
1218+
1219+
// Attempt to salvage back through as many instructions as possible. Bail if
1220+
// a non-instruction is seen, such as a constant expression or global
1221+
// variable. FIXME: Further work could recover those too.
1222+
while (isa<Instruction>(V)) {
1223+
Instruction &VAsInst = *cast<Instruction>(V);
1224+
DIExpression *NewExpr = salvageDebugInfoImpl(VAsInst, Expr, StackValue);
1225+
1226+
// If we cannot salvage any further, and haven't yet found a suitable debug
1227+
// expression, bail out.
1228+
if (!NewExpr)
1229+
break;
1230+
1231+
// New value and expr now represent this debuginfo.
1232+
V = VAsInst.getOperand(0);
1233+
Expr = NewExpr;
1234+
1235+
// Some kind of simplification occurred: check whether the operand of the
1236+
// salvaged debug expression can be encoded in this DAG.
1237+
if (handleDebugValue(V, Var, Expr, DL, InstDL, SDOrder)) {
1238+
LLVM_DEBUG(dbgs() << "Salvaged debug location info for:\n "
1239+
<< DDI.getDI() << "\nBy stripping back to:\n " << V);
1240+
return;
1241+
}
1242+
}
1243+
1244+
// This was the final opportunity to salvage this debug information, and it
1245+
// couldn't be done. Place an undef DBG_VALUE at this location to terminate
1246+
// any earlier variable location.
1247+
auto Undef = UndefValue::get(DDI.getDI()->getVariableLocation()->getType());
1248+
auto SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder);
1249+
DAG.AddDbgValue(SDV, nullptr, false);
1250+
1251+
LLVM_DEBUG(dbgs() << "Dropping debug value info for:\n " << DDI.getDI()
1252+
<< "\n");
1253+
LLVM_DEBUG(dbgs() << " Last seen at:\n " << *DDI.getDI()->getOperand(0)
1254+
<< "\n");
1255+
}
1256+
11881257
bool SelectionDAGBuilder::handleDebugValue(const Value *V, DILocalVariable *Var,
11891258
DIExpression *Expr, DebugLoc dl,
11901259
DebugLoc InstDL, unsigned Order) {
@@ -1277,6 +1346,14 @@ bool SelectionDAGBuilder::handleDebugValue(const Value *V, DILocalVariable *Var,
12771346
return false;
12781347
}
12791348

1349+
void SelectionDAGBuilder::resolveOrClearDbgInfo() {
1350+
// Try to fixup any remaining dangling debug info -- and drop it if we can't.
1351+
for (auto &Pair : DanglingDebugInfoMap)
1352+
for (auto &DDI : Pair.getSecond())
1353+
salvageUnresolvedDbgValue(DDI);
1354+
clearDanglingDebugInfo();
1355+
}
1356+
12801357
/// getCopyFromRegs - If there was virtual register allocated for the value V
12811358
/// emit CopyFromReg of the specified type Ty. Return empty SDValue() otherwise.
12821359
SDValue SelectionDAGBuilder::getCopyFromRegs(const Value *V, Type *Ty) {
@@ -5552,21 +5629,12 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
55525629
SDNodeOrder))
55535630
return nullptr;
55545631

5555-
// TODO: When we get here we will either drop the dbg.value completely, or
5556-
// we try to move it forward by letting it dangle for awhile. So we should
5557-
// probably add an extra DbgValue to the DAG here, with a reference to
5558-
// "noreg", to indicate that we have lost the debug location for the
5559-
// variable.
5560-
5561-
if (!V->use_empty() ) {
5562-
// Do not call getValue(V) yet, as we don't want to generate code.
5563-
// Remember it for later.
5564-
DanglingDebugInfoMap[V].emplace_back(&DI, dl, SDNodeOrder);
5565-
return nullptr;
5566-
}
5632+
// TODO: Dangling debug info will eventually either be resolved or produce
5633+
// an Undef DBG_VALUE. However in the resolution case, a gap may appear
5634+
// between the original dbg.value location and its resolved DBG_VALUE, which
5635+
// we should ideally fill with an extra Undef DBG_VALUE.
55675636

5568-
LLVM_DEBUG(dbgs() << "Dropping debug location info for:\n " << DI << "\n");
5569-
LLVM_DEBUG(dbgs() << " Last seen at:\n " << *V << "\n");
5637+
DanglingDebugInfoMap[V].emplace_back(&DI, dl, SDNodeOrder);
55705638
return nullptr;
55715639
}
55725640

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,16 +676,24 @@ class SelectionDAGBuilder {
676676
void dropDanglingDebugInfo(const DILocalVariable *Variable,
677677
const DIExpression *Expr);
678678

679-
// If we saw an earlier dbg_value referring to V, generate the debug data
680-
// structures now that we've seen its definition.
679+
/// If we saw an earlier dbg_value referring to V, generate the debug data
680+
/// structures now that we've seen its definition.
681681
void resolveDanglingDebugInfo(const Value *V, SDValue Val);
682682

683-
// For a given Value, attempt to create and record a SDDbgValue in the
684-
// SelectionDAG.
683+
/// For the given dangling debuginfo record, perform last-ditch efforts to
684+
/// resolve the debuginfo to something that is represented in this DAG. If
685+
/// this cannot be done, produce an Undef debug value record.
686+
void salvageUnresolvedDbgValue(DanglingDebugInfo &DDI);
687+
688+
/// For a given Value, attempt to create and record a SDDbgValue in the
689+
/// SelectionDAG.
685690
bool handleDebugValue(const Value *V, DILocalVariable *Var,
686691
DIExpression *Expr, DebugLoc CurDL,
687692
DebugLoc InstDL, unsigned Order);
688693

694+
/// Evict any dangling debug information, attempting to salvage it first.
695+
void resolveOrClearDbgInfo();
696+
689697
SDValue getValue(const Value *V);
690698
bool findValue(const Value *V) const;
691699

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
691691
// Make sure the root of the DAG is up-to-date.
692692
CurDAG->setRoot(SDB->getControlRoot());
693693
HadTailCall = SDB->HasTailCall;
694+
SDB->resolveOrClearDbgInfo();
694695
SDB->clear();
695696

696697
// Final step, emit the lowered DAG as machine code.

llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ entry3:
101101
; Verify that the def comes before the for bar4.
102102
define i32 @test4() local_unnamed_addr #0 !dbg !40 {
103103
; CHECK-LABEL: bb.0.entry4
104+
; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[FOO4]], !DIExpression()
104105
; CHECK-NEXT: DBG_VALUE 0, $noreg, ![[FOO4]], !DIExpression()
105106
; CHECK-NEXT: [[REG4:%[0-9]+]]:gr64 =
106107
; CHECK-NEXT: DBG_VALUE [[REG4]], $noreg, ![[BAR4]], !DIExpression()
@@ -114,6 +115,7 @@ entry4:
114115
; Verify that we do not get a DBG_VALUE that maps foo5 to @S here.
115116
define i32 @test5() local_unnamed_addr #0 !dbg !47 {
116117
; CHECK-LABEL: bb.0.entry5:
118+
; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[FOO5]], !DIExpression()
117119
; CHECK-NEXT: DBG_VALUE 0, $noreg, ![[FOO5]], !DIExpression()
118120
; CHECK-NEXT: [[REG5:%[0-9]+]]:gr64 =
119121
; CHECK-NEXT: DBG_VALUE [[REG5]], $noreg, ![[BAR5]], !DIExpression()
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare -stop-before expand-isel-pseudos %s -o - | FileCheck %s
2+
3+
; Test that the dbg.value for %baz, which doesn't exist in the 'next' bb,
4+
; can be salvaged back to the underlying argument vreg.
5+
6+
; CHECK: ![[AAAVAR:.*]] = !DILocalVariable(name: "aaa",
7+
; CHECK-LABEL: bb.1.next:
8+
; CHECK: DBG_VALUE %{{[0-9]+}}, $noreg, ![[AAAVAR]]
9+
10+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
11+
target triple = "x86_64-linux-gnu"
12+
13+
define i8 @f(i32* %foo) local_unnamed_addr !dbg !6 {
14+
entry:
15+
%bar = getelementptr i32, i32* %foo, i32 4
16+
%baz = bitcast i32* %bar to i8*
17+
%quux = load i8, i8* %baz
18+
br label %next
19+
20+
next: ; preds = %entry
21+
tail call void @llvm.dbg.value(metadata i8* %baz, metadata !15, metadata !DIExpression()), !dbg !30
22+
%xyzzy = add i8 %quux, 123
23+
br label %fin
24+
25+
fin: ; preds = %next
26+
%trains = getelementptr i32, i32* %foo, i32 3
27+
%planes = bitcast i32* %trains to i8*
28+
%cars = load i8, i8* %planes
29+
%ret = add i8 %xyzzy, %cars
30+
ret i8 %ret
31+
}
32+
33+
; Function Attrs: nounwind readnone speculatable
34+
declare void @llvm.dbg.value(metadata, metadata, metadata) #0
35+
36+
attributes #0 = { nounwind readnone speculatable }
37+
38+
!llvm.dbg.cu = !{!0}
39+
!llvm.module.flags = !{!25, !26, !27, !28}
40+
!llvm.ident = !{!29}
41+
42+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
43+
!1 = !DIFile(filename: "test.c", directory: ".")
44+
!2 = !{}
45+
!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 18, type: !7, scopeLine: 19, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !14)
46+
!7 = !DISubroutineType(types: !8)
47+
!8 = !{!13}
48+
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_unsigned)
49+
!14 = !{!15}
50+
!15 = !DILocalVariable(name: "aaa", scope: !6, file: !1, line: 18, type: !13)
51+
!25 = !{i32 2, !"Dwarf Version", i32 4}
52+
!26 = !{i32 2, !"Debug Info Version", i32 3}
53+
!27 = !{i32 1, !"wchar_size", i32 4}
54+
!28 = !{i32 7, !"PIC Level", i32 2}
55+
!29 = !{!"clang"}
56+
!30 = !DILocation(line: 18, column: 14, scope: !6)

0 commit comments

Comments
 (0)