
RAGreedy invokes InlineSpiller to spill a particular virtreg inline. When the spiller does this, it also identifies small, adjacent liveranges called snippets. These are also spilled or rematerialized in the process. However, the spiller does not inform RA that it has spilled these regs. This means that debug variable locations referencing these regs/ranges are lost. Mark any spilled regs which do not have a stack slot assigned to them as allocated to the slot being spilled to to tell LDV that those regs are located in that slot, even though the regs might no longer exist in the program after regalloc is finished. Also, inform RA about all of the regs which were replaced (spilled or rematted), not just the one that was requested so that it can properly manage the ranges of the debug vars.
101 lines
4.5 KiB
YAML
101 lines
4.5 KiB
YAML
# RUN: llc -mtriple i386 -start-before=greedy -stop-after=livedebugvars %s -o - | FileCheck %s
|
|
|
|
# There should be multiple debug values for this variable after regalloc. The
|
|
# value has been spilled, but we shouldn't lose track of the location because
|
|
# of this.
|
|
|
|
# CHECK-COUNT-4: DBG_VALUE $ebp, 0, !6, !DIExpression(DW_OP_constu, 16, DW_OP_minus), debug-location !10
|
|
|
|
--- |
|
|
|
|
define void @main() #0 !dbg !4 {
|
|
entry:
|
|
#dbg_value(i32 undef, !6, !DIExpression(), !10)
|
|
ret void
|
|
}
|
|
|
|
attributes #0 = { "frame-pointer"="all" }
|
|
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
|
|
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 20.0.0git.prerel", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2, splitDebugInlining: false, nameTableKind: None)
|
|
!1 = !DIFile(filename: "xx.c", directory: "/path", checksumkind: CSK_MD5, checksum: "c4b2fc62bca9171ad484c91fb78b8842")
|
|
!2 = !{}
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 20, type: !5, scopeLine: 20, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
!5 = !DISubroutineType(types: !2)
|
|
!6 = !DILocalVariable(name: "flag", arg: 2, scope: !7, file: !1, line: 8, type: !9)
|
|
!7 = distinct !DISubprogram(name: "transparent_crc", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
!8 = distinct !DISubroutineType(types: !2)
|
|
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!10 = !DILocation(line: 0, scope: !7, inlinedAt: !11)
|
|
!11 = distinct !DILocation(line: 28, column: 3, scope: !4)
|
|
|
|
...
|
|
---
|
|
name: main
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
hasWinCFI: false
|
|
noPhis: true
|
|
fixedStack:
|
|
- { id: 0, type: default, offset: 0, size: 4, alignment: 4, stack-id: default,
|
|
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
|
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
|
- { id: 1, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
|
|
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
|
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
|
- { id: 2, type: default, offset: 8, size: 1, alignment: 4, stack-id: default,
|
|
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
|
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
|
- { id: 3, type: default, offset: 12, size: 4, alignment: 4, stack-id: default,
|
|
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
|
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
|
body: |
|
|
bb.0:
|
|
successors: %bb.2(0x80000000)
|
|
|
|
%0:gr32 = MOV32rm %fixed-stack.3, 1, $noreg, 0, $noreg :: (load (s32) from %fixed-stack.3)
|
|
%1:gr8 = MOV8rm %fixed-stack.2, 1, $noreg, 0, $noreg :: (load (s8) from %fixed-stack.2, align 4)
|
|
%2:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %fixed-stack.0)
|
|
%3:gr32_abcd = MOV32r0 implicit-def dead $eflags
|
|
TEST32rr %2, %2, implicit-def $eflags
|
|
%3.sub_8bit:gr32_abcd = SETCCr 5, implicit $eflags
|
|
%4:gr32 = COPY %2
|
|
%4:gr32 = SAR32ri %4, 1, implicit-def dead $eflags
|
|
%5:gr32 = MOV32rm %fixed-stack.1, 1, $noreg, 0, $noreg :: (load (s32) from %fixed-stack.1)
|
|
%6:gr32 = MOV32r0 implicit-def dead $eflags
|
|
JMP_1 %bb.2
|
|
|
|
bb.1:
|
|
successors: %bb.4(0x30000000), %bb.3(0x50000000)
|
|
|
|
DBG_VALUE %3, $noreg, !6, !DIExpression(), debug-location !10
|
|
TEST32rr %3, %3, implicit-def $eflags
|
|
JCC_1 %bb.4, 4, implicit $eflags
|
|
JMP_1 %bb.3
|
|
|
|
bb.2:
|
|
successors: %bb.1(0x04000000), %bb.2(0x7c000000)
|
|
|
|
%6:gr32 = XOR32rr %6, %0, implicit-def dead $eflags
|
|
%6:gr32 = SAR32ri %6, 2, implicit-def dead $eflags
|
|
%6:gr32 = XOR32rr %6, %4, implicit-def dead $eflags
|
|
%6:gr32 = XOR32rr %6, %5, implicit-def dead $eflags
|
|
%6:gr32 = XOR32rr %6, %2, implicit-def dead $eflags
|
|
TEST8ri %1, 1, implicit-def $eflags
|
|
JCC_1 %bb.1, 5, implicit $eflags
|
|
JMP_1 %bb.2
|
|
|
|
bb.3:
|
|
successors: %bb.4(0x80000000)
|
|
|
|
MOV32mi $noreg, 1, $noreg, 4, $noreg, 0 :: (store (s32) into `ptr null` + 4)
|
|
MOV32mi $noreg, 1, $noreg, 0, $noreg, 0 :: (store (s32) into `ptr null`)
|
|
|
|
bb.4:
|
|
RET 0
|
|
|
|
...
|