Skip to content

Commit afb4e0f

Browse files
committed
[AArch64] Omit SEH directives for the epilogue if none are needed
For these cases, we already omit the prologue directives, if (!AFI->hasStackFrame() && !windowsRequiresStackProbe && !NumBytes). When writing the epilogue (after the prolog has been written), if the function doesn't have the WinCFI flag set (i.e. if no prologue was generated), assume that no epilogue will be needed either, and don't emit any epilog start pseudo instruction. After completing the epilogue, make sure that it actually matched the prologue. Previously, when epilogue start/end was generated, but no prologue, the unwind info for such functions actually was huge; 12 bytes xdata (4 bytes header, 4 bytes for one non-folded epilogue header, 4 bytes for padded opcodes) and 8 bytes pdata. Because the epilog consisted of one opcode (end) but the prolog was empty (no .seh_endprologue), the epilogue couldn't be folded into the prologue, and thus couldn't be considered for packed form either. On a 6.5 MB DLL with 110 KB pdata and 166 KB xdata, this gets rid of 38 KB pdata and 62 KB xdata. Differential Revision: https://reviews.llvm.org/D88641
1 parent 47df8c5 commit afb4e0f

File tree

8 files changed

+22
-41
lines changed

8 files changed

+22
-41
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,10 +1524,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
15241524
bool NeedsWinCFI = needsWinCFI(MF);
15251525
bool HasWinCFI = false;
15261526
bool IsFunclet = false;
1527-
auto WinCFI = make_scope_exit([&]() {
1528-
if (!MF.hasWinCFI())
1529-
MF.setHasWinCFI(HasWinCFI);
1530-
});
1527+
auto WinCFI = make_scope_exit([&]() { assert(HasWinCFI == MF.hasWinCFI()); });
15311528

15321529
if (MBB.end() != MBBI) {
15331530
DL = MBBI->getDebugLoc();
@@ -1627,7 +1624,13 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
16271624
NeedsWinCFI, &HasWinCFI);
16281625
}
16291626

1630-
if (NeedsWinCFI) {
1627+
if (MF.hasWinCFI()) {
1628+
// If the prologue didn't contain any SEH opcodes and didn't set the
1629+
// MF.hasWinCFI() flag, assume the epilogue won't either, and skip the
1630+
// EpilogStart - to avoid generating CFI for functions that don't need it.
1631+
// (And as we didn't generate any prologue at all, it would be assymetrical
1632+
// to the epilogue.) By the end of the function, we assert that
1633+
// HasWinCFI is equal to MF.hasWinCFI(), to verify this assumption.
16311634
HasWinCFI = true;
16321635
BuildMI(MBB, LastPopI, DL, TII->get(AArch64::SEH_EpilogStart))
16331636
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1641,7 +1644,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
16411644
emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
16421645
{NumBytes + (int64_t)AfterCSRPopSize, MVT::i8}, TII,
16431646
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
1644-
if (NeedsWinCFI && HasWinCFI)
1647+
if (HasWinCFI)
16451648
BuildMI(MBB, MBB.getFirstTerminator(), DL,
16461649
TII->get(AArch64::SEH_EpilogEnd))
16471650
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1720,8 +1723,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
17201723
{StackRestoreBytes, MVT::i8}, TII,
17211724
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
17221725
if (Done) {
1723-
if (NeedsWinCFI) {
1724-
HasWinCFI = true;
1726+
if (HasWinCFI) {
17251727
BuildMI(MBB, MBB.getFirstTerminator(), DL,
17261728
TII->get(AArch64::SEH_EpilogEnd))
17271729
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1767,7 +1769,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
17671769
{(int64_t)AfterCSRPopSize, MVT::i8}, TII,
17681770
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
17691771
}
1770-
if (NeedsWinCFI && HasWinCFI)
1772+
if (HasWinCFI)
17711773
BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::SEH_EpilogEnd))
17721774
.setMIFlag(MachineInstr::FrameDestroy);
17731775
}

llvm/test/CodeGen/AArch64/lrint-conv-fp16-win.ll

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
; CHECK-LABEL: testmhhs:
44
; CHECK: frintx h0, h0
55
; CHECK-NEXT: fcvtzs w0, h0
6-
; CHECK-NEXT: .seh_startepilogue
7-
; CHECK-NEXT: .seh_endepilogue
86
; CHECK-NEXT: ret
97
define i16 @testmhhs(half %x) {
108
entry:
@@ -16,8 +14,6 @@ entry:
1614
; CHECK-LABEL: testmhws:
1715
; CHECK: frintx h0, h0
1816
; CHECK-NEXT: fcvtzs w0, h0
19-
; CHECK-NEXT: .seh_startepilogue
20-
; CHECK-NEXT: .seh_endepilogue
2117
; CHECK-NEXT: ret
2218
define i32 @testmhws(half %x) {
2319
entry:
@@ -29,8 +25,6 @@ entry:
2925
; CHECK: frintx h0, h0
3026
; CHECK-NEXT: fcvtzs w8, h0
3127
; CHECK-NEXT: sxtw x0, w8
32-
; CHECK-NEXT: .seh_startepilogue
33-
; CHECK-NEXT: .seh_endepilogue
3428
; CHECK-NEXT: ret
3529
define i64 @testmhxs(half %x) {
3630
entry:

llvm/test/CodeGen/AArch64/lrint-conv-win.ll

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
; CHECK: frintx [[SREG:s[0-9]+]], s0
55
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[SREG]]
66
; CHECK-NEXT: sxtw x0, [[WREG]]
7-
; CHECK-NEXT: .seh_startepilogue
8-
; CHECK-NEXT: .seh_endepilogue
97
; CHECK-NEXT: ret
108
define i64 @testmsxs(float %x) {
119
entry:
@@ -17,8 +15,6 @@ entry:
1715
; CHECK-LABEL: testmsws:
1816
; CHECK: frintx [[SREG:s[0-9]+]], s0
1917
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[SREG]]
20-
; CHECK-NEXT: .seh_startepilogue
21-
; CHECK-NEXT: .seh_endepilogue
2218
; CHECK-NEXT: ret
2319
define i32 @testmsws(float %x) {
2420
entry:
@@ -30,8 +26,6 @@ entry:
3026
; CHECK: frintx [[DREG:d[0-9]+]], d0
3127
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[DREG]]
3228
; CHECK-NEXT: sxtw x0, [[WREG]]
33-
; CHECK-NEXT: .seh_startepilogue
34-
; CHECK-NEXT: .seh_endepilogue
3529
; CHECK-NEXT: ret
3630
define i64 @testmsxd(double %x) {
3731
entry:
@@ -43,8 +37,6 @@ entry:
4337
; CHECK-LABEL: testmswd:
4438
; CHECK: frintx [[DREG:d[0-9]+]], d0
4539
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[DREG]]
46-
; CHECK-NEXT: .seh_startepilogue
47-
; CHECK-NEXT: .seh_endepilogue
4840
; CHECK-NEXT: ret
4941
define i32 @testmswd(double %x) {
5042
entry:

llvm/test/CodeGen/AArch64/lround-conv-fp16-win.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ entry:
2222
; CHECK-LABEL: testmhxs:
2323
; CHECK: fcvtas w8, h0
2424
; CHECK-NEXT: sxtw x0, w8
25-
; CHECK-NEXT: .seh_startepilogue
26-
; CHECK-NEXT: .seh_endepilogue
2725
; CHECK-NEXT: ret
2826
define i64 @testmhxs(half %x) {
2927
entry:

llvm/test/CodeGen/AArch64/lround-conv-win.ll

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
; CHECK-LABEL: testmsxs:
44
; CHECK: fcvtas w8, s0
55
; CHECK-NEXT: sxtw x0, w8
6-
; CHECK-NEXT: .seh_startepilogue
7-
; CHECK-NEXT: .seh_endepilogue
86
; CHECK-NEXT: ret
97
define i64 @testmsxs(float %x) {
108
entry:
@@ -15,8 +13,6 @@ entry:
1513

1614
; CHECK-LABEL: testmsws:
1715
; CHECK: fcvtas w0, s0
18-
; CHECK-NEXT: .seh_startepilogue
19-
; CHECK-NEXT: .seh_endepilogue
2016
; CHECK-NEXT: ret
2117
define i32 @testmsws(float %x) {
2218
entry:
@@ -27,8 +23,6 @@ entry:
2723
; CHECK-LABEL: testmsxd:
2824
; CHECK: fcvtas w8, d0
2925
; CHECK-NEXT: sxtw x0, w8
30-
; CHECK-NEXT: .seh_startepilogue
31-
; CHECK-NEXT: .seh_endepilogue
3226
; CHECK-NEXT: ret
3327
define i64 @testmsxd(double %x) {
3428
entry:
@@ -39,8 +33,6 @@ entry:
3933

4034
; CHECK-LABEL: testmswd:
4135
; CHECK: fcvtas w0, d0
42-
; CHECK-NEXT: .seh_startepilogue
43-
; CHECK-NEXT: .seh_endepilogue
4436
; CHECK-NEXT: ret
4537
define i32 @testmswd(double %x) {
4638
entry:

llvm/test/CodeGen/AArch64/powi-windows.ll

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ entry:
1111

1212
; CHECK-LABEL: d:
1313
; CHECK: scvtf d1, w0
14-
; CHECK-NEXT: .seh_startepilogue
15-
; CHECK-NEXT: .seh_endepilogue
1614
; CHECK-NEXT: b pow
1715

1816
define float @f(float %f, i32 %i) {
@@ -23,8 +21,6 @@ entry:
2321

2422
; CHECK-LABEL: f:
2523
; CHECK: scvtf s1, w0
26-
; CHECK-NEXT: .seh_startepilogue
27-
; CHECK-NEXT: .seh_endepilogue
2824
; CHECK-NEXT: b powf
2925

3026
define float @g(double %d, i32 %i) {

llvm/test/CodeGen/AArch64/win64-nocfi.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@ entry:
1111
}
1212

1313
declare void @llvm.trap() noreturn nounwind
14+
15+
define dso_local i32 @getValue() nounwind sspstrong uwtable {
16+
; CHECK-LABEL: getValue
17+
; CHECK-NOT: .seh_proc
18+
; CHECK-NOT: .seh_endprologue
19+
; CHECK-NOT: .seh_startepilogue
20+
; CHECK-NOT: .seh_endepilogue
21+
; CHECK-NOT: .seh_endproc
22+
entry:
23+
ret i32 42
24+
}

llvm/test/CodeGen/AArch64/win_cst_pool.ll

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ define double @double() {
1212
; CHECK: double:
1313
; CHECK: adrp x8, __real@2000000000800001
1414
; CHECK-NEXT: ldr d0, [x8, __real@2000000000800001]
15-
; CHECK-NEXT: .seh_startepilogue
16-
; CHECK-NEXT: .seh_endepilogue
1715
; CHECK-NEXT: ret
1816

1917
; MINGW: .section .rdata,"dr"
@@ -23,6 +21,4 @@ define double @double() {
2321
; MINGW: double:
2422
; MINGW: adrp x8, [[LABEL]]
2523
; MINGW-NEXT: ldr d0, [x8, [[LABEL]]]
26-
; MINGW-NEXT: .seh_startepilogue
27-
; MINGW-NEXT: .seh_endepilogue
2824
; MINGW-NEXT: ret

0 commit comments

Comments
 (0)