Index: llvm/trunk/lib/CodeGen/LiveDebugValues.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LiveDebugValues.cpp +++ llvm/trunk/lib/CodeGen/LiveDebugValues.cpp @@ -258,7 +258,8 @@ bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs, const VarLocMap &VarLocIDs, - SmallPtrSet &Visited); + SmallPtrSet &Visited, + SmallPtrSetImpl &ArtificialBlocks); bool ExtendRanges(MachineFunction &MF); @@ -633,9 +634,11 @@ /// 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 &Visited) { +bool LiveDebugValues::join( + MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs, + const VarLocMap &VarLocIDs, + SmallPtrSet &Visited, + SmallPtrSetImpl &ArtificialBlocks) { LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n"); bool Changed = false; @@ -678,13 +681,16 @@ // 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); @@ -737,6 +743,10 @@ 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 ArtificialBlocks; + DenseMap OrderToBB; DenseMap BBToOrder; std::priority_queue, @@ -758,6 +768,15 @@ 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())); @@ -783,7 +802,8 @@ 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; Index: llvm/trunk/test/DebugInfo/AArch64/compiler-gen-bbs-livedebugvalues.ll =================================================================== --- llvm/trunk/test/DebugInfo/AArch64/compiler-gen-bbs-livedebugvalues.ll +++ llvm/trunk/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)