mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
308759bb3b
This patch adds support for DBG_VALUE_LIST in the LiveDebugVariables pass. The changes are mostly in computeIntervals, extendDef, and addDefsFromCopies; when extending the def of a DBG_VALUE_LIST the live ranges of every used register must be considered, and when such a def is killed by more than one of its used registers being killed at the same time it is necessary to find valid copies of all of those registers to create a new def with. The DebugVariableValue class has also been changed to reference multiple location numbers instead of just one. This has been accomplished by using a C-style array with a unique_ptr and an array length packed into 6 bits, to minimize the size of the class (which must be kept low to be used with IntervalMap). This may not be the most efficient solution possible, and should be looked at if performance issues arise. Differential Revision: https://reviews.llvm.org/D83895
114 lines
5.8 KiB
YAML
114 lines
5.8 KiB
YAML
# RUN: llc -start-after=phi-node-elimination -stop-after=virtregrewriter %s -mtriple=x86_64-unknown-unknown -o - | FileCheck %s
|
|
#
|
|
# This is a copy of the adjacent "-movements.mir" file, but where one of the
|
|
# operands to DBG_VALUE_LIST is a stack _pointer_ rather than a spilt value.
|
|
# The expression should grow no additional derefs for the stack pointer.
|
|
#
|
|
# CHECK-LABEL: bb.0.entry:
|
|
# CHECK: $rbx = COPY $rsi
|
|
# CHECK-NEXT: MOV64mr %stack.1, 1, $noreg, 0, $noreg, $rdi
|
|
# CHECK-NEXT: DBG_VALUE_LIST !14, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref, DW_OP_LLVM_arg, 1, DW_OP_plus), %stack.1, %stack.0.local1
|
|
# CHECK-NEXT: INLINEASM
|
|
# CHECK-NEXT: $rax = MOV64rm %stack.1,
|
|
# CHECK-NEXT: DBG_VALUE_LIST !14, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), $rax, %stack.0.local1,
|
|
# CHECK-NEXT: CALL64pcrel32 @foo
|
|
# CHECK-NEXT: DBG_VALUE_LIST !14, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref, DW_OP_LLVM_arg, 1, DW_OP_plus), %stack.1, %stack.0.local1,
|
|
# CHECK-NEXT: $rcx = COPY killed renamable $rbx
|
|
# CHECK-NEXT: INLINEASM
|
|
# CHECK-NEXT: $rax = MOV64rm %stack.1
|
|
# CHECK-NEXT: DBG_VALUE_LIST !14, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), $rax, %stack.0.local1,
|
|
|
|
--- |
|
|
; ModuleID = 'tmp.ll'
|
|
source_filename = "tmp.ll"
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
%struct.a = type { i32 }
|
|
|
|
; Function Attrs: nounwind ssp
|
|
define i32 @bar(%struct.a* nocapture %b, i32 %shoes) !dbg !4 {
|
|
entry:
|
|
%local1 = alloca i64
|
|
tail call void @llvm.dbg.value(metadata i32 %shoes, metadata !9, metadata !DIExpression()), !dbg !16
|
|
%tmp1 = getelementptr inbounds %struct.a, %struct.a* %b, i64 0, i32 0, !dbg !17
|
|
br label %bb3
|
|
|
|
bb1: ; preds = %bb2
|
|
tail call void @llvm.dbg.value(metadata i32 %shoes, metadata !9, metadata !DIExpression()), !dbg !16
|
|
%add = add nsw i32 %tmp2, 1, !dbg !18
|
|
br label %exit
|
|
|
|
bb2: ; preds = %bb3
|
|
tail call void @llvm.dbg.value(metadata i32 %tmp2, metadata !14, metadata !DIExpression()), !dbg !17
|
|
%call = tail call i32 (...) @foo(i32 %tmp2), !dbg !19
|
|
br label %bb1
|
|
|
|
bb3: ; preds = %entry
|
|
%tmp2 = load i32, i32* %tmp1, align 4, !dbg !17
|
|
br label %bb2
|
|
|
|
exit: ; preds = %bb1
|
|
ret i32 %shoes, !dbg !18
|
|
}
|
|
|
|
declare i32 @foo(...)
|
|
|
|
; Function Attrs: nounwind readnone speculatable willreturn
|
|
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
|
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
|
|
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 2.9 (trunk 122997)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2)
|
|
!1 = !DIFile(filename: "bar.c", directory: "/private/tmp")
|
|
!2 = !{}
|
|
!3 = !{i32 1, !"Debug Info Version", i32 3}
|
|
!4 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !5, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
|
|
!5 = !DISubroutineType(types: !6)
|
|
!6 = !{!7}
|
|
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
|
!8 = !{!9, !14}
|
|
!9 = !DILocalVariable(name: "b", arg: 1, scope: !4, file: !1, line: 5, type: !10)
|
|
!10 = !DIDerivedType(tag: DW_TAG_pointer_type, scope: !0, baseType: !11, size: 64, align: 64)
|
|
!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "a", scope: !0, file: !1, line: 1, size: 32, align: 32, elements: !12)
|
|
!12 = !{!13}
|
|
!13 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !1, file: !1, line: 2, baseType: !7, size: 32, align: 32)
|
|
!14 = !DILocalVariable(name: "x", scope: !15, file: !1, line: 6, type: !7)
|
|
!15 = distinct !DILexicalBlock(scope: !4, file: !1, line: 5, column: 22)
|
|
!16 = !DILocation(line: 5, column: 19, scope: !4)
|
|
!17 = !DILocation(line: 6, column: 14, scope: !15)
|
|
!18 = !DILocation(line: 8, column: 2, scope: !15)
|
|
!19 = !DILocation(line: 7, column: 2, scope: !15)
|
|
|
|
...
|
|
---
|
|
name: bar
|
|
tracksRegLiveness: true
|
|
stack:
|
|
- { id: 0, name: local1, type: default, offset: -24, size: 8, alignment: 8,
|
|
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
|
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: $rdi, $rsi
|
|
|
|
%4:gr64= COPY $rsi
|
|
%2:gr64 = COPY $rdi
|
|
DBG_VALUE_LIST !14, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), %2, %stack.0, debug-location !17
|
|
%3:gr64 = COPY killed %2
|
|
%5:gr64 = COPY killed %4
|
|
|
|
; Force allocation into $rax and $rbx
|
|
INLINEASM &"", 1, 12, implicit-def dead $rcx, 12, implicit-def dead $rdx, 12, implicit-def dead $rsi, 12, implicit-def dead $rdi, 12, implicit-def $rbp, 12, implicit-def dead $r8, 12, implicit-def dead $r9, 12, implicit-def dead $r10, 12, implicit-def dead $r11, 12, implicit-def dead $r12, 12, implicit-def dead $r13, 12, implicit-def dead $r14, 12, implicit-def dead $r15, 12, !18, debug-location !17
|
|
|
|
; Force a use of these two registers.
|
|
CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit %3, implicit %5
|
|
|
|
; Now make the register allocator move them to rcx and rdx!
|
|
INLINEASM &"", 1, 12, implicit-def dead $rax, 12, implicit-def dead $rbx, 12, implicit-def dead $rsi, 12, implicit-def dead $rdi, 12, implicit-def $rbp, 12, implicit-def dead $r8, 12, implicit-def dead $r9, 12, implicit-def dead $r10, 12, implicit-def dead $r11, 12, implicit-def dead $r12, 12, implicit-def dead $r13, 12, implicit-def dead $r14, 12, implicit-def dead $r15, 12, !18, debug-location !17
|
|
|
|
CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit %3, implicit %5
|
|
|
|
RETQ
|
|
...
|