Skip to content

Commit 8c94d7c

Browse files
[AArch64][DebugInfo]Add Target hooks for InstrRef on AArch64
According to llvm/docs/InstrRefDebugInfo.md, to support proper instruction referecing on any platform, the target specific `TargetInstrInfo::isLoadFromStackSlotPostFE` and `TargetInstrInfo::isStoreToStackSlotPostFE` functions are needed to be implemented for the Instruction Reference-based LiveDebugValues pass to identify spill and restore instructions. This patch is attempting to reland #162327
1 parent e876540 commit 8c94d7c

File tree

3 files changed

+123
-11
lines changed

3 files changed

+123
-11
lines changed

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,11 +2392,10 @@ bool AArch64InstrInfo::isFPRCopy(const MachineInstr &MI) {
23922392
return false;
23932393
}
23942394

2395-
Register AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
2396-
int &FrameIndex) const {
2397-
switch (MI.getOpcode()) {
2395+
static bool isFrameLoadOpcode(int Opcode) {
2396+
switch (Opcode) {
23982397
default:
2399-
break;
2398+
return false;
24002399
case AArch64::LDRWui:
24012400
case AArch64::LDRXui:
24022401
case AArch64::LDRBui:
@@ -2405,22 +2404,26 @@ Register AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
24052404
case AArch64::LDRDui:
24062405
case AArch64::LDRQui:
24072406
case AArch64::LDR_PXI:
2407+
return true;
2408+
}
2409+
}
2410+
2411+
Register AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
2412+
int &FrameIndex) const {
2413+
if (isFrameLoadOpcode(MI.getOpcode())) {
24082414
if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() &&
24092415
MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) {
24102416
FrameIndex = MI.getOperand(1).getIndex();
24112417
return MI.getOperand(0).getReg();
24122418
}
2413-
break;
24142419
}
2415-
24162420
return 0;
24172421
}
24182422

2419-
Register AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
2420-
int &FrameIndex) const {
2421-
switch (MI.getOpcode()) {
2423+
static bool isFrameStoreOpcode(int Opcode) {
2424+
switch (Opcode) {
24222425
default:
2423-
break;
2426+
return false;
24242427
case AArch64::STRWui:
24252428
case AArch64::STRXui:
24262429
case AArch64::STRBui:
@@ -2429,16 +2432,55 @@ Register AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
24292432
case AArch64::STRDui:
24302433
case AArch64::STRQui:
24312434
case AArch64::STR_PXI:
2435+
return true;
2436+
}
2437+
}
2438+
2439+
Register AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
2440+
int &FrameIndex) const {
2441+
if (isFrameStoreOpcode(MI.getOpcode())) {
24322442
if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() &&
24332443
MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) {
24342444
FrameIndex = MI.getOperand(1).getIndex();
24352445
return MI.getOperand(0).getReg();
24362446
}
2437-
break;
24382447
}
24392448
return 0;
24402449
}
24412450

2451+
Register AArch64InstrInfo::isStoreToStackSlotPostFE(const MachineInstr &MI,
2452+
int &FrameIndex) const {
2453+
if (isFrameStoreOpcode(MI.getOpcode())) {
2454+
SmallVector<const MachineMemOperand *, 1> Accesses;
2455+
if (Register Reg = isStoreToStackSlot(MI, FrameIndex))
2456+
return Reg;
2457+
2458+
if (hasStoreToStackSlot(MI, Accesses)) {
2459+
FrameIndex =
2460+
cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
2461+
->getFrameIndex();
2462+
return MI.getOperand(0).getReg();
2463+
}
2464+
}
2465+
return Register();
2466+
}
2467+
2468+
Register AArch64InstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI,
2469+
int &FrameIndex) const {
2470+
if (isFrameLoadOpcode(MI.getOpcode())) {
2471+
if (Register Reg = isLoadFromStackSlot(MI, FrameIndex))
2472+
return Reg;
2473+
SmallVector<const MachineMemOperand *, 1> Accesses;
2474+
if (hasLoadFromStackSlot(MI, Accesses)) {
2475+
FrameIndex =
2476+
cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
2477+
->getFrameIndex();
2478+
return MI.getOperand(0).getReg();
2479+
}
2480+
}
2481+
return Register();
2482+
}
2483+
24422484
/// Check all MachineMemOperands for a hint to suppress pairing.
24432485
bool AArch64InstrInfo::isLdStPairSuppressed(const MachineInstr &MI) {
24442486
return llvm::any_of(MI.memoperands(), [](MachineMemOperand *MMO) {

llvm/lib/Target/AArch64/AArch64InstrInfo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,15 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
205205
Register isStoreToStackSlot(const MachineInstr &MI,
206206
int &FrameIndex) const override;
207207

208+
/// isStoreToStackSlotPostFE - Check for post-frame ptr elimination
209+
/// stack locations as well. This uses a heuristic so it isn't
210+
/// reliable for correctness.
211+
Register isStoreToStackSlotPostFE(const MachineInstr &MI,
212+
int &FrameIndex) const override;
213+
214+
Register isLoadFromStackSlotPostFE(const MachineInstr &MI,
215+
int &FrameIndex) const override;
216+
208217
/// Does this instruction set its full destination register to zero?
209218
static bool isGPRZero(const MachineInstr &MI);
210219

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
; Test to ensure that variable "__last" is properly recovered at the end of the livedebugvalues pass when Instruction Referencing-based LiveDebugValues is used.
2+
; This testcase was obtained by looking at FileCheck.cpp and reducing it down via llvm-reduce.
3+
4+
; RUN: llc -mtriple=aarch64-apple-darwin -o - %s -stop-after=livedebugvalues -O2 -experimental-debug-variable-locations | FileCheck %s
5+
6+
; CHECK: ![[LOC:[0-9]+]] = !DILocalVariable(name: "__last",
7+
; CHECK: DBG_VALUE_LIST ![[LOC]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 8, DW_OP_deref), $sp
8+
9+
10+
declare void @_ZdlPvm()
11+
define fastcc void @"_ZNSt3__111__introsortINS_17_ClassicAlgPolicyERZL18DumpAnnotatedInputRN4llvm11raw_ostreamERKNS2_16FileCheckRequestE20DumpInputFilterValuejNS2_9StringRefERNS_6vectorI15InputAnnotationNS_9allocatorISB_EEEEjE3$_0PSB_Lb0EEEvT1_SJ_T0_NS_15iterator_traitsISJ_E15difference_typeEb"(ptr %__first, ptr %__last, i1 %cmp, ptr %__first.addr.0, ptr %Label3.i.i.i241, ptr %__pivot.sroa.9113.8.copyload.i, ptr %0, ptr %1) !dbg !4 {
12+
br label %while.cond
13+
while.cond: ; preds = %if.end16, %entry
14+
br i1 %cmp, label %if.then13, label %if.end16
15+
if.then13: ; preds = %while.cond
16+
%cmp.i = icmp eq ptr %__first, %__last
17+
%or.cond.i = select i1 %cmp.i, i1 false, i1 false
18+
#dbg_value(ptr %__last, !10, !DIExpression(), !16)
19+
br i1 %or.cond.i, label %common.ret, label %for.body.i, !dbg !23
20+
common.ret: ; preds = %for.body.i, %if.then13
21+
ret void
22+
for.body.i: ; preds = %if.then13
23+
%InputLine.i.i = getelementptr i8, ptr %__first.addr.0, i64 132
24+
br label %common.ret
25+
if.end16: ; preds = %while.cond
26+
%__pivot.sroa.13.8.copyload.i = load i64, ptr null, align 8
27+
call void @_ZdlPvm()
28+
store ptr %__pivot.sroa.9113.8.copyload.i, ptr %0, align 8
29+
store i64 %__pivot.sroa.13.8.copyload.i, ptr %1, align 8
30+
store i64 0, ptr %__first, align 8
31+
store i32 0, ptr %__first.addr.0, align 8
32+
store i32 1, ptr %Label3.i.i.i241, align 4
33+
br label %while.cond
34+
}
35+
!llvm.module.flags = !{!0}
36+
!llvm.dbg.cu = !{!1}
37+
!0 = !{i32 2, !"Debug Info Version", i32 3}
38+
!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !2, producer: "clang version 22.0.0git ([email protected]:llvm/llvm-project.git 46a3b4d5dc6dd9449ec7c0c9065552368cdf41d6)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, retainedTypes: !3, globals: !3, imports: !3, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/Library/Developer/CommandLineTools/SDKs/MacOSX15.3.sdk", sdk: "MacOSX15.3.sdk")
39+
!2 = !DIFile(filename: "/Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/llvm/utils/FileCheck/FileCheck.cpp", directory: "/Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/build-instr-ref-stage2", checksumkind: CSK_MD5, checksum: "fa5f53f1b5782eb8b92fadec416b8941")
40+
!3 = !{}
41+
!4 = distinct !DISubprogram(name: "__introsort<std::__1::_ClassicAlgPolicy, (lambda at /Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/llvm/utils/FileCheck/FileCheck.cpp:544:14) &, InputAnnotation *, false>", linkageName: "_ZNSt3__111__introsortINS_17_ClassicAlgPolicyERZL18DumpAnnotatedInputRN4llvm11raw_ostreamERKNS2_16FileCheckRequestE20DumpInputFilterValuejNS2_9StringRefERNS_6vectorI15InputAnnotationNS_9allocatorISB_EEEEjE3$_0PSB_Lb0EEEvT1_SJ_T0_NS_15iterator_traitsISJ_E15difference_typeEb", scope: !6, file: !5, line: 758, type: !8, scopeLine: 762, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !1, templateParams: !3, retainedNodes: !3, keyInstructions: true)
42+
!5 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX15.3.sdk/usr/include/c++/v1/__algorithm/sort.h", directory: "")
43+
!6 = !DINamespace(name: "__1", scope: !7, exportSymbols: true)
44+
!7 = !DINamespace(name: "std", scope: null)
45+
!8 = !DISubroutineType(cc: DW_CC_nocall, types: !9)
46+
!9 = !{null}
47+
!10 = !DILocalVariable(name: "__last", arg: 2, scope: !11, file: !5, line: 284, type: !13)
48+
!11 = distinct !DISubprogram(name: "__insertion_sort<std::__1::_ClassicAlgPolicy, (lambda at /Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/llvm/utils/FileCheck/FileCheck.cpp:544:14) &, InputAnnotation *>", linkageName: "_ZNSt3__116__insertion_sortB8nn180100INS_17_ClassicAlgPolicyERZL18DumpAnnotatedInputRN4llvm11raw_ostreamERKNS2_16FileCheckRequestE20DumpInputFilterValuejNS2_9StringRefERNS_6vectorI15InputAnnotationNS_9allocatorISB_EEEEjE3$_0PSB_EEvT1_SJ_T0_", scope: !6, file: !5, line: 284, type: !12, scopeLine: 284, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !1, templateParams: !3, retainedNodes: !3, keyInstructions: true)
49+
!12 = distinct !DISubroutineType(types: !9)
50+
!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64)
51+
!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "InputAnnotation", file: !15, line: 323, size: 768, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !3, identifier: "_ZTS15InputAnnotation")
52+
!15 = !DIFile(filename: "llvm/utils/FileCheck/FileCheck.cpp", directory: "/Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project", checksumkind: CSK_MD5, checksum: "fa5f53f1b5782eb8b92fadec416b8941")
53+
!16 = !DILocation(line: 0, scope: !11, inlinedAt: !17)
54+
!17 = distinct !DILocation(line: 800, column: 9, scope: !18)
55+
!18 = distinct !DILexicalBlock(scope: !19, file: !5, line: 799, column: 23)
56+
!19 = distinct !DILexicalBlock(scope: !20, file: !5, line: 799, column: 11)
57+
!20 = distinct !DILexicalBlock(scope: !21, file: !5, line: 798, column: 26)
58+
!21 = distinct !DILexicalBlock(scope: !22, file: !5, line: 798, column: 9)
59+
!22 = distinct !DILexicalBlock(scope: !4, file: !5, line: 770, column: 16)
60+
!23 = !DILocation(line: 288, column: 15, scope: !24, inlinedAt: !17, atomGroup: 1, atomRank: 1)
61+
!24 = distinct !DILexicalBlock(scope: !11, file: !5, line: 288, column: 7)

0 commit comments

Comments
 (0)