-
Notifications
You must be signed in to change notification settings - Fork 11.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DebugInfo][InstrRef] Track values fused into stack spills
During register allocation, some instructions can have stack spills fused into them. It means that when vregs are allocated on the stack we can convert: SETCCr %0 DBG_VALUE %0 to SETCCm %stack.0 DBG_VALUE %stack.0 Unfortunately instruction referencing finds this harder: a store to the stack doesn't have a specific operand number, therefore we don't substitute the old operand for a new operand, and the location is dropped. This patch implements a solution: just recognise the memory operand attached to an instruction with a Special Number (TM), and record a substitution between the old value and the new one. This patch adds substitution code to InlineSpiller to record such fused spills, and tracking in InstrRefBasedLDV to recognise such values, and produce the value numbers for them. Everything to do with the movement of stack-defined values is already handled in InstrRefBasedLDV. Differential Revision: https://reviews.llvm.org/D111317
- Loading branch information
Showing
9 changed files
with
778 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
llvm/test/DebugInfo/MIR/InstrRef/memory-operand-folding-tieddef.mir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
# RUN: llc %s -o - -experimental-debug-variable-locations \ | ||
# RUN: -start-before=x86-flags-copy-lowering -stop-after=virtregrewriter \ | ||
# RUN: | FileCheck %s | ||
# | ||
# This test is for stack spill folding -- the INC32r near the end of the MIR | ||
# below show be morphed into an INC32m by the register allocator, making it | ||
# load-operate-store to %stack.0. We should track this fact in the substitution | ||
# table, by adding a substitution to the memory-operand operand number. | ||
# | ||
# The INC32r is a tied-def instruction. | ||
# | ||
# NB: This test would more ideally start at phi-node-elimination, where | ||
# register allocation begins, however for some reason the INC32r gets | ||
# transformed into a different instruction if we do that. Start at the last | ||
# optimisation pass before regalloc instead. | ||
# | ||
# CHECK: debugValueSubstitutions: | ||
# CHECK-NEXT: - { srcinst: 1, srcop: 0, dstinst: 2, dstop: 1000000, subreg: 0 } | ||
# CHECK-LABEL: bb.5: | ||
# CHECK: INC32m %stack.0, {{.*}} debug-instr-number 2, | ||
--- | | ||
; ModuleID = 'reduced.ll' | ||
source_filename = "reduced.ll" | ||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" | ||
|
||
%"class.llvm::APInt" = type { i32, %union.anon } | ||
%union.anon = type { i64 } | ||
|
||
define void @_ZNK4llvm5APInt5magicEv() local_unnamed_addr align 2 !dbg !7 { | ||
ret void | ||
} | ||
|
||
!llvm.dbg.cu = !{!0} | ||
!llvm.module.flags = !{!3, !4, !5} | ||
!llvm.ident = !{!6} | ||
|
||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) | ||
!1 = !DIFile(filename: "test.c", directory: ".") | ||
!2 = !{} | ||
!3 = !{i32 7, !"Dwarf Version", i32 4} | ||
!4 = !{i32 2, !"Debug Info Version", i32 3} | ||
!5 = !{i32 1, !"wchar_size", i32 4} | ||
!6 = !{!"clang"} | ||
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) | ||
!8 = !DISubroutineType(types: !9) | ||
!9 = !{!10, !11, !11} | ||
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) | ||
!11 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) | ||
!12 = !DILocalVariable(name: "bar", arg: 1, scope: !7, file: !1, line: 3, type: !11) | ||
!13 = !DILocation(line: 0, scope: !7) | ||
!14 = !DILocalVariable(name: "baz", arg: 2, scope: !7, file: !1, line: 3, type: !11) | ||
!15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 8, column: 7) | ||
|
||
... | ||
--- | ||
name: _ZNK4llvm5APInt5magicEv | ||
alignment: 16 | ||
tracksRegLiveness: true | ||
registers: | ||
- { id: 0, class: gr64 } | ||
- { id: 1, class: gr32 } | ||
- { id: 2, class: gr64 } | ||
- { id: 3, class: gr32 } | ||
- { id: 4, class: gr64 } | ||
- { id: 5, class: gr32 } | ||
- { id: 6, class: gr32 } | ||
- { id: 7, class: gr32 } | ||
- { id: 8, class: gr64 } | ||
- { id: 9, class: gr32 } | ||
- { id: 10, class: gr64 } | ||
- { id: 11, class: gr32 } | ||
- { id: 12, class: gr64 } | ||
- { id: 13, class: gr32 } | ||
- { id: 14, class: gr64 } | ||
- { id: 15, class: gr32 } | ||
- { id: 16, class: gr64 } | ||
- { id: 17, class: gr64 } | ||
- { id: 18, class: gr64 } | ||
- { id: 19, class: gr32 } | ||
- { id: 20, class: gr8 } | ||
- { id: 21, class: gr32 } | ||
- { id: 22, class: gr64 } | ||
- { id: 23, class: gr64 } | ||
- { id: 24, class: gr64 } | ||
- { id: 25, class: gr64 } | ||
- { id: 26, class: gr64 } | ||
- { id: 27, class: gr32 } | ||
- { id: 28, class: gr8 } | ||
- { id: 29, class: gr64 } | ||
- { id: 30, class: gr64 } | ||
- { id: 31, class: gr64 } | ||
- { id: 32, class: gr64 } | ||
- { id: 33, class: gr64 } | ||
- { id: 34, class: gr64 } | ||
- { id: 35, class: gr64 } | ||
- { id: 36, class: gr64 } | ||
- { id: 37, class: gr64 } | ||
- { id: 38, class: gr8 } | ||
frameInfo: | ||
maxAlignment: 1 | ||
hasCalls: true | ||
machineFunctionInfo: {} | ||
body: | | ||
bb.0: | ||
%15:gr32 = IMPLICIT_DEF | ||
%14:gr64 = IMPLICIT_DEF | ||
%17:gr64 = IMPLICIT_DEF | ||
%18:gr64 = IMPLICIT_DEF | ||
%19:gr32 = MOV32r0 implicit-def dead $eflags | ||
%22:gr64 = IMPLICIT_DEF | ||
%23:gr64 = IMPLICIT_DEF | ||
%24:gr64 = IMPLICIT_DEF | ||
%25:gr64 = IMPLICIT_DEF | ||
%26:gr64 = IMPLICIT_DEF | ||
%30:gr64 = IMPLICIT_DEF | ||
%31:gr64 = IMPLICIT_DEF | ||
%32:gr64 = IMPLICIT_DEF | ||
%33:gr64 = IMPLICIT_DEF | ||
%34:gr64 = IMPLICIT_DEF | ||
%35:gr64 = IMPLICIT_DEF | ||
%36:gr64 = IMPLICIT_DEF | ||
%37:gr64 = IMPLICIT_DEF | ||
%21:gr32 = IMPLICIT_DEF | ||
bb.1: | ||
%0:gr64 = PHI %14, %bb.0, %12, %bb.5 | ||
%1:gr32 = PHI %15, %bb.0, %11, %bb.5 | ||
%2:gr64 = PHI %14, %bb.0, %10, %bb.5 | ||
%3:gr32 = PHI %15, %bb.0, %9, %bb.5 | ||
%4:gr64 = PHI %14, %bb.0, %8, %bb.5 | ||
%5:gr32 = PHI %15, %bb.0, %7, %bb.5, debug-location !13 | ||
%6:gr32 = PHI %15, %bb.0, %13, %bb.5, debug-location !13 | ||
%16:gr64 = ADD64rr %4, %4, implicit-def dead $eflags, debug-location !13 | ||
MOV32mr %17, 1, $noreg, 0, $noreg, %5, debug-location !13 :: (store (s32) into `i32* undef`, align 8) | ||
MOV64mr %18, 1, $noreg, 0, $noreg, killed %16, debug-location !13 :: (store (s64) into `i64* undef`) | ||
%20:gr8 = COPY %19.sub_8bit | ||
TEST8rr %20, %20, implicit-def $eflags, debug-location !13 | ||
JCC_1 %bb.3, 5, implicit $eflags, debug-location !13 | ||
JMP_1 %bb.2, debug-location !13 | ||
bb.2: | ||
bb.3: | ||
successors: %bb.4, %bb.5 | ||
%7:gr32 = PHI %5, %bb.1, %21, %bb.2, debug-location !13 | ||
MOV32mr %22, 1, $noreg, 0, $noreg, %7, debug-location !13 :: (store (s32) into `i32* undef`, align 8) | ||
%8:gr64 = MOV64rm %23, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s64) from `i64* undef`) | ||
MOV32mr %24, 1, $noreg, 0, $noreg, %3, debug-location !13 :: (store (s32) into `i32* undef`, align 8) | ||
MOV64mi32 %25, 1, $noreg, 0, $noreg, 0, debug-location !13 :: (store (s64) into `i64* undef`) | ||
%28:gr8 = COPY %19.sub_8bit | ||
TEST8rr %28, %28, implicit-def $eflags, debug-location !13 | ||
JCC_1 %bb.5, 5, implicit $eflags, debug-location !13 | ||
JMP_1 %bb.4, debug-location !13 | ||
bb.4: | ||
%29:gr64 = ADD64rr %2, %2, implicit-def dead $eflags, debug-location !13 | ||
MOV64mr %30, 1, $noreg, 0, $noreg, killed %29, debug-location !13 :: (store (s64) into `i64* undef`) | ||
bb.5: | ||
%9:gr32 = MOV32rm %26, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s32) from `i32* undef`, align 8) | ||
%10:gr64 = MOV64rm %31, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s64) from `i64* undef`) | ||
%12:gr64 = ADD64rr %0, %0, implicit-def dead $eflags, debug-location !13 | ||
MOV32mr %32, 1, $noreg, 0, $noreg, %1, debug-location !13 :: (store (s32) into `i32* undef`, align 8) | ||
MOV64mr %33, 1, $noreg, 0, $noreg, %12, debug-location !13 :: (store (s64) into `i64* undef`) | ||
%11:gr32 = MOV32rm %34, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s32) from `i32* undef`, align 8) | ||
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !13 | ||
$rdi = COPY %35, debug-location !13 | ||
$rsi = COPY %36, debug-location !13 | ||
CALL64r %37, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp, implicit-def $al, debug-location !13 | ||
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !13 | ||
%13:gr32 = INC32r %6, implicit-def dead $eflags, debug-instr-number 1, debug-location !13 | ||
DBG_INSTR_REF 1, 0, !12, !DIExpression(), debug-location !13 | ||
JMP_1 %bb.1, debug-location !13 | ||
... |
Oops, something went wrong.