[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