[llvm] afb4e0f - [AArch64] Omit SEH directives for the epilogue if none are needed
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 23:41:05 PDT 2020
Author: Martin Storsjö
Date: 2020-10-02T09:12:56+03:00
New Revision: afb4e0f289ac6d020faafda078642a3716629abd
URL: https://github.com/llvm/llvm-project/commit/afb4e0f289ac6d020faafda078642a3716629abd
DIFF: https://github.com/llvm/llvm-project/commit/afb4e0f289ac6d020faafda078642a3716629abd.diff
LOG: [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
Added:
Modified:
llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/test/CodeGen/AArch64/lrint-conv-fp16-win.ll
llvm/test/CodeGen/AArch64/lrint-conv-win.ll
llvm/test/CodeGen/AArch64/lround-conv-fp16-win.ll
llvm/test/CodeGen/AArch64/lround-conv-win.ll
llvm/test/CodeGen/AArch64/powi-windows.ll
llvm/test/CodeGen/AArch64/win64-nocfi.ll
llvm/test/CodeGen/AArch64/win_cst_pool.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 868bb247ed5e..dde2b06a36f0 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1524,10 +1524,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
bool NeedsWinCFI = needsWinCFI(MF);
bool HasWinCFI = false;
bool IsFunclet = false;
- auto WinCFI = make_scope_exit([&]() {
- if (!MF.hasWinCFI())
- MF.setHasWinCFI(HasWinCFI);
- });
+ auto WinCFI = make_scope_exit([&]() { assert(HasWinCFI == MF.hasWinCFI()); });
if (MBB.end() != MBBI) {
DL = MBBI->getDebugLoc();
@@ -1627,7 +1624,13 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
NeedsWinCFI, &HasWinCFI);
}
- if (NeedsWinCFI) {
+ if (MF.hasWinCFI()) {
+ // If the prologue didn't contain any SEH opcodes and didn't set the
+ // MF.hasWinCFI() flag, assume the epilogue won't either, and skip the
+ // EpilogStart - to avoid generating CFI for functions that don't need it.
+ // (And as we didn't generate any prologue at all, it would be assymetrical
+ // to the epilogue.) By the end of the function, we assert that
+ // HasWinCFI is equal to MF.hasWinCFI(), to verify this assumption.
HasWinCFI = true;
BuildMI(MBB, LastPopI, DL, TII->get(AArch64::SEH_EpilogStart))
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1641,7 +1644,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
{NumBytes + (int64_t)AfterCSRPopSize, MVT::i8}, TII,
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
- if (NeedsWinCFI && HasWinCFI)
+ if (HasWinCFI)
BuildMI(MBB, MBB.getFirstTerminator(), DL,
TII->get(AArch64::SEH_EpilogEnd))
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1720,8 +1723,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
{StackRestoreBytes, MVT::i8}, TII,
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
if (Done) {
- if (NeedsWinCFI) {
- HasWinCFI = true;
+ if (HasWinCFI) {
BuildMI(MBB, MBB.getFirstTerminator(), DL,
TII->get(AArch64::SEH_EpilogEnd))
.setMIFlag(MachineInstr::FrameDestroy);
@@ -1767,7 +1769,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
{(int64_t)AfterCSRPopSize, MVT::i8}, TII,
MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
}
- if (NeedsWinCFI && HasWinCFI)
+ if (HasWinCFI)
BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::SEH_EpilogEnd))
.setMIFlag(MachineInstr::FrameDestroy);
}
diff --git a/llvm/test/CodeGen/AArch64/lrint-conv-fp16-win.ll b/llvm/test/CodeGen/AArch64/lrint-conv-fp16-win.ll
index 4299ce89ad18..ec9a8b2be874 100644
--- a/llvm/test/CodeGen/AArch64/lrint-conv-fp16-win.ll
+++ b/llvm/test/CodeGen/AArch64/lrint-conv-fp16-win.ll
@@ -3,8 +3,6 @@
; CHECK-LABEL: testmhhs:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs w0, h0
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i16 @testmhhs(half %x) {
entry:
@@ -16,8 +14,6 @@ entry:
; CHECK-LABEL: testmhws:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs w0, h0
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i32 @testmhws(half %x) {
entry:
@@ -29,8 +25,6 @@ entry:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs w8, h0
; CHECK-NEXT: sxtw x0, w8
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i64 @testmhxs(half %x) {
entry:
diff --git a/llvm/test/CodeGen/AArch64/lrint-conv-win.ll b/llvm/test/CodeGen/AArch64/lrint-conv-win.ll
index 8195ffe8a9fd..490f009c3fba 100644
--- a/llvm/test/CodeGen/AArch64/lrint-conv-win.ll
+++ b/llvm/test/CodeGen/AArch64/lrint-conv-win.ll
@@ -4,8 +4,6 @@
; CHECK: frintx [[SREG:s[0-9]+]], s0
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[SREG]]
; CHECK-NEXT: sxtw x0, [[WREG]]
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i64 @testmsxs(float %x) {
entry:
@@ -17,8 +15,6 @@ entry:
; CHECK-LABEL: testmsws:
; CHECK: frintx [[SREG:s[0-9]+]], s0
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[SREG]]
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i32 @testmsws(float %x) {
entry:
@@ -30,8 +26,6 @@ entry:
; CHECK: frintx [[DREG:d[0-9]+]], d0
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[DREG]]
; CHECK-NEXT: sxtw x0, [[WREG]]
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i64 @testmsxd(double %x) {
entry:
@@ -43,8 +37,6 @@ entry:
; CHECK-LABEL: testmswd:
; CHECK: frintx [[DREG:d[0-9]+]], d0
; CHECK-NEXT: fcvtzs [[WREG:w[0-9]+]], [[DREG]]
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i32 @testmswd(double %x) {
entry:
diff --git a/llvm/test/CodeGen/AArch64/lround-conv-fp16-win.ll b/llvm/test/CodeGen/AArch64/lround-conv-fp16-win.ll
index ea14659203ed..5eabc2a4f463 100644
--- a/llvm/test/CodeGen/AArch64/lround-conv-fp16-win.ll
+++ b/llvm/test/CodeGen/AArch64/lround-conv-fp16-win.ll
@@ -22,8 +22,6 @@ entry:
; CHECK-LABEL: testmhxs:
; CHECK: fcvtas w8, h0
; CHECK-NEXT: sxtw x0, w8
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i64 @testmhxs(half %x) {
entry:
diff --git a/llvm/test/CodeGen/AArch64/lround-conv-win.ll b/llvm/test/CodeGen/AArch64/lround-conv-win.ll
index b815f2a29249..8bc9213fdced 100644
--- a/llvm/test/CodeGen/AArch64/lround-conv-win.ll
+++ b/llvm/test/CodeGen/AArch64/lround-conv-win.ll
@@ -3,8 +3,6 @@
; CHECK-LABEL: testmsxs:
; CHECK: fcvtas w8, s0
; CHECK-NEXT: sxtw x0, w8
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i64 @testmsxs(float %x) {
entry:
@@ -15,8 +13,6 @@ entry:
; CHECK-LABEL: testmsws:
; CHECK: fcvtas w0, s0
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i32 @testmsws(float %x) {
entry:
@@ -27,8 +23,6 @@ entry:
; CHECK-LABEL: testmsxd:
; CHECK: fcvtas w8, d0
; CHECK-NEXT: sxtw x0, w8
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i64 @testmsxd(double %x) {
entry:
@@ -39,8 +33,6 @@ entry:
; CHECK-LABEL: testmswd:
; CHECK: fcvtas w0, d0
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
define i32 @testmswd(double %x) {
entry:
diff --git a/llvm/test/CodeGen/AArch64/powi-windows.ll b/llvm/test/CodeGen/AArch64/powi-windows.ll
index 809563f3e9e0..859d772b447a 100644
--- a/llvm/test/CodeGen/AArch64/powi-windows.ll
+++ b/llvm/test/CodeGen/AArch64/powi-windows.ll
@@ -11,8 +11,6 @@ entry:
; CHECK-LABEL: d:
; CHECK: scvtf d1, w0
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: b pow
define float @f(float %f, i32 %i) {
@@ -23,8 +21,6 @@ entry:
; CHECK-LABEL: f:
; CHECK: scvtf s1, w0
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: b powf
define float @g(double %d, i32 %i) {
diff --git a/llvm/test/CodeGen/AArch64/win64-nocfi.ll b/llvm/test/CodeGen/AArch64/win64-nocfi.ll
index a1ca56173a2a..aae157a81372 100644
--- a/llvm/test/CodeGen/AArch64/win64-nocfi.ll
+++ b/llvm/test/CodeGen/AArch64/win64-nocfi.ll
@@ -11,3 +11,14 @@ entry:
}
declare void @llvm.trap() noreturn nounwind
+
+define dso_local i32 @getValue() nounwind sspstrong uwtable {
+; CHECK-LABEL: getValue
+; CHECK-NOT: .seh_proc
+; CHECK-NOT: .seh_endprologue
+; CHECK-NOT: .seh_startepilogue
+; CHECK-NOT: .seh_endepilogue
+; CHECK-NOT: .seh_endproc
+entry:
+ ret i32 42
+}
diff --git a/llvm/test/CodeGen/AArch64/win_cst_pool.ll b/llvm/test/CodeGen/AArch64/win_cst_pool.ll
index 6065b5f344ce..5d9eed408d40 100644
--- a/llvm/test/CodeGen/AArch64/win_cst_pool.ll
+++ b/llvm/test/CodeGen/AArch64/win_cst_pool.ll
@@ -12,8 +12,6 @@ define double @double() {
; CHECK: double:
; CHECK: adrp x8, __real at 2000000000800001
; CHECK-NEXT: ldr d0, [x8, __real at 2000000000800001]
-; CHECK-NEXT: .seh_startepilogue
-; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: ret
; MINGW: .section .rdata,"dr"
@@ -23,6 +21,4 @@ define double @double() {
; MINGW: double:
; MINGW: adrp x8, [[LABEL]]
; MINGW-NEXT: ldr d0, [x8, [[LABEL]]]
-; MINGW-NEXT: .seh_startepilogue
-; MINGW-NEXT: .seh_endepilogue
; MINGW-NEXT: ret
More information about the llvm-commits
mailing list