[PATCH] D51114: [WebAssembly] Don't write SP back when prolog is generated only for EH

Heejin Ahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 22 11:17:08 PDT 2018


aheejin created this revision.
aheejin added reviewers: dschuff, jgravelle-google.
Herald added subscribers: llvm-commits, sunfish, sbc100.

When we don't actually have stack-allocated variables but needs SP only
to support EH, we don't need to write SP back in the epilog, because we
don't bump down the stack pointer.


Repository:
  rL LLVM

https://reviews.llvm.org/D51114

Files:
  lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp
  lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
  test/CodeGen/WebAssembly/exception.ll


Index: test/CodeGen/WebAssembly/exception.ll
===================================================================
--- test/CodeGen/WebAssembly/exception.ll
+++ test/CodeGen/WebAssembly/exception.ll
@@ -217,6 +217,35 @@
   cleanupret from %8 unwind to caller
 }
 
+; When a function does not have stack-allocated objects, it does not need to
+; store SP back to __stack_pointer global at the epilog.
+
+; CHECK-LABEL: no_sp_writeback
+; CHECK:  try
+; CHECK:  call foo at FUNCTION
+; CHECK:  end_try
+; CHECK-NOT:  set_global  __stack_pointer at GLOBAL
+; CHECK:  return
+define void @no_sp_writeback() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+entry:
+  invoke void @foo()
+          to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchswitch within none [label %catch.start] unwind to caller
+
+catch.start:                                      ; preds = %catch.dispatch
+  %1 = catchpad within %0 [i8* null]
+  %2 = call i8* @llvm.wasm.get.exception(token %1)
+  %3 = call i32 @llvm.wasm.get.ehselector(token %1)
+  %4 = call i8* @__cxa_begin_catch(i8* %2) #2 [ "funclet"(token %1) ]
+  call void @__cxa_end_catch() [ "funclet"(token %1) ]
+  catchret from %1 to label %try.cont
+
+try.cont:                                         ; preds = %entry, %catch.start
+  ret void
+}
+
 declare void @foo()
 declare void @bar(i32*)
 declare i32 @__gxx_wasm_personality_v0(...)
Index: lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
===================================================================
--- lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
+++ lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
@@ -105,8 +105,17 @@
 bool WebAssemblyFrameLowering::needsSPWriteback(
     const MachineFunction &MF, const MachineFrameInfo &MFI) const {
   assert(needsSP(MF, MFI));
-  return MFI.getStackSize() > RedZoneSize || MFI.hasCalls() ||
-         MF.getFunction().hasFnAttribute(Attribute::NoRedZone);
+  // When we don't actually have stack-allocated variables but needs SP only to
+  // support EH, we don't need to write SP back in the epilog, because we don't
+  // bump down the stack pointer. We need to write SP back in the epilog only if
+  // 1. We need SP not only for EH support but also because we actually use
+  // stack or we have a frame address taken.
+  // 2. We cannot use the red zone.
+  bool NeedsSPOnlyForEH = !MFI.getStackSize() && !MFI.adjustsStack() &&
+                          !hasFP(MF) && needsPrologForEH(MF);
+  bool CanUseRedZone = MFI.getStackSize() <= RedZoneSize && !MFI.hasCalls() &&
+                       !MF.getFunction().hasFnAttribute(Attribute::NoRedZone);
+  return !NeedsSPOnlyForEH && !CanUseRedZone;
 }
 
 void WebAssemblyFrameLowering::writeSPToGlobal(
Index: lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp
===================================================================
--- lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp
+++ lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp
@@ -68,6 +68,11 @@
     // pad, after the catch instruction. (Catch instructions may have been
     // reordered, and catch_all instructions have not been inserted yet, but
     // those cases are handled in LateEHPrepare).
+    //
+    // Here it is safe to assume that SP32 holds the latest value of
+    // __stack_poiner, because the only exception for this case is when a
+    // function uses the red zone, but that only happens with leaf functions,
+    // and leaf functions can't catch exceptions anyway.
     auto InsertPos = MBB.begin();
     if (WebAssembly::isCatch(*MBB.begin()))
       InsertPos++;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51114.162006.patch
Type: text/x-patch
Size: 3692 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180822/74424394/attachment.bin>


More information about the llvm-commits mailing list