This patch adds support to the instruction-referencing LiveDebugValues implementation for emitting entry values. The instruction referencing implementations tracking by value rather than location means that we can get around two of the issues with VarLocs. DBG_VALUE instructions that re-assign the same value to a variable are no longer a problem, because we can "see through" to the value being assigned. We also don't need to do anything special during the dataflow stages: the "variable value problem" doesn't need to know whether a value is available most of the time, and the times it deoes need to know are always when entry values need to be terminated. The patch modifies the "TransferTracker" class, adding methods to identify when a variable ias an entry value candidate, and when a machine value is an entry value. recoverAsEntryValue tests these two things and emits an entry-value expression if they're true. It's used when we clobber or otherwise lose a value and can't find a replacement location for the value it contained. Differential Revision: https://reviews.llvm.org/D88406
124 lines
4.2 KiB
YAML
124 lines
4.2 KiB
YAML
# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown | FileCheck %s
|
|
# RUN: llc %s -o - -force-instr-ref-livedebugvalues=1 -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown | FileCheck %s
|
|
#
|
|
# In this lightly modified test case, the transfer in the entry block from
|
|
# geti32's return value in $eax to the non-volatile $ebx should be recognized,
|
|
# and propagated throughout the whole function.
|
|
#
|
|
# CHECK-LABEL: bb.0.entry
|
|
# CHECK: DBG_VALUE $eax
|
|
# CHECK: DBG_VALUE $ebx
|
|
# CHECK-LABEL: bb.1.loop2
|
|
# CHECK: DBG_VALUE $ebx
|
|
# CHECK-LABEL: bb.2.loop
|
|
# CHECK: DBG_VALUE $ebx
|
|
# CHECK-LABEL: bb.3.exit
|
|
# CHECK: DBG_VALUE $ebx
|
|
--- |
|
|
; ModuleID = 'asdf'
|
|
source_filename = "asdf.ll"
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-unknown"
|
|
|
|
@glob = global i32 0
|
|
|
|
declare i1 @booler()
|
|
|
|
declare i32 @geti32()
|
|
|
|
declare void @escape(i32)
|
|
|
|
; Function Attrs: nounwind readnone speculatable willreturn
|
|
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
|
|
|
define i32 @foo() !dbg !4 {
|
|
entry:
|
|
%bar = call i32 @geti32(), !dbg !10
|
|
call void @llvm.dbg.value(metadata i32 %bar, metadata !9, metadata !DIExpression()), !dbg !10
|
|
br label %loop
|
|
|
|
loop: ; preds = %loop2, %entry
|
|
call void @escape(i32 %bar)
|
|
%retval = call i1 @booler(), !dbg !10
|
|
br i1 %retval, label %loop2, label %exit
|
|
|
|
loop2: ; preds = %loop
|
|
store i32 %bar, i32* @glob
|
|
br label %loop
|
|
|
|
exit: ; preds = %loop
|
|
ret i32 %bar
|
|
}
|
|
|
|
; Function Attrs: nounwind
|
|
declare void @llvm.stackprotector(i8*, i8**)
|
|
|
|
!llvm.module.flags = !{!0, !1}
|
|
!llvm.dbg.cu = !{!2}
|
|
|
|
!0 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!1 = !{i32 2, !"Dwarf Version", i32 4}
|
|
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "beards", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
|
|
!3 = !DIFile(filename: "bees.cpp", directory: ".")
|
|
!4 = distinct !DISubprogram(name: "nope", scope: !3, file: !3, line: 1, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
|
|
!5 = !DISubroutineType(types: !6)
|
|
!6 = !{!7}
|
|
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
|
!8 = !{!9}
|
|
!9 = !DILocalVariable(name: "toast", scope: !4, file: !3, line: 1, type: !7)
|
|
!10 = !DILocation(line: 1, scope: !4)
|
|
|
|
...
|
|
---
|
|
name: foo
|
|
tracksRegLiveness: true
|
|
frameInfo:
|
|
stackSize: 8
|
|
offsetAdjustment: -8
|
|
adjustsStack: true
|
|
hasCalls: true
|
|
cvBytesOfCalleeSavedRegisters: 8
|
|
fixedStack:
|
|
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: default,
|
|
callee-saved-register: '$rbx', callee-saved-restored: true, debug-info-variable: '',
|
|
debug-info-expression: '', debug-info-location: '' }
|
|
stack: []
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.1(0x80000000)
|
|
liveins: $rbx
|
|
|
|
frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp, debug-location !10
|
|
CFI_INSTRUCTION def_cfa_offset 16
|
|
CFI_INSTRUCTION offset $rbx, -16
|
|
CALL64pcrel32 @geti32, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !10
|
|
DBG_VALUE $eax, $noreg, !9, !DIExpression(), debug-location !10
|
|
$ebx = MOV32rr killed $eax, debug-location !10
|
|
JMP_1 %bb.1
|
|
|
|
bb.1.loop2:
|
|
successors: %bb.2
|
|
liveins: $ebx
|
|
|
|
MOV32mr $rip, 1, $noreg, @glob, $noreg, renamable $ebx :: (store (s32) into @glob)
|
|
|
|
bb.2.loop:
|
|
successors: %bb.1, %bb.3
|
|
liveins: $ebx
|
|
|
|
$edi = MOV32rr $ebx
|
|
CALL64pcrel32 @escape, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit-def $rsp, implicit-def $ssp
|
|
CALL64pcrel32 @booler, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $al, debug-location !10
|
|
TEST8ri killed renamable $al, 1, implicit-def $eflags
|
|
JCC_1 %bb.1, 5, implicit $eflags
|
|
|
|
bb.3.exit:
|
|
liveins: $ebx
|
|
|
|
$eax = MOV32rr killed $ebx
|
|
$rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp
|
|
CFI_INSTRUCTION def_cfa_offset 8
|
|
RETQ $eax
|
|
|
|
...
|