1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00
llvm-mirror/test/DebugInfo/X86/live-debug-vars-intervals.mir
OCHyams eca70845a6 [DebugInfo] Teach LDV how to handle identical variable fragments
LiveDebugVariables uses interval maps to explicitly represent DBG_VALUE
intervals. DBG_VALUEs are filtered into an interval map based on their {
Variable, DIExpression }. The interval map will coalesce adjacent entries that
use the same { Location }.  Under this model, DBG_VALUEs which refer to the same
bits of the same variable will be filtered into different interval maps if they
have different DIExpressions which means the original intervals will not be
properly preserved.

This patch fixes the problem by using { Variable, Fragment } to filter the
DBG_VALUEs into maps, and coalesces adjacent entries iff they have the same
{ Location, DIExpression } pair.

The solution is not perfect because we see the similar issues appear when
partially overlapping fragments are encountered, but is far simpler than a
complete solution (i.e. D70121).

Fixes: pr41992, pr43957
Reviewed By: aprantl
Differential Revision: https://reviews.llvm.org/D74053
2020-02-11 10:20:24 +00:00

155 lines
8.1 KiB
YAML

# These tests check that DBG_VALUE intervals are correctly coalesced (or not) in
# LiveDebugVariables.
# NOTE: We do not currently handle partially overlapping fragments in LDV.
#
# The IR in this file has been modified by hand, generated from this source:
# void escape(int *);
# extern int global;
# void f(int x) {
# escape(&x);
# x = 1;
# global = x;
# x = 2;
# escape(&x);
# }
# RUN: llc %s -start-before=machine-scheduler -stop-after=virtregrewriter -o - \
# RUN: | FileCheck %s --implicit-check-not=DBG_VALUE
# Verify that DBG_VALUEs with same { Variable, Fragment } but different DIExpressions
# are not coalesced.
#
# DV1 %0 "x" (deref) --+-- Do not coalesce these because DV2 refers to the same bits.
# DV2 %0 "x" () |
# DV3 %0 "x" (deref) --+
#
# CHECK: name: f1
# CHECK: DBG_VALUE %stack.0.x.addr, $noreg, ![[VAR:[0-9]+]], !DIExpression(DW_OP_deref)
# CHECK: DBG_VALUE %stack.0.x.addr, $noreg, ![[VAR]], !DIExpression()
# CHECK: DBG_VALUE %stack.0.x.addr, $noreg, ![[VAR]], !DIExpression(DW_OP_deref)
# Verify that DBG_VALUEs with same { Variable, Fragment } and { Location, DIExpression } are
# coalesced if there are no intervening DBG_VALUEs with the same { Variable, Fragment }.
#
# DV1 %0 "x" (fragment 00 16) --+-- Coalesce these because DV2 refers to different bits.
# DV2 %0 "x" (fragment 16 16) |
# DV3 %0 "x" (fragment 00 16) --+
#
# CHECK: name: f2
# CHECK: DBG_VALUE %stack.0.x.addr, $noreg, ![[VAR:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 16)
# CHECK: DBG_VALUE %stack.0.x.addr, $noreg, ![[VAR]], !DIExpression(DW_OP_LLVM_fragment, 16, 16)
--- |
target triple = "x86_64-unknown-linux-gnu"
@global = external global i32, align 4
declare void @llvm.dbg.value(metadata, metadata, metadata)
declare void @escape(i32*)
define void @f1(i32 %x) !dbg !6 {
entry:
%x.addr = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !11, metadata !DIExpression(DW_OP_deref)), !dbg !12
call void @escape(i32* %x.addr), !dbg !12
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !11, metadata !DIExpression()), !dbg !12
store i32 1, i32* @global, align 4, !dbg !12
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !11, metadata !DIExpression(DW_OP_deref)), !dbg !12
store i32 2, i32* %x.addr, align 4, !dbg !12
call void @escape(i32* %x.addr), !dbg !12
ret void, !dbg !12
}
define void @f2(i32 %x) !dbg !13 {
entry:
%x.addr = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !14, metadata !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 16)), !dbg !15
call void @escape(i32* %x.addr)
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !14, metadata !DIExpression(DW_OP_LLVM_fragment, 16, 16)), !dbg !15
store i32 1, i32* @global, align 4
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !14, metadata !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 16)), !dbg !15
store i32 2, i32* %x.addr, align 4
call void @escape(i32* %x.addr)
ret void
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!llvm.ident = !{!5}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "test.c", directory: "")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{!"clang version 11.0.0 "}
!6 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 3, type: !7, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
!7 = !DISubroutineType(types: !8)
!8 = !{null, !9}
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!10 = !{!11}
!11 = !DILocalVariable(name: "x", arg: 1, scope: !6, file: !1, line: 3, type: !9)
!12 = !DILocation(line: 3, column: 12, scope: !6)
!13 = distinct !DISubprogram(name: "f2", scope: !1, file: !1, line: 20, type: !7, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
!14 = !DILocalVariable(name: "x", arg: 1, scope: !13, file: !1, line: 21, type: !9)
!15 = !DILocation(line: 23, column: 12, scope: !13)
...
---
name: f1
tracksRegLiveness: true
stack:
- { id: 0, name: x.addr, type: default, offset: 0, size: 4, alignment: 4,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
body: |
bb.0.entry:
liveins: $edi
%0:gr32 = COPY $edi
MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0 :: (store 4 into %ir.x.addr)
DBG_VALUE %stack.0.x.addr, $noreg, !11, !DIExpression(DW_OP_deref), debug-location !12
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !12
%1:gr64 = LEA64r %stack.0.x.addr, 1, $noreg, 0, $noreg
$rdi = COPY %1, debug-location !12
CALL64pcrel32 @escape, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, debug-location !12
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !12
DBG_VALUE %stack.0.x.addr, $noreg, !11, !DIExpression(), debug-location !12
MOV32mi $rip, 1, $noreg, @global, $noreg, 1, debug-location !12 :: (store 4 into @global)
DBG_VALUE %stack.0.x.addr, $noreg, !11, !DIExpression(DW_OP_deref), debug-location !12
MOV32mi %stack.0.x.addr, 1, $noreg, 0, $noreg, 2, debug-location !12 :: (store 4 into %ir.x.addr)
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !12
$rdi = COPY %1, debug-location !12
CALL64pcrel32 @escape, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, debug-location !12
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !12
RET 0, debug-location !12
...
---
name: f2
tracksRegLiveness: true
stack:
- { id: 0, name: x.addr, type: default, offset: 0, size: 4, alignment: 4,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
body: |
bb.0.entry:
liveins: $edi
%0:gr32 = COPY $edi
MOV32mr %stack.0.x.addr, 1, $noreg, 0, $noreg, %0 :: (store 4 into %ir.x.addr)
DBG_VALUE %stack.0.x.addr, $noreg, !14, !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 16), debug-location !15
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
%1:gr64 = LEA64r %stack.0.x.addr, 1, $noreg, 0, $noreg
$rdi = COPY %1
CALL64pcrel32 @escape, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
DBG_VALUE %stack.0.x.addr, $noreg, !14, !DIExpression(DW_OP_LLVM_fragment, 16, 16), debug-location !15
MOV32mi $rip, 1, $noreg, @global, $noreg, 1 :: (store 4 into @global)
DBG_VALUE %stack.0.x.addr, $noreg, !14, !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 16), debug-location !15
MOV32mi %stack.0.x.addr, 1, $noreg, 0, $noreg, 2 :: (store 4 into %ir.x.addr)
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
$rdi = COPY %1
CALL64pcrel32 @escape, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
RET 0
...