forked from OSchip/llvm-project
Resubmit r301309: [DebugInfo][X86] Fix handling of DBG_VALUE's in post-RA scheduler.
This patch reapplies r301309 with the fix to the MIR test to fix the assertion triggered by r301309. Had trimmed a little bit too much from the MIR! llvm-svn: 301317
This commit is contained in:
parent
ba01143193
commit
10ebfe0684
|
@ -964,10 +964,8 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
|||
// sure to update that as well.
|
||||
const SUnit *SU = MISUnitMap[Q.second.Operand->getParent()];
|
||||
if (!SU) continue;
|
||||
for (DbgValueVector::iterator DVI = DbgValues.begin(),
|
||||
DVE = DbgValues.end(); DVI != DVE; ++DVI)
|
||||
if (DVI->second == Q.second.Operand->getParent())
|
||||
UpdateDbgValue(*DVI->first, AntiDepReg, NewReg);
|
||||
UpdateDbgValues(DbgValues, Q.second.Operand->getParent(),
|
||||
AntiDepReg, NewReg);
|
||||
}
|
||||
|
||||
// We just went back in time and modified history; the
|
||||
|
|
|
@ -60,6 +60,25 @@ public:
|
|||
if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == OldReg)
|
||||
MI.getOperand(0).setReg(NewReg);
|
||||
}
|
||||
|
||||
/// Update all DBG_VALUE instructions that may be affected by the dependency
|
||||
/// breaker's update of ParentMI to use NewReg.
|
||||
void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI,
|
||||
unsigned OldReg, unsigned NewReg) {
|
||||
// The following code is dependent on the order in which the DbgValues are
|
||||
// constructed in ScheduleDAGInstrs::buildSchedGraph.
|
||||
MachineInstr *PrevDbgMI = nullptr;
|
||||
for (const auto &DV : make_range(DbgValues.crbegin(), DbgValues.crend())) {
|
||||
MachineInstr *PrevMI = DV.second;
|
||||
if ((PrevMI == ParentMI) || (PrevMI == PrevDbgMI)) {
|
||||
MachineInstr *DbgMI = DV.first;
|
||||
UpdateDbgValue(*DbgMI, OldReg, NewReg);
|
||||
PrevDbgMI = DbgMI;
|
||||
} else if (PrevDbgMI) {
|
||||
break; // If no match and already found a DBG_VALUE, we're done.
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -648,10 +648,8 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits,
|
|||
// as well.
|
||||
const SUnit *SU = MISUnitMap[Q->second->getParent()];
|
||||
if (!SU) continue;
|
||||
for (DbgValueVector::iterator DVI = DbgValues.begin(),
|
||||
DVE = DbgValues.end(); DVI != DVE; ++DVI)
|
||||
if (DVI->second == Q->second->getParent())
|
||||
UpdateDbgValue(*DVI->first, AntiDepReg, NewReg);
|
||||
UpdateDbgValues(DbgValues, Q->second->getParent(),
|
||||
AntiDepReg, NewReg);
|
||||
}
|
||||
|
||||
// We just went back in time and modified history; the
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
# RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=btver2 -run-pass=post-RA-sched -o - %s | FileCheck %s
|
||||
|
||||
# Test that multiple DBG_VALUE's following an instruction whose register needs
|
||||
# to be changed during the post-RA scheduler pass are updated correctly.
|
||||
|
||||
# Test case was derived from the output from the following command and
|
||||
# the source code below:
|
||||
#
|
||||
# clang -S -emit-llvm -target x86_64 -march=btver2 -O2 -g -o - <srcfile> |
|
||||
# llc -stop-before=post-RA-sched -o -
|
||||
#
|
||||
# Source code reduced from the original 8MB source file:
|
||||
#
|
||||
# struct a;
|
||||
# class b {
|
||||
# public:
|
||||
# a *c = ap;
|
||||
# unsigned *d() { return (unsigned *)c; }
|
||||
# a *ap;
|
||||
# };
|
||||
# enum { e = 2 };
|
||||
# template <typename f> f *g(f *h, f *i) {
|
||||
# long j = long(i), k = -!h;
|
||||
# return reinterpret_cast<f *>(long(h) | k & j);
|
||||
# }
|
||||
# class l {
|
||||
# public:
|
||||
# l(int);
|
||||
# int m;
|
||||
# };
|
||||
# unsigned *n;
|
||||
# unsigned o;
|
||||
# class p {
|
||||
# public:
|
||||
# int aa();
|
||||
# unsigned *q() {
|
||||
# n = r.d();
|
||||
# return g(n, &o);
|
||||
# }
|
||||
# b r;
|
||||
# };
|
||||
# class s : l {
|
||||
# public:
|
||||
# p t;
|
||||
# s(int h) : l(h), ab(t), ac(~0 << h) { ae(); }
|
||||
# p &ab;
|
||||
# int ac;
|
||||
# void ae() {
|
||||
# const unsigned *v;
|
||||
# const unsigned u = 0;
|
||||
# v = ab.q();
|
||||
# const unsigned *x = g(v, &u);
|
||||
# int w = x[m] & ac;
|
||||
# while (w) {
|
||||
# int z = (ab.aa() - 1) / e;
|
||||
# if (m <= z)
|
||||
# return;
|
||||
# }
|
||||
# }
|
||||
# };
|
||||
# class ad {
|
||||
# public:
|
||||
# ~ad() {
|
||||
# for (y();;)
|
||||
# ;
|
||||
# }
|
||||
# class y {
|
||||
# public:
|
||||
# y() : af(0) {}
|
||||
# s af;
|
||||
# };
|
||||
# };
|
||||
# class ag {
|
||||
# ad ah;
|
||||
# };
|
||||
# enum ai {};
|
||||
# class aj {
|
||||
# public:
|
||||
# aj(unsigned(ai));
|
||||
# ag ak;
|
||||
# };
|
||||
# struct al {
|
||||
# static unsigned am(ai);
|
||||
# };
|
||||
# template <int> struct an : al { static aj ao; };
|
||||
# template <> aj an<0>::ao(am);
|
||||
|
||||
--- |
|
||||
|
||||
%class.s = type <{ %class.l, [4 x i8], %class.p, %class.p*, i32, [4 x i8] }>
|
||||
%class.l = type { i32 }
|
||||
%class.p = type { %class.b }
|
||||
%class.b = type { %struct.a*, %struct.a* }
|
||||
%struct.a = type opaque
|
||||
|
||||
@n = local_unnamed_addr global i32* null, align 8
|
||||
@o = global i32 0, align 4
|
||||
|
||||
define linkonce_odr void @_ZN1sC2Ei(%class.s*, i32) unnamed_addr #0 align 2 !dbg !4 {
|
||||
%3 = alloca i32, align 4
|
||||
%4 = bitcast %class.s* %0 to %class.l*
|
||||
tail call void @_ZN1lC2Ei(%class.l* %4, i32 %1)
|
||||
%5 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 2
|
||||
tail call void @llvm.dbg.value(metadata %class.p* %5, i64 0, metadata !10, metadata !17), !dbg !18
|
||||
tail call void @llvm.dbg.value(metadata %class.p* %5, i64 0, metadata !20, metadata !17), !dbg !27
|
||||
%6 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 2, i32 0, i32 1
|
||||
%7 = bitcast %struct.a** %6 to i64*
|
||||
%8 = load i64, i64* %7, align 8
|
||||
%9 = bitcast %class.p* %5 to i64*
|
||||
store i64 %8, i64* %9, align 8
|
||||
%10 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 3
|
||||
store %class.p* %5, %class.p** %10, align 8
|
||||
%11 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 4
|
||||
%12 = shl i32 -1, %1
|
||||
store i32 %12, i32* %11, align 8
|
||||
store i32 0, i32* %3, align 4
|
||||
%13 = bitcast %class.p* %5 to i32**
|
||||
%14 = load i32*, i32** %13, align 8
|
||||
store i32* %14, i32** @n, align 8
|
||||
%15 = icmp eq i32* %14, null
|
||||
%16 = ptrtoint i32* %14 to i64
|
||||
%17 = select i1 %15, i64 ptrtoint (i32* @o to i64), i64 0
|
||||
%18 = or i64 %17, %16
|
||||
tail call void @llvm.dbg.value(metadata i32* %3, i64 0, metadata !29, metadata !35), !dbg !36
|
||||
tail call void @llvm.dbg.value(metadata i32* %3, i64 0, metadata !39, metadata !17), !dbg !44
|
||||
%19 = ptrtoint i32* %3 to i64
|
||||
call void @llvm.dbg.value(metadata i64 %19, i64 0, metadata !46, metadata !17), !dbg !48
|
||||
%20 = icmp eq i64 %18, 0
|
||||
%21 = select i1 %20, i64 %19, i64 0
|
||||
%22 = or i64 %21, %18
|
||||
%23 = inttoptr i64 %22 to i32*
|
||||
%24 = bitcast %class.s* %0 to i32*
|
||||
%25 = load i32, i32* %24, align 8
|
||||
%26 = sext i32 %25 to i64
|
||||
%27 = getelementptr inbounds i32, i32* %23, i64 %26
|
||||
%28 = load i32, i32* %27, align 4
|
||||
%29 = and i32 %12, %28
|
||||
%30 = icmp eq i32 %29, 0
|
||||
br i1 %30, label %47, label %31
|
||||
|
||||
; <label>:31: ; preds = %2
|
||||
%32 = bitcast %class.s* %0 to i32*
|
||||
%33 = call i32 @_ZN1p2aaEv(%class.p* %5)
|
||||
%34 = add nsw i32 %33, -1
|
||||
%35 = sdiv i32 %34, 2
|
||||
%36 = load i32, i32* %32, align 8
|
||||
%37 = icmp sgt i32 %36, %35
|
||||
br i1 %37, label %38, label %47
|
||||
|
||||
; <label>:38: ; preds = %31
|
||||
br label %39
|
||||
|
||||
; <label>:39: ; preds = %39, %38
|
||||
%40 = bitcast %class.s* %0 to i32*
|
||||
%sunkaddr = ptrtoint %class.s* %0 to i64
|
||||
%sunkaddr1 = add i64 %sunkaddr, 24
|
||||
%sunkaddr2 = inttoptr i64 %sunkaddr1 to %class.p**
|
||||
%41 = load %class.p*, %class.p** %sunkaddr2, align 8
|
||||
%42 = call i32 @_ZN1p2aaEv(%class.p* %41)
|
||||
%43 = add nsw i32 %42, -1
|
||||
%44 = sdiv i32 %43, 2
|
||||
%45 = load i32, i32* %40, align 8
|
||||
%46 = icmp sgt i32 %45, %44
|
||||
br i1 %46, label %39, label %47
|
||||
|
||||
; <label>:47: ; preds = %39, %31, %2
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @_ZN1lC2Ei(%class.l*, i32) unnamed_addr #1
|
||||
|
||||
declare i32 @_ZN1p2aaEv(%class.p*) local_unnamed_addr #1
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!2, !3}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
!1 = !DIFile(filename: "test.cpp", directory: "")
|
||||
!2 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!4 = distinct !DISubprogram(name: "s", linkageName: "_ZN1sC2Ei", scope: !5, file: !1, line: 32, type: !6, isLocal: false, isDefinition: true, scopeLine: 32, flags: DIFlagPrototyped, isOptimized: true, unit: !0)
|
||||
!5 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "s", file: !1, line: 29, size: 320, identifier: "_ZTS1s")
|
||||
!6 = !DISubroutineType(types: !7)
|
||||
!7 = !{null, !8, !9}
|
||||
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
|
||||
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!10 = !DILocalVariable(name: "this", arg: 1, scope: !11, type: !16, flags: DIFlagArtificial | DIFlagObjectPointer)
|
||||
!11 = distinct !DISubprogram(name: "p", linkageName: "_ZN1pC2Ev", scope: !12, file: !1, line: 20, type: !13, isLocal: false, isDefinition: true, scopeLine: 20, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: true, unit: !0)
|
||||
!12 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "p", file: !1, line: 20, size: 128, identifier: "_ZTS1p")
|
||||
!13 = !DISubroutineType(types: !14)
|
||||
!14 = !{null, !15}
|
||||
!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
|
||||
!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
|
||||
!17 = !DIExpression()
|
||||
!18 = !DILocation(line: 0, scope: !11, inlinedAt: !19)
|
||||
!19 = distinct !DILocation(line: 32, column: 3, scope: !4)
|
||||
!20 = !DILocalVariable(name: "this", arg: 1, scope: !21, type: !26, flags: DIFlagArtificial | DIFlagObjectPointer)
|
||||
!21 = distinct !DISubprogram(name: "b", linkageName: "_ZN1bC2Ev", scope: !22, file: !1, line: 2, type: !23, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: true, unit: !0)
|
||||
!22 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "b", file: !1, line: 2, size: 128, identifier: "_ZTS1b")
|
||||
!23 = !DISubroutineType(types: !24)
|
||||
!24 = !{null, !25}
|
||||
!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
|
||||
!26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64)
|
||||
!27 = !DILocation(line: 0, scope: !21, inlinedAt: !28)
|
||||
!28 = distinct !DILocation(line: 20, column: 7, scope: !11, inlinedAt: !19)
|
||||
!29 = !DILocalVariable(name: "u", scope: !30, file: !1, line: 37, type: !33)
|
||||
!30 = distinct !DISubprogram(name: "ae", linkageName: "_ZN1s2aeEv", scope: !5, file: !1, line: 35, type: !31, isLocal: false, isDefinition: true, scopeLine: 35, flags: DIFlagPrototyped, isOptimized: true, unit: !0)
|
||||
!31 = !DISubroutineType(types: !32)
|
||||
!32 = !{null, !8}
|
||||
!33 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !34)
|
||||
!34 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
|
||||
!35 = !DIExpression(DW_OP_deref)
|
||||
!36 = !DILocation(line: 37, column: 20, scope: !30, inlinedAt: !37)
|
||||
!37 = distinct !DILocation(line: 32, column: 41, scope: !38)
|
||||
!38 = distinct !DILexicalBlock(scope: !4, file: !1, line: 32, column: 39)
|
||||
!39 = !DILocalVariable(name: "i", arg: 2, scope: !40, file: !1, line: 9, type: !43)
|
||||
!40 = distinct !DISubprogram(name: "g<const unsigned int>", linkageName: "_Z1gIKjEPT_S2_S2_", scope: !1, file: !1, line: 9, type: !41, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !0)
|
||||
!41 = !DISubroutineType(types: !42)
|
||||
!42 = !{!43, !43, !43}
|
||||
!43 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !33, size: 64)
|
||||
!44 = !DILocation(line: 9, column: 37, scope: !40, inlinedAt: !45)
|
||||
!45 = distinct !DILocation(line: 39, column: 25, scope: !30, inlinedAt: !37)
|
||||
!46 = !DILocalVariable(name: "j", scope: !40, file: !1, line: 10, type: !47)
|
||||
!47 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
|
||||
!48 = !DILocation(line: 10, column: 8, scope: !40, inlinedAt: !45)
|
||||
|
||||
...
|
||||
---
|
||||
name: _ZN1sC2Ei
|
||||
tracksRegLiveness: true
|
||||
liveins:
|
||||
- { reg: '%rdi' }
|
||||
- { reg: '%esi' }
|
||||
fixedStack:
|
||||
- { id: 0, type: spill-slot, offset: -32, size: 8, alignment: 16, callee-saved-register: '%rbx' }
|
||||
- { id: 1, type: spill-slot, offset: -24, size: 8, alignment: 8, callee-saved-register: '%r14' }
|
||||
- { id: 2, type: spill-slot, offset: -16, size: 8, alignment: 16 }
|
||||
stack:
|
||||
- { id: 0, offset: -36, size: 4, alignment: 4 }
|
||||
body: |
|
||||
bb.0:
|
||||
successors: %bb.3, %bb.2
|
||||
liveins: %esi, %rdi, %r14, %rbx, %rbp
|
||||
|
||||
; CHECK: [[REGISTER:%r[a-z0-9]+]] = LEA64r {{%r[a-z0-9]+}}, 1, _, -20, _
|
||||
; CHECK-NEXT: DBG_VALUE debug-use [[REGISTER]], debug-use _, !46, !17, debug-location !48
|
||||
; CHECK-NEXT: DBG_VALUE debug-use [[REGISTER]], debug-use _, !39, !17, debug-location !44
|
||||
|
||||
frame-setup PUSH64r killed %rbp, implicit-def %rsp, implicit %rsp
|
||||
CFI_INSTRUCTION def_cfa_offset 16
|
||||
CFI_INSTRUCTION offset %rbp, -16
|
||||
%rbp = frame-setup MOV64rr %rsp
|
||||
CFI_INSTRUCTION def_cfa_register %rbp
|
||||
frame-setup PUSH64r killed %r14, implicit-def %rsp, implicit %rsp
|
||||
frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp
|
||||
%rsp = frame-setup SUB64ri8 %rsp, 16, implicit-def dead %eflags
|
||||
CFI_INSTRUCTION offset %rbx, -32
|
||||
CFI_INSTRUCTION offset %r14, -24
|
||||
%r14d = MOV32rr %esi
|
||||
%rbx = MOV64rr %rdi
|
||||
CALL64pcrel32 @_ZN1lC2Ei, csr_64, implicit %rsp, implicit %rdi, implicit %esi, implicit-def %rsp
|
||||
%rdi = LEA64r %rbx, 1, _, 8, _
|
||||
DBG_VALUE debug-use %rdi, debug-use _, !20, !17, debug-location !27
|
||||
DBG_VALUE debug-use %rdi, debug-use _, !10, !17, debug-location !18
|
||||
%rax = MOV64rm %rbx, 1, _, 16, _ :: (load 8)
|
||||
MOV64mr %rbx, 1, _, 8, _, killed %rax :: (store 8)
|
||||
MOV64mr %rbx, 1, _, 24, _, %rdi :: (store 8)
|
||||
%eax = MOV32ri -1
|
||||
%cl = MOV8rr %r14b, implicit killed %r14d
|
||||
%eax = SHL32rCL killed %eax, implicit-def dead %eflags, implicit %cl
|
||||
MOV32mr %rbx, 1, _, 32, _, %eax :: (store 4, align 8)
|
||||
MOV32mi %rbp, 1, _, -20, _, 0 :: (store 4)
|
||||
%rcx = MOV64rm %rbx, 1, _, 8, _ :: (load 8)
|
||||
MOV64mr %rip, 1, _, @n, _, %rcx :: (store 8)
|
||||
%edx = XOR32rr undef %edx, undef %edx, implicit-def dead %eflags, implicit-def %rdx
|
||||
TEST64rr %rcx, %rcx, implicit-def %eflags
|
||||
%esi = MOV32ri @o, implicit-def %rsi
|
||||
%rsi = CMOVNE64rr killed %rsi, %rdx, implicit killed %eflags
|
||||
%rsi = OR64rr killed %rsi, killed %rcx, implicit-def %eflags
|
||||
%rcx = LEA64r %rbp, 1, _, -20, _
|
||||
DBG_VALUE debug-use %rcx, debug-use _, !46, !17, debug-location !48
|
||||
DBG_VALUE debug-use %rcx, debug-use _, !39, !17, debug-location !44
|
||||
DBG_VALUE %rbp, -20, !29, !17, debug-location !36
|
||||
%rcx = CMOVNE64rr killed %rcx, killed %rdx, implicit killed %eflags
|
||||
%rcx = OR64rr killed %rcx, killed %rsi, implicit-def dead %eflags
|
||||
%rdx = MOVSX64rm32 %rbx, 1, _, 0, _ :: (load 4, align 8)
|
||||
TEST32rm killed %eax, killed %rcx, 4, killed %rdx, 0, _, implicit-def %eflags :: (load 4)
|
||||
JNE_1 %bb.2, implicit %eflags
|
||||
JMP_1 %bb.3
|
||||
|
||||
bb.1:
|
||||
successors: %bb.2
|
||||
liveins: %rbx, %rbp
|
||||
|
||||
%rdi = MOV64rm %rbx, 1, _, 24, _ :: (load 8)
|
||||
|
||||
bb.2:
|
||||
successors: %bb.1, %bb.3
|
||||
liveins: %rbx, %rbp, %rsp, %rdi
|
||||
|
||||
CALL64pcrel32 @_ZN1p2aaEv, csr_64, implicit %rsp, implicit %rdi, implicit-def %rsp, implicit-def %eax
|
||||
%eax = KILL %eax, implicit-def %rax
|
||||
%ecx = LEA64_32r %rax, 1, _, -1, _, implicit-def %rcx
|
||||
%ecx = SHR32ri %ecx, 31, implicit-def dead %eflags, implicit killed %rcx, implicit-def %rcx
|
||||
%eax = LEA64_32r killed %rax, 1, killed %rcx, -1, _
|
||||
%eax = SAR32r1 killed %eax, implicit-def dead %eflags
|
||||
CMP32mr %rbx, 1, _, 0, _, killed %eax, implicit-def %eflags :: (load 4, align 8), (load 4, align 8)
|
||||
JG_1 %bb.1, implicit killed %eflags
|
||||
|
||||
bb.3:
|
||||
liveins: %rbp
|
||||
|
||||
%rsp = ADD64ri8 %rsp, 16, implicit-def dead %eflags
|
||||
%rbx = POP64r implicit-def %rsp, implicit %rsp
|
||||
%r14 = POP64r implicit-def %rsp, implicit %rsp
|
||||
%rbp = POP64r implicit-def %rsp, implicit %rsp
|
||||
RETQ
|
||||
|
||||
...
|
Loading…
Reference in New Issue