[llvm] r340454 - [WebAssembly] Don't write SP back when prolog is generated only for EH

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 22 14:13:50 PDT 2018


Author: aheejin
Date: Wed Aug 22 14:13:49 2018
New Revision: 340454

URL: http://llvm.org/viewvc/llvm-project?rev=340454&view=rev
Log:
[WebAssembly] Don't write SP back when prolog is generated only for EH

Summary:
When we don't actually have stack-allocated variables but need 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.

Reviewers: dschuff

Subscribers: jgravelle-google, sbc100, sunfish, llvm-commits

Differential Revision: https://reviews.llvm.org/D51114

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
    llvm/trunk/test/CodeGen/WebAssembly/exception.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp?rev=340454&r1=340453&r2=340454&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp Wed Aug 22 14:13:49 2018
@@ -68,6 +68,11 @@ bool WebAssemblyEHRestoreStackPointer::r
     // 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_pointer, because the only exception for this case is when a
+    // function uses the red zone, but that only happens with leaf functions,
+    // and we don't restore __stack_pointer in leaf functions anyway.
     auto InsertPos = MBB.begin();
     if (WebAssembly::isCatch(*MBB.begin()))
       InsertPos++;

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp?rev=340454&r1=340453&r2=340454&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp Wed Aug 22 14:13:49 2018
@@ -79,6 +79,14 @@ bool WebAssemblyFrameLowering::hasReserv
   return !MF.getFrameInfo().hasVarSizedObjects();
 }
 
+// Returns true if this function needs a local user-space stack pointer for its
+// local frame (not for exception handling).
+bool WebAssemblyFrameLowering::needsSPForLocalFrame(
+    const MachineFunction &MF) const {
+  auto &MFI = MF.getFrameInfo();
+  return MFI.getStackSize() || MFI.adjustsStack() || hasFP(MF);
+}
+
 // In function with EH pads, we need to make a copy of the value of
 // __stack_pointer global in SP32 register, in order to use it when restoring
 // __stack_pointer after an exception is caught.
@@ -93,9 +101,7 @@ bool WebAssemblyFrameLowering::needsProl
 /// Unlike a machine stack pointer, the wasm user stack pointer is a global
 /// variable, so it is loaded into a register in the prolog.
 bool WebAssemblyFrameLowering::needsSP(const MachineFunction &MF) const {
-  auto &MFI = MF.getFrameInfo();
-  return MFI.getStackSize() || MFI.adjustsStack() || hasFP(MF) ||
-         needsPrologForEH(MF);
+  return needsSPForLocalFrame(MF) || needsPrologForEH(MF);
 }
 
 /// Returns true if the local user-space stack pointer needs to be written back
@@ -106,8 +112,16 @@ bool WebAssemblyFrameLowering::needsSPWr
     const MachineFunction &MF) const {
   auto &MFI = MF.getFrameInfo();
   assert(needsSP(MF));
-  return MFI.getStackSize() > RedZoneSize || MFI.hasCalls() ||
-         MF.getFunction().hasFnAttribute(Attribute::NoRedZone);
+  // When we don't need a local stack pointer for its local frame but only to
+  // support EH, we don't need to write SP back in the epilog, because we don't
+  // bump down the stack pointer in the prolog. 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 CanUseRedZone = MFI.getStackSize() <= RedZoneSize && !MFI.hasCalls() &&
+                       !MF.getFunction().hasFnAttribute(Attribute::NoRedZone);
+  return needsSPForLocalFrame(MF) && !CanUseRedZone;
 }
 
 void WebAssemblyFrameLowering::writeSPToGlobal(

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.h?rev=340454&r1=340453&r2=340454&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.h Wed Aug 22 14:13:49 2018
@@ -56,6 +56,7 @@ class WebAssemblyFrameLowering final : p
 
 private:
   bool hasBP(const MachineFunction &MF) const;
+  bool needsSPForLocalFrame(const MachineFunction &MF) const;
   bool needsSP(const MachineFunction &MF) const;
   bool needsSPWriteback(const MachineFunction &MF) const;
 };

Modified: llvm/trunk/test/CodeGen/WebAssembly/exception.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/exception.ll?rev=340454&r1=340453&r2=340454&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/exception.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/exception.ll Wed Aug 22 14:13:49 2018
@@ -217,6 +217,35 @@ ehcleanup:
   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(...)




More information about the llvm-commits mailing list