Skip to content

Commit

Permalink
[LiveDebugValues] Extend var ranges through artificial blocks
Browse files Browse the repository at this point in the history
ASan often introduces basic blocks consisting exclusively of
instructions without debug locations, or with line 0 debug locations.

LiveDebugValues needs to extend variable ranges through these artificial
blocks. Otherwise, a lot of variables disappear -- even at -O0.

Typically, LiveDebugValues does not extend a variable's range into a
block unless the block is essentially "part of" the variable's scope
(for a precise definition, see LexicalScopes::dominates). This patch
relaxes the lexical dominance check for artificial blocks.

This makes the following Swift program debuggable at -O0:
```
  1| var x = 100
  2| print("x = \(x)")
```

rdar://39127144

Differential Revision: https://reviews.llvm.org/D52921

llvm-svn: 343890
  • Loading branch information
vedantk committed Oct 5, 2018
1 parent 9b55838 commit 8c46668
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 12 deletions.
44 changes: 32 additions & 12 deletions llvm/lib/CodeGen/LiveDebugValues.cpp
Expand Up @@ -258,7 +258,8 @@ class LiveDebugValues : public MachineFunctionPass {

bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
const VarLocMap &VarLocIDs,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited);
SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks);

bool ExtendRanges(MachineFunction &MF);

Expand Down Expand Up @@ -633,9 +634,11 @@ bool LiveDebugValues::process(MachineInstr &MI, OpenRangesSet &OpenRanges,
/// This routine joins the analysis results of all incoming edges in @MBB by
/// inserting a new DBG_VALUE instruction at the start of the @MBB - if the same
/// source variable in all the predecessors of @MBB reside in the same location.
bool LiveDebugValues::join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs,
VarLocInMBB &InLocs, const VarLocMap &VarLocIDs,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited) {
bool LiveDebugValues::join(
MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
const VarLocMap &VarLocIDs,
SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
SmallPtrSetImpl<const MachineBasicBlock *> &ArtificialBlocks) {
LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n");
bool Changed = false;

Expand Down Expand Up @@ -678,13 +681,16 @@ bool LiveDebugValues::join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs,

// Filter out DBG_VALUES that are out of scope.
VarLocSet KillSet;
for (auto ID : InLocsT) {
if (!VarLocIDs[ID].dominates(MBB)) {
KillSet.set(ID);
LLVM_DEBUG({
auto Name = VarLocIDs[ID].Var.getVar()->getName();
dbgs() << " killing " << Name << ", it doesn't dominate MBB\n";
});
bool IsArtificial = ArtificialBlocks.count(&MBB);
if (!IsArtificial) {
for (auto ID : InLocsT) {
if (!VarLocIDs[ID].dominates(MBB)) {
KillSet.set(ID);
LLVM_DEBUG({
auto Name = VarLocIDs[ID].Var.getVar()->getName();
dbgs() << " killing " << Name << ", it doesn't dominate MBB\n";
});
}
}
}
InLocsT.intersectWithComplement(KillSet);
Expand Down Expand Up @@ -737,6 +743,10 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
VarLocInMBB InLocs; // Ranges that are incoming after joining.
TransferMap Transfers; // DBG_VALUEs associated with spills.

// Blocks which are artificial, i.e. blocks which exclusively contain
// instructions without locations, or with line 0 locations.
SmallPtrSet<const MachineBasicBlock *, 16> ArtificialBlocks;

DenseMap<unsigned int, MachineBasicBlock *> OrderToBB;
DenseMap<MachineBasicBlock *, unsigned int> BBToOrder;
std::priority_queue<unsigned int, std::vector<unsigned int>,
Expand All @@ -758,6 +768,15 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers,
dontTransferChanges);

auto hasNonArtificialLocation = [](const MachineInstr &MI) -> bool {
if (const DebugLoc &DL = MI.getDebugLoc())
return DL.getLine() != 0;
return false;
};
for (auto &MBB : MF)
if (none_of(MBB.instrs(), hasNonArtificialLocation))
ArtificialBlocks.insert(&MBB);

LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs,
"OutLocs after initialization", dbgs()));

Expand All @@ -783,7 +802,8 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
while (!Worklist.empty()) {
MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
Worklist.pop();
MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs, Visited);
MBBJoined =
join(*MBB, OutLocs, InLocs, VarLocIDs, Visited, ArtificialBlocks);
Visited.insert(MBB);
if (MBBJoined) {
MBBJoined = false;
Expand Down
66 changes: 66 additions & 0 deletions llvm/test/DebugInfo/AArch64/compiler-gen-bbs-livedebugvalues.ll
@@ -0,0 +1,66 @@
; RUN: llc -O0 -regalloc=fast -stop-after=livedebugvalues -o - < %s | \
; RUN: FileCheck %s -implicit-check-not=DBG_VALUE

target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-ios12.1.0"

declare void @use(i32 %x)

define void @f1(i32 %x) !dbg !6 {
; CHECK-LABEL: name: f1
entry:
; CHECK-LABEL: bb.0.entry:
%var = add i32 %x, 1, !dbg !12
call void @llvm.dbg.value(metadata i32 %var, metadata !9, metadata !DIExpression()), !dbg !12
; CHECK: DBG_VALUE debug-use renamable $w0, debug-use $noreg, !9, !DIExpression(), debug-location !12
; CHECK-NEXT: STRWui killed $w0, $sp, 3 :: (store 4 into %stack.0)
; CHECK-NEXT: DBG_VALUE debug-use $sp, 0, !9, !DIExpression(DW_OP_plus_uconst, 12)

br label %artificial-bb-1, !dbg !13

artificial-bb-1: ; preds = %entry
; CHECK-LABEL: bb.1.artificial-bb-1:
; CHECK: DBG_VALUE debug-use $sp, 0, !9, !DIExpression(DW_OP_plus_uconst, 12)

br label %artificial-bb-2

artificial-bb-2: ; preds = %artificial-bb-1
; CHECK-LABEL: bb.2.artificial-bb-2:
; CHECK: DBG_VALUE debug-use $sp, 0, !9, !DIExpression(DW_OP_plus_uconst, 12)

%invisible = add i32 %var, 1
br label %return, !dbg !14

return: ; preds = %artificial-bb-2
; CHECK-LABEL: bb.3.return:
; CHECK: DBG_VALUE debug-use $sp, 0, !9, !DIExpression(DW_OP_plus_uconst, 12)

call void @use(i32 %var)
ret void, !dbg !15
}

; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.value(metadata, metadata, metadata) #0

attributes #0 = { nounwind readnone speculatable }

!llvm.dbg.cu = !{!0}
!llvm.debugify = !{!3, !4}
!llvm.module.flags = !{!5}

!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "compiler-gen-bbs-livedebugvalues.ll", directory: "/")
!2 = !{}
!3 = !{i32 6}
!4 = !{i32 2}
!5 = !{i32 2, !"Debug Info Version", i32 3}
!6 = distinct !DISubprogram(name: "f1", linkageName: "f1", scope: null, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !8)
!7 = !DISubroutineType(types: !2)
!8 = !{!9, !11}
!9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
!10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
!11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 4, type: !10)
!12 = !DILocation(line: 1, column: 1, scope: !6)
!13 = !DILocation(line: 2, column: 1, scope: !6)
!14 = !DILocation(line: 0, column: 1, scope: !6)
!15 = !DILocation(line: 4, column: 1, scope: !6)

0 comments on commit 8c46668

Please sign in to comment.