diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -1651,7 +1651,8 @@ /// Add all implicit def and use operands to this instruction. void addImplicitDefUseOperands(MachineFunction &MF); - /// Scan instructions following MI and collect any matching DBG_VALUEs. + /// Scan instructions immediately following MI and collect any matching + /// DBG_VALUEs. void collectDebugValues(SmallVectorImpl &DbgValues); /// Find all DBG_VALUEs that point to the register def in this instruction diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -7230,42 +7230,46 @@ return false; } -// llvm.dbg.value is far away from the value then iSel may not be able -// handle it properly. iSel will drop llvm.dbg.value if it can not -// find a node corresponding to the value. +// A llvm.dbg.value may be using a value before its definition, due to +// optimizations in this pass and others. Scan for such dbg.values, and rescue +// them by moving the dbg.value to immediately after the value definition. +// FIXME: Ideally this should never be necessary, and this has the potential +// to re-order dbg.value intrinsics. bool CodeGenPrepare::placeDbgValues(Function &F) { bool MadeChange = false; + DominatorTree DT(F); + for (BasicBlock &BB : F) { - Instruction *PrevNonDbgInst = nullptr; for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;) { Instruction *Insn = &*BI++; DbgValueInst *DVI = dyn_cast(Insn); - // Leave dbg.values that refer to an alloca alone. These - // intrinsics describe the address of a variable (= the alloca) - // being taken. They should not be moved next to the alloca - // (and to the beginning of the scope), but rather stay close to - // where said address is used. - if (!DVI || (DVI->getValue() && isa(DVI->getValue()))) { - PrevNonDbgInst = Insn; + if (!DVI) continue; - } Instruction *VI = dyn_cast_or_null(DVI->getValue()); - if (VI && VI != PrevNonDbgInst && !VI->isTerminator()) { - // If VI is a phi in a block with an EHPad terminator, we can't insert - // after it. - if (isa(VI) && VI->getParent()->getTerminator()->isEHPad()) - continue; - LLVM_DEBUG(dbgs() << "Moving Debug Value before :\n" - << *DVI << ' ' << *VI); - DVI->removeFromParent(); - if (isa(VI)) - DVI->insertBefore(&*VI->getParent()->getFirstInsertionPt()); - else - DVI->insertAfter(VI); - MadeChange = true; - ++NumDbgValueMoved; - } + + if (!VI || VI->isTerminator()) + continue; + + // If VI is a phi in a block with an EHPad terminator, we can't insert + // after it. + if (isa(VI) && VI->getParent()->getTerminator()->isEHPad()) + continue; + + // If the defining instruction dominates the dbg.value, we do not need + // to move the dbg.value. + if (DT.dominates(VI, DVI)) + continue; + + LLVM_DEBUG(dbgs() << "Moving Debug Value before :\n" + << *DVI << ' ' << *VI); + DVI->removeFromParent(); + if (isa(VI)) + DVI->insertBefore(&*VI->getParent()->getFirstInsertionPt()); + else + DVI->insertAfter(VI); + MadeChange = true; + ++NumDbgValueMoved; } } return MadeChange; diff --git a/llvm/test/DebugInfo/COFF/register-variables.ll b/llvm/test/DebugInfo/COFF/register-variables.ll --- a/llvm/test/DebugInfo/COFF/register-variables.ll +++ b/llvm/test/DebugInfo/COFF/register-variables.ll @@ -32,9 +32,6 @@ ; ASM: #DEBUG_VALUE: f:p <- $esi ; ASM: callq getint ; ASM: [[after_getint:\.Ltmp.*]]: -; ASM: #DEBUG_VALUE: a <- $eax -; ASM: #DEBUG_VALUE: inlineinc:a <- $eax -; ASM: #DEBUG_VALUE: c <- $eax ; ASM: testl %esi, %esi ; ASM: je .LBB0_2 ; ASM: [[after_je:\.Ltmp.*]]: @@ -45,16 +42,17 @@ ; ASM: addl $1, %eax ; ASM: [[after_inc_eax:\.Ltmp.*]]: ; ASM: #DEBUG_VALUE: inlineinc:b <- $eax -; ASM: #DEBUG_VALUE: b <- $eax ; ASM: addl $1, x(%rip) ; ASM: [[after_if:\.Ltmp.*]]: ; ASM: .LBB0_2: # %if.else ; ASM: #DEBUG_VALUE: f:p <- $esi +; ASM: #DEBUG_VALUE: c <- $eax ; ASM: movl %eax, %ecx ; ASM: addq $32, %rsp ; ASM: popq %rsi ; ASM: [[func_end:\.Ltmp.*]]: ; ASM: jmp putint # TAILCALL +; ASM: [[func_finished:\.Ltmp.*]]: ; ASM: .short 4414 # Record kind: S_LOCAL ; ASM: .asciz "p" @@ -62,18 +60,20 @@ ; ASM: .cv_def_range [[p_ecx_esi]] [[func_end]], reg, 23 ; ASM: .short 4414 # Record kind: S_LOCAL ; ASM: .asciz "c" -; ASM: .cv_def_range [[after_getint]] [[after_je]], reg, 17 +; ASM: .cv_def_range [[after_if]] [[func_finished]], reg, 17 ; ASM: .short 4414 # Record kind: S_LOCAL ; ASM: .asciz "a" -; ASM: .cv_def_range [[after_getint]] [[after_inc_eax]], reg, 17 +; ASM: .cv_def_range [[after_je]] [[after_inc_eax]], reg, 17 ; ASM: .short 4414 # Record kind: S_LOCAL ; ASM: .asciz "b" -; ASM: .cv_def_range [[after_inc_eax]] [[after_if]], reg, 17 +; ASM: .cv_def_range [[after_if]] [[after_if]], reg, 17 + +; Note: "b" is a victim of tail de-duplication / branch folding. ; ASM: .short 4429 # Record kind: S_INLINESITE ; ASM: .short 4414 # Record kind: S_LOCAL ; ASM: .asciz "a" -; ASM: .cv_def_range [[after_getint]] [[after_inc_eax]], reg, 17 +; ASM: .cv_def_range [[after_je]] [[after_inc_eax]], reg, 17 ; ASM: .short 4414 # Record kind: S_LOCAL ; ASM: .asciz "b" ; ASM: .cv_def_range [[after_inc_eax]] [[after_if]], reg, 17 @@ -116,9 +116,9 @@ ; OBJ: DefRangeRegisterSym { ; OBJ: Register: EAX (0x11) ; OBJ: LocalVariableAddrRange { -; OBJ: OffsetStart: .text+0xC +; OBJ: OffsetStart: .text+0x1A ; OBJ: ISectStart: 0x0 -; OBJ: Range: 0x4 +; OBJ: Range: 0xC ; OBJ: } ; OBJ: } ; OBJ: LocalSym { @@ -130,23 +130,9 @@ ; OBJ: DefRangeRegisterSym { ; OBJ: Register: EAX (0x11) ; OBJ: LocalVariableAddrRange { -; OBJ: OffsetStart: .text+0xC +; OBJ: OffsetStart: .text+0x10 ; OBJ: ISectStart: 0x0 -; OBJ: Range: 0x7 -; OBJ: } -; OBJ: } -; OBJ: LocalSym { -; OBJ: Type: int (0x74) -; OBJ: Flags [ (0x0) -; OBJ: ] -; OBJ: VarName: b -; OBJ: } -; OBJ: DefRangeRegisterSym { -; OBJ: Register: EAX (0x11) -; OBJ: MayHaveNoName: 0 -; OBJ: OffsetStart: .text+0x13 -; OBJ: ISectStart: 0x0 -; OBJ: Range: 0x7 +; OBJ: Range: 0x3 ; OBJ: } ; OBJ: } ; OBJ: InlineSiteSym { @@ -164,9 +150,9 @@ ; OBJ: DefRangeRegisterSym { ; OBJ: Register: EAX (0x11) ; OBJ: LocalVariableAddrRange { -; OBJ: OffsetStart: .text+0xC +; OBJ: OffsetStart: .text+0x10 ; OBJ: ISectStart: 0x0 -; OBJ: Range: 0x7 +; OBJ: Range: 0x3 ; OBJ: } ; OBJ: } ; OBJ: LocalSym { diff --git a/llvm/test/DebugInfo/NVPTX/debug-info.ll b/llvm/test/DebugInfo/NVPTX/debug-info.ll --- a/llvm/test/DebugInfo/NVPTX/debug-info.ll +++ b/llvm/test/DebugInfo/NVPTX/debug-info.ll @@ -8388,8 +8388,8 @@ ; CHECK-NEXT: .b8 37 // DW_AT_call_column ; CHECK-NEXT: .b8 43 // Abbrev [43] 0x2711:0x23 DW_TAG_inlined_subroutine ; CHECK-NEXT: .b32 9791 // DW_AT_abstract_origin -; CHECK-NEXT: .b64 Ltmp10 // DW_AT_low_pc -; CHECK-NEXT: .b64 Ltmp11 // DW_AT_high_pc +; CHECK-NEXT: .b64 Ltmp9 // DW_AT_low_pc +; CHECK-NEXT: .b64 Ltmp10 // DW_AT_high_pc ; CHECK-NEXT: .b8 12 // DW_AT_call_file ; CHECK-NEXT: .b8 8 // DW_AT_call_line ; CHECK-NEXT: .b8 5 // DW_AT_call_column diff --git a/llvm/test/DebugInfo/X86/DW_AT_location-reference.ll b/llvm/test/DebugInfo/X86/DW_AT_location-reference.ll --- a/llvm/test/DebugInfo/X86/DW_AT_location-reference.ll +++ b/llvm/test/DebugInfo/X86/DW_AT_location-reference.ll @@ -32,7 +32,9 @@ ; CHECK: .debug_info contents: ; CHECK: DW_TAG_variable ; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x00000000 -; Check that the location contains only 2 ranges. +; Check that the location contains only 4 ranges. +; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}}) +; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}}) ; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}}) ; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}}){{.*}}) ; CHECK-NEXT: DW_AT_name {{.*}} "x" diff --git a/llvm/test/DebugInfo/X86/PR37234.ll b/llvm/test/DebugInfo/X86/PR37234.ll --- a/llvm/test/DebugInfo/X86/PR37234.ll +++ b/llvm/test/DebugInfo/X86/PR37234.ll @@ -20,9 +20,8 @@ ; CHECK-LABEL: # %bb.{{.*}}: ; CHECK: #DEBUG_VALUE: main:aa <- 0 -; CHECK: #DEBUG_VALUE: main:aa <- $[[REG:[0-9a-z]+]] ; CHECK: .LBB0_1: -; CHECK: #DEBUG_VALUE: main:aa <- $[[REG]] +; CHECK: #DEBUG_VALUE: main:aa <- $[[REG:[0-9a-z]+]] ; CHECK: je .LBB0_4 ; CHECK: # %bb.{{.*}}: ; CHECK: #DEBUG_VALUE: main:aa <- $[[REG]] diff --git a/llvm/test/DebugInfo/X86/codegenprep-addrsink.ll b/llvm/test/DebugInfo/X86/codegenprep-addrsink.ll --- a/llvm/test/DebugInfo/X86/codegenprep-addrsink.ll +++ b/llvm/test/DebugInfo/X86/codegenprep-addrsink.ll @@ -9,17 +9,12 @@ ; memory instruction. Test that the one before does _not_ get updated (as that ; would either make it use-before-def or shift when the variable appears), and ; that the dbg.value after the memory instruction does get updated. -; -; Due to placeDbgValues, the dbg.values currently get shifted up a few -; instructions. define dso_local i8 @foo(i32 *%p, i32 %cond) !dbg !7 { entry: -; The first dbg.value of %arith, in the 'next' block, will be moved up here -; by placeDbgValues, +; There should be no dbg.values in this block. ; CHECK-LABEL: entry: -; CHECK: dbg.value(metadata i8* %arith, metadata ![[DIVAR:[0-9]+]], -; CHECK-SAME: metadata !DIExpression() +; CHECK-NOT: dbg.value %casted = bitcast i32 *%p to i8* %arith = getelementptr i8, i8 *%casted, i32 3 %load1 = load i8, i8 *%arith @@ -30,12 +25,14 @@ ; Address calcs should be duplicated into this block. One dbg.value should be ; updated, and the other should not. ; CHECK-LABEL: next: -; CHECK: %[[CASTVAR:[0-9a-zA-Z]+]] = bitcast i32* %p to i8* +; CHECK: dbg.value(metadata i8* %arith, metadata ![[DIVAR:[0-9]+]], +; CHECK-SAME: metadata !DIExpression() +; CHECK-NEXT: %[[CASTVAR:[0-9a-zA-Z]+]] = bitcast i32* %p to i8* ; CHECK-NEXT: %[[GEPVAR:[0-9a-zA-Z]+]] = getelementptr i8, i8* %[[CASTVAR]], ; CHECK-SAME: i64 3 +; CHECK-NEXT: %loaded = load i8, i8* %[[GEPVAR]] ; CHECK-NEXT: call void @llvm.dbg.value(metadata i8* %[[GEPVAR]], ; CHECK-SAME: metadata ![[DIVAR]], -; CHECK-NEXT: %loaded = load i8, i8* %[[GEPVAR]] call void @llvm.dbg.value(metadata i8 *%arith, metadata !12, metadata !DIExpression()), !dbg !14 %loaded = load i8, i8 *%arith call void @llvm.dbg.value(metadata i8 *%arith, metadata !12, metadata !DIExpression()), !dbg !14 diff --git a/llvm/test/tools/llvm-locstats/locstats.ll b/llvm/test/tools/llvm-locstats/locstats.ll --- a/llvm/test/tools/llvm-locstats/locstats.ll +++ b/llvm/test/tools/llvm-locstats/locstats.ll @@ -11,9 +11,9 @@ ; LOCSTATS: 30-39% 0 0% ; LOCSTATS: 40-49% 1 11% ; LOCSTATS: 50-59% 1 11% -; LOCSTATS: 60-69% 1 11% +; LOCSTATS: 60-69% 0 0% ; LOCSTATS: 70-79% 0 0% -; LOCSTATS: 80-89% 2 22% +; LOCSTATS: 80-89% 3 33% ; LOCSTATS: 90-99% 1 11% ; LOCSTATS: 100% 2 22% ;