aheejin updated this revision to Diff 328116.
aheejin added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97834/new/

https://reviews.llvm.org/D97834

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/wasm-eh.cpp
  llvm/lib/CodeGen/WasmEHPrepare.cpp
  llvm/lib/Target/WebAssembly/CMakeLists.txt
  llvm/lib/Target/WebAssembly/WebAssembly.h
  llvm/lib/Target/WebAssembly/WebAssemblyHandleEHTerminatePads.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
  llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
  llvm/test/CodeGen/WebAssembly/eh-lsda.ll
  llvm/test/CodeGen/WebAssembly/exception.ll
  llvm/test/CodeGen/WebAssembly/wasmehprepare.ll

Index: llvm/test/CodeGen/WebAssembly/wasmehprepare.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/wasmehprepare.ll
+++ llvm/test/CodeGen/WebAssembly/wasmehprepare.ll
@@ -132,59 +132,6 @@
   ret void
 }
 
-; A cleanuppad with a call to __clang_call_terminate().
-;
-; void foo();
-; void test2() {
-;   try {
-;     foo();
-;   } catch (...) {
-;     foo();
-;   }
-; }
-define void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
-; CHECK-LABEL: @test2
-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) [ "funclet"(token %1) ]
-  invoke void @foo() [ "funclet"(token %1) ]
-          to label %invoke.cont1 unwind label %ehcleanup
-
-invoke.cont1:                                     ; preds = %catch.start
-  call void @__cxa_end_catch() [ "funclet"(token %1) ]
-  catchret from %1 to label %try.cont
-
-try.cont:                                         ; preds = %entry, %invoke.cont1
-  ret void
-
-ehcleanup:                                        ; preds = %catch.start
-  %5 = cleanuppad within %1 []
-  invoke void @__cxa_end_catch() [ "funclet"(token %5) ]
-          to label %invoke.cont2 unwind label %terminate
-
-invoke.cont2:                                     ; preds = %ehcleanup
-  cleanupret from %5 unwind to caller
-
-terminate:                                        ; preds = %ehcleanup
-  %6 = cleanuppad within %5 []
-  %7 = call i8* @llvm.wasm.get.exception(token %6)
-  call void @__clang_call_terminate(i8* %7) [ "funclet"(token %6) ]
-  unreachable
-; CHECK: terminate:
-; CHECK-NEXT: cleanuppad
-; CHECK-NEXT:   %[[EXN:.*]] = call i8* @llvm.wasm.catch
-; CHECK-NEXT:   call void @__clang_call_terminate(i8* %[[EXN]])
-}
-
 ; PHI demotion test. Only the phi before catchswitch should be demoted; the phi
 ; before cleanuppad should NOT.
 ;
@@ -194,7 +141,7 @@
 ;   ~Temp() {}
 ; };
 ;
-; void test3() {
+; void test2() {
 ;   int num;
 ;   try {
 ;     Temp t;
@@ -214,8 +161,8 @@
 ;     bar(num);
 ;   }
 ; }
-define void @test3() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
-; CHECK-LABEL: @test3
+define void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+; CHECK-LABEL: @test2
 entry:
   %t = alloca %struct.Temp, align 1
   invoke void @foo()
@@ -279,8 +226,8 @@
 ; Tests if instructions after a call to @llvm.wasm.throw are deleted and the
 ; BB's dead children are deleted.
 
-; CHECK-LABEL: @test4
-define i32 @test4(i1 %b, i8* %p) {
+; CHECK-LABEL: @test3
+define i32 @test3(i1 %b, i8* %p) {
 entry:
   br i1 %b, label %bb.true, label %bb.false
 
@@ -308,14 +255,22 @@
 declare void @bar(i32)
 declare %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* returned)
 declare i32 @__gxx_wasm_personality_v0(...)
-declare i8* @llvm.wasm.get.exception(token)
-declare i32 @llvm.wasm.get.ehselector(token)
-declare i32 @llvm.eh.typeid.for(i8*)
-declare void @llvm.wasm.throw(i32, i8*)
-declare void @llvm.wasm.rethrow()
+; Function Attrs: nounwind
+declare i8* @llvm.wasm.get.exception(token) #0
+; Function Attrs: nounwind
+declare i32 @llvm.wasm.get.ehselector(token) #0
+; Function Attrs: nounwind
+declare i32 @llvm.eh.typeid.for(i8*) #0
+; Function Attrs: noreturn
+declare void @llvm.wasm.throw(i32, i8*) #1
+; Function Attrs: noreturn
+declare void @llvm.wasm.rethrow() #1
 declare i8* @__cxa_begin_catch(i8*)
 declare void @__cxa_end_catch()
-declare void @__clang_call_terminate(i8*)
+declare void @_ZSt9terminatev()
+
+attributes #0 = { nounwind }
+attributes #1 = { noreturn }
 
 ; CHECK-DAG: declare void @llvm.wasm.landingpad.index(token, i32 immarg)
 ; CHECK-DAG: declare i8* @llvm.wasm.lsda()
Index: llvm/test/CodeGen/WebAssembly/exception.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/exception.ll
+++ llvm/test/CodeGen/WebAssembly/exception.ll
@@ -1,5 +1,5 @@
 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs | FileCheck --implicit-check-not=ehgcr -allow-deprecated-dag-overlap %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs -O0 | FileCheck -allow-deprecated-dag-overlap --check-prefix=NOOPT %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs -O0
 ; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers -exception-model=wasm -mattr=+exception-handling
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
@@ -129,9 +129,6 @@
 ; CHECK:   catch_all
 ; CHECK:     try
 ; CHECK:       call      __cxa_end_catch
-; CHECK:     catch     $[[EXN:[0-9]+]]=, __cpp_exception
-; CHECK:       call      __clang_call_terminate, $[[EXN]]
-; CHECK:       unreachable
 ; CHECK:     catch_all
 ; CHECK:       call      _ZSt9terminatev
 ; CHECK:       unreachable
@@ -173,75 +170,7 @@
 
 terminate:                                        ; preds = %ehcleanup
   %6 = cleanuppad within %5 []
-  %7 = call i8* @llvm.wasm.get.exception(token %6)
-  call void @__clang_call_terminate(i8* %7) [ "funclet"(token %6) ]
-  unreachable
-}
-
-; Tests a case when there are multiple BBs within a terminate pad. This kind of
-; structure is not generated by clang, but can generated by code
-; transformations. After LateEHPrepare, there should be a single 'terminate' BB
-; with these instructions:
-
-; %exn = catch $__cpp_exception
-; call @__clang_call_terminate(%exn)
-; unreachable
-
-; NOOPT-LABEL: test_split_terminatepad
-define void @test_split_terminatepad(i1 %arg) 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
-
-; NOOPT:      catch
-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) [ "funclet"(token %1) ]
-  invoke void @foo() [ "funclet"(token %1) ]
-          to label %invoke.cont1 unwind label %ehcleanup
-
-invoke.cont1:                                     ; preds = %catch.start
-  call void @__cxa_end_catch() [ "funclet"(token %1) ]
-  catchret from %1 to label %try.cont
-
-try.cont:                                         ; preds = %invoke.cont1, %entry
-  ret void
-
-; NOOPT:      catch_all
-ehcleanup:                                        ; preds = %catch.start
-  %5 = cleanuppad within %1 []
-  invoke void @__cxa_end_catch() [ "funclet"(token %5) ]
-          to label %invoke.cont2 unwind label %terminate
-
-invoke.cont2:                                     ; preds = %ehcleanup
-  cleanupret from %5 unwind to caller
-
-; This weird structure of split terminate pads are not generated by clang, but
-; we cannot guarantee this kind of multi-BB terminate pads cannot be generated
-; by code transformations. This structure is manually created for this test.
-; NOOPT:      catch     $[[EXN:[0-9]+]]=, __cpp_exception
-; NOOPT-NEXT: global.set  __stack_pointer
-; NOOPT-NEXT: call  __clang_call_terminate, $[[EXN]]
-; NOOPT-NEXT: unreachable
-
-terminate:                                        ; preds = %ehcleanup
-  %6 = cleanuppad within %5 []
-  %7 = call i8* @llvm.wasm.get.exception(token %6)
-  br i1 %arg, label %terminate.split1, label %terminate.split2
-
-terminate.split1:
-  call void @__clang_call_terminate(i8* %7) [ "funclet"(token %6) ]
-  unreachable
-
-terminate.split2:
-  ; This is to test a hypothetical case that a call to __clang_call_terminate is
-  ; duplicated within a terminate pad
-  call void @__clang_call_terminate(i8* %7) [ "funclet"(token %6) ]
+  call void @_ZSt9terminatev() [ "funclet"(token %6) ]
   unreachable
 }
 
@@ -424,16 +353,23 @@
 declare void @foo()
 declare void @bar(i32*)
 declare i32 @__gxx_wasm_personality_v0(...)
-declare void @llvm.wasm.throw(i32, i8*)
-declare i8* @llvm.wasm.get.exception(token)
-declare i32 @llvm.wasm.get.ehselector(token)
-declare void @llvm.wasm.rethrow()
-declare i32 @llvm.eh.typeid.for(i8*)
+; Function Attrs: noreturn
+declare void @llvm.wasm.throw(i32, i8*) #1
+; Function Attrs: nounwind
+declare i8* @llvm.wasm.get.exception(token) #0
+; Function Attrs: nounwind
+declare i32 @llvm.wasm.get.ehselector(token) #0
+; Function Attrs: noreturn
+declare void @llvm.wasm.rethrow() #1
+; Function Attrs: nounwind
+declare i32 @llvm.eh.typeid.for(i8*) #0
 declare i8* @__cxa_begin_catch(i8*)
 declare void @__cxa_end_catch()
-declare void @__clang_call_terminate(i8*)
 declare void @_ZSt9terminatev()
 declare %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* returned)
 
+attributes #0 = { nounwind }
+attributes #1 = { noreturn }
+
 ; CHECK: __cpp_exception:
 ; CHECK: .eventtype  __cpp_exception i32
Index: llvm/test/CodeGen/WebAssembly/eh-lsda.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/eh-lsda.ll
+++ llvm/test/CodeGen/WebAssembly/eh-lsda.ll
@@ -231,10 +231,15 @@
 }
 
 declare void @may_throw()
-declare i32 @llvm.eh.typeid.for(i8*)
-declare i8* @llvm.wasm.get.exception(token)
-declare i32 @llvm.wasm.get.ehselector(token)
+; Function Attrs: nounwind
+declare i32 @llvm.eh.typeid.for(i8*) #0
+; Function Attrs: nounwind
+declare i8* @llvm.wasm.get.exception(token) #0
+; Function Attrs: nounwind
+declare i32 @llvm.wasm.get.ehselector(token) #0
 declare void @__cxa_rethrow()
 declare i8* @__cxa_begin_catch(i8*)
 declare void @__cxa_end_catch()
 declare i32 @__gxx_wasm_personality_v0(...)
+
+attributes #0 = { nounwind }
Index: llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
+++ llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
@@ -233,8 +233,8 @@
 ; CHECK:         catch
 ; CHECK:           try
 ; CHECK:             call      __cxa_end_catch
-; CHECK:           catch
-; CHECK:             call      __clang_call_terminate
+; CHECK:           catch_all
+; CHECK:             call      _ZSt9terminatev
 ; CHECK:             unreachable
 ; CHECK:           end_try
 ; CHECK:           rethrow   0                         # to caller
@@ -291,8 +291,7 @@
 
 terminate:                                        ; preds = %ehcleanup
   %6 = cleanuppad within %5 []
-  %7 = call i8* @llvm.wasm.get.exception(token %6)
-  call void @__clang_call_terminate(i8* %7) [ "funclet"(token %6) ]
+  call void @_ZSt9terminatev() [ "funclet"(token %6) ]
   unreachable
 }
 
@@ -806,8 +805,7 @@
 
 terminate:                                        ; preds = %entry
   %0 = cleanuppad within none []
-  %1 = tail call i8* @llvm.wasm.get.exception(token %0)
-  call void @__clang_call_terminate(i8* %1) [ "funclet"(token %0) ]
+  call void @_ZSt9terminatev() [ "funclet"(token %0) ]
   unreachable
 }
 
@@ -876,8 +874,7 @@
 
 terminate7:                                       ; preds = %ehcleanup
   %10 = cleanuppad within %9 []
-  %11 = call i8* @llvm.wasm.get.exception(token %10)
-  call void @__clang_call_terminate(i8* %11) [ "funclet"(token %10) ]
+  call void @_ZSt9terminatev() [ "funclet"(token %10) ]
   unreachable
 }
 
@@ -1046,8 +1043,7 @@
 
 ehcleanup:                                        ; preds = %catch.start
   %5 = cleanuppad within %1 []
-  %6 = call i8* @llvm.wasm.get.exception(token %5)
-  call void @__clang_call_terminate(i8* %6) [ "funclet"(token %5) ]
+  call void @_ZSt9terminatev() [ "funclet"(token %5) ]
   unreachable
 
 while.end:                                        ; preds = %while.body, %while.cond
@@ -1570,8 +1566,7 @@
 ; Function Attrs: nounwind
 declare i32 @llvm.wasm.get.ehselector(token) #0
 declare i8* @__cxa_allocate_exception(i32) #0
-; Function Attrs: noreturn
-declare void @__cxa_throw(i8*, i8*, i8*) #1
+declare void @__cxa_throw(i8*, i8*, i8*)
 ; Function Attrs: noreturn
 declare void @llvm.wasm.rethrow() #1
 ; Function Attrs: nounwind
@@ -1580,7 +1575,6 @@
 declare i8* @__cxa_begin_catch(i8*)
 declare void @__cxa_end_catch()
 declare i8* @__cxa_get_exception_ptr(i8*)
-declare void @__clang_call_terminate(i8*)
 declare void @_ZSt9terminatev()
 ; Function Attrs: nounwind
 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg) #0
Index: llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
@@ -18,7 +18,6 @@
 #include "llvm/MC/MCContext.h"
 using namespace llvm;
 
-const char *const WebAssembly::ClangCallTerminateFn = "__clang_call_terminate";
 const char *const WebAssembly::CxaBeginCatchFn = "__cxa_begin_catch";
 const char *const WebAssembly::CxaRethrowFn = "__cxa_rethrow";
 const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev";
@@ -73,7 +72,7 @@
     return false;
   // These functions never throw
   if (F->getName() == CxaBeginCatchFn || F->getName() == PersonalityWrapperFn ||
-      F->getName() == ClangCallTerminateFn || F->getName() == StdTerminateFn)
+      F->getName() == StdTerminateFn)
     return false;
 
   // TODO Can we exclude call instructions that are marked as 'nounwind' in the
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -82,7 +82,6 @@
   initializeWebAssemblyExceptionInfoPass(PR);
   initializeWebAssemblyCFGSortPass(PR);
   initializeWebAssemblyCFGStackifyPass(PR);
-  initializeWebAssemblyHandleEHTerminatePadsPass(PR);
   initializeWebAssemblyExplicitLocalsPass(PR);
   initializeWebAssemblyLowerBrUnlessPass(PR);
   initializeWebAssemblyRegNumberingPass(PR);
@@ -486,10 +485,6 @@
   // Insert BLOCK and LOOP markers.
   addPass(createWebAssemblyCFGStackify());
 
-  // Handle terminate pads for cleanups
-  if (TM->Options.ExceptionModel == ExceptionHandling::Wasm)
-    addPass(createWebAssemblyHandleEHTerminatePads());
-
   // Insert explicit local.get and local.set operators.
   if (!WasmDisableExplicitLocals)
     addPass(createWebAssemblyExplicitLocals());
Index: llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
@@ -38,7 +38,6 @@
   bool addCatchAlls(MachineFunction &MF);
   bool replaceFuncletReturns(MachineFunction &MF);
   bool removeUnnecessaryUnreachables(MachineFunction &MF);
-  bool ensureSingleBBTermPads(MachineFunction &MF);
   bool restoreStackPointer(MachineFunction &MF);
 
   MachineBasicBlock *getMatchingEHPad(MachineInstr *MI);
@@ -128,7 +127,6 @@
     Changed |= hoistCatches(MF);
     Changed |= addCatchAlls(MF);
     Changed |= replaceFuncletReturns(MF);
-    Changed |= ensureSingleBBTermPads(MF);
   }
   Changed |= removeUnnecessaryUnreachables(MF);
   if (MF.getFunction().hasPersonalityFn())
@@ -288,80 +286,6 @@
   return Changed;
 }
 
-// Clang-generated terminate pads are an single-BB EH pad in the form of
-// termpad:
-//   %exn = catch $__cpp_exception
-//   call @__clang_call_terminate(%exn)
-//   unreachable
-// (There can be local.set and local.gets before the call if we didn't run
-// RegStackify)
-// But code transformations can change or add more control flow, so the call to
-// __clang_call_terminate() function may not be in the original EH pad anymore.
-// This ensures every terminate pad is a single BB in the form illustrated
-// above.
-//
-// This is preparation work for the HandleEHTerminatePads pass later, which
-// duplicates terminate pads both for 'catch' and 'catch_all'. Refer to
-// WebAssemblyHandleEHTerminatePads.cpp for details.
-bool WebAssemblyLateEHPrepare::ensureSingleBBTermPads(MachineFunction &MF) {
-  const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
-
-  // Find calls to __clang_call_terminate()
-  SmallVector<MachineInstr *, 8> ClangCallTerminateCalls;
-  SmallPtrSet<MachineBasicBlock *, 8> TermPads;
-  for (auto &MBB : MF) {
-    for (auto &MI : MBB) {
-      if (MI.isCall()) {
-        const MachineOperand &CalleeOp = MI.getOperand(0);
-        if (CalleeOp.isGlobal() && CalleeOp.getGlobal()->getName() ==
-                                       WebAssembly::ClangCallTerminateFn) {
-          MachineBasicBlock *EHPad = getMatchingEHPad(&MI);
-          assert(EHPad && "No matching EH pad for __clang_call_terminate");
-          // In case a __clang_call_terminate call is duplicated during code
-          // transformation so one terminate pad contains multiple
-          // __clang_call_terminate calls, we only count one of them
-          if (TermPads.insert(EHPad).second)
-            ClangCallTerminateCalls.push_back(&MI);
-        }
-      }
-    }
-  }
-
-  bool Changed = false;
-  for (auto *Call : ClangCallTerminateCalls) {
-    MachineBasicBlock *EHPad = getMatchingEHPad(Call);
-    assert(EHPad && "No matching EH pad for __clang_call_terminate");
-
-    // If it is already the form we want, skip it
-    if (Call->getParent() == EHPad &&
-        Call->getNextNode()->getOpcode() == WebAssembly::UNREACHABLE)
-      continue;
-
-    // In case the __clang_call_terminate() call is not in its matching EH pad,
-    // move the call to the end of EH pad and add an unreachable instruction
-    // after that. Delete all successors and their children if any, because here
-    // the program terminates.
-    Changed = true;
-    // This runs after hoistCatches(), so catch instruction should be at the top
-    MachineInstr *Catch = WebAssembly::findCatch(EHPad);
-    assert(Catch && "EH pad does not have a catch instruction");
-    // Takes the result register of the catch instruction as argument. There may
-    // have been some other local.set/local.gets in between, but at this point
-    // we don't care.
-    Call->getOperand(1).setReg(Catch->getOperand(0).getReg());
-    auto InsertPos = std::next(MachineBasicBlock::iterator(Catch));
-    EHPad->insert(InsertPos, Call->removeFromParent());
-    BuildMI(*EHPad, InsertPos, Call->getDebugLoc(),
-            TII.get(WebAssembly::UNREACHABLE));
-    EHPad->erase(InsertPos, EHPad->end());
-    SmallVector<MachineBasicBlock *, 8> Succs(EHPad->successors());
-    for (auto *Succ : Succs)
-      EHPad->removeSuccessor(Succ);
-    eraseDeadBBsAndChildren(Succs);
-  }
-  return Changed;
-}
-
 // After the stack is unwound due to a thrown exception, the __stack_pointer
 // global can point to an invalid address. This inserts instructions that
 // restore __stack_pointer global.
Index: llvm/lib/Target/WebAssembly/WebAssemblyHandleEHTerminatePads.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyHandleEHTerminatePads.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-// WebAssemblyHandleEHTerminatePads.cpp - WebAssembly Handle EH TerminatePads //
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Add catch_all blocks to terminate pads.
-///
-/// Terminate pads are cleanup pads with a __clang_call_terminate call. These
-/// are reached when an exception is thrown again in the middle of processing a
-/// thrown exception, to terminate the program. These are cleanup pads that
-/// should run regardless whether the thrown exception is a C++ exception or
-/// not.
-///
-/// Because __clang_call_terminate takes an exception pointer, and
-/// llvm.get.exception intrinsic is selected to 'catch' instruction in
-/// instruction selection, terminate pads have a catch instruction and are in
-/// this form after LateEHPrepare, even though they are cleanup pads:
-/// termpad:
-///   %exn = catch $__cpp_exception
-///   call @__clang_call_terminate(%exn)
-///   unreachable
-///
-/// This pass assumes LateEHPrepare ensured every terminate pad is a single
-/// BB.
-///
-/// __clang_call_terminate is a function generated by clang, in the form of
-/// void __clang_call_terminate(i8* %arg) {
-///   call @__cxa_begin_catch(%arg)
-///   call void @std::terminate()
-///   unreachable
-/// }
-///
-/// To make the terminate pads reachable when a foreign exception is thrown,
-/// this pass attaches an additional catch_all BB after this catch terminate pad
-/// BB, with a call to std::terminate, because foreign exceptions don't have a
-/// valid exception pointer to call __cxa_begin_catch with. So the code example
-/// becomes:
-/// termpad:
-///   %exn = catch $__cpp_exception
-///   call @__clang_call_terminate(%exn)
-///   unreachable
-/// termpad-catchall:
-///   catch_all
-///   call @std::terminate()
-///   unreachable
-///
-/// We do this at the very end of compilation pipeline, even after CFGStackify,
-/// because even though wasm spec allows multiple catch/catch_all blocks per a
-/// try instruction, it has been convenient to maintain the invariant so far
-/// that there has been only a single catch or catch_all attached to a try. This
-/// assumption makes ExceptionInfo generation and CFGStackify simpler, because
-/// we have been always able to assume an EH pad is an end of try block and a
-/// start of catch/catch_all block.
-//===----------------------------------------------------------------------===//
-
-#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
-#include "WebAssembly.h"
-#include "WebAssemblySubtarget.h"
-#include "WebAssemblyUtilities.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetMachine.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "wasm-handle-termpads"
-
-namespace {
-class WebAssemblyHandleEHTerminatePads final : public MachineFunctionPass {
-  StringRef getPassName() const override {
-    return "WebAssembly Handle EH Terminate Pads";
-  }
-
-  bool runOnMachineFunction(MachineFunction &MF) override;
-
-public:
-  static char ID; // Pass identification, replacement for typeid
-  WebAssemblyHandleEHTerminatePads() : MachineFunctionPass(ID) {}
-};
-} // end anonymous namespace
-
-char WebAssemblyHandleEHTerminatePads::ID = 0;
-INITIALIZE_PASS(WebAssemblyHandleEHTerminatePads, DEBUG_TYPE,
-                "WebAssembly Handle EH Terminate Pads", false, false)
-
-FunctionPass *llvm::createWebAssemblyHandleEHTerminatePads() {
-  return new WebAssemblyHandleEHTerminatePads();
-}
-
-bool WebAssemblyHandleEHTerminatePads::runOnMachineFunction(
-    MachineFunction &MF) {
-  LLVM_DEBUG(dbgs() << "********** Handle EH Terminate Pads **********\n"
-                       "********** Function: "
-                    << MF.getName() << '\n');
-
-  if (MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() !=
-          ExceptionHandling::Wasm ||
-      !MF.getFunction().hasPersonalityFn())
-    return false;
-
-  const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
-
-  // Find calls to __clang_call_terminate()
-  SmallVector<MachineInstr *, 8> ClangCallTerminateCalls;
-  for (auto &MBB : MF) {
-    for (auto &MI : MBB) {
-      if (MI.isCall()) {
-        const MachineOperand &CalleeOp = MI.getOperand(0);
-        if (CalleeOp.isGlobal() && CalleeOp.getGlobal()->getName() ==
-                                       WebAssembly::ClangCallTerminateFn)
-          ClangCallTerminateCalls.push_back(&MI);
-      }
-    }
-  }
-
-  if (ClangCallTerminateCalls.empty())
-    return false;
-
-  for (auto *Call : ClangCallTerminateCalls) {
-    // This should be an EH pad because LateEHPrepare ensures terminate pads are
-    // a single BB.
-    MachineBasicBlock *CatchBB = Call->getParent();
-    assert(CatchBB->isEHPad());
-
-    auto *CatchAllBB = MF.CreateMachineBasicBlock();
-    MF.insert(std::next(CatchBB->getIterator()), CatchAllBB);
-    CatchAllBB->setIsEHPad(true);
-    for (auto *Pred : CatchBB->predecessors())
-      Pred->addSuccessor(CatchAllBB);
-
-    // If the definition of __clang_call_terminate exists in the module, there
-    // should be a declaration of std::terminate within the same module, because
-    // __clang_call_terminate calls it.
-    const auto *StdTerminateFn =
-        MF.getMMI().getModule()->getNamedValue(WebAssembly::StdTerminateFn);
-    assert(StdTerminateFn && "std::terminate() does not exist in the module");
-
-    // Generate a BB in the form of:
-    //   catch_all
-    //   call @std::terminate
-    //   unreachable
-    BuildMI(CatchAllBB, Call->getDebugLoc(), TII.get(WebAssembly::CATCH_ALL));
-    BuildMI(CatchAllBB, Call->getDebugLoc(), TII.get(WebAssembly::CALL))
-        .addGlobalAddress(StdTerminateFn);
-    BuildMI(CatchAllBB, Call->getDebugLoc(), TII.get(WebAssembly::UNREACHABLE));
-  }
-
-  return true;
-}
Index: llvm/lib/Target/WebAssembly/WebAssembly.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssembly.h
+++ llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -49,7 +49,6 @@
 FunctionPass *createWebAssemblyLateEHPrepare();
 FunctionPass *createWebAssemblyCFGSort();
 FunctionPass *createWebAssemblyCFGStackify();
-FunctionPass *createWebAssemblyHandleEHTerminatePads();
 FunctionPass *createWebAssemblyExplicitLocals();
 FunctionPass *createWebAssemblyLowerBrUnless();
 FunctionPass *createWebAssemblyRegNumbering();
@@ -76,7 +75,6 @@
 void initializeWebAssemblyExceptionInfoPass(PassRegistry &);
 void initializeWebAssemblyCFGSortPass(PassRegistry &);
 void initializeWebAssemblyCFGStackifyPass(PassRegistry &);
-void initializeWebAssemblyHandleEHTerminatePadsPass(PassRegistry &);
 void initializeWebAssemblyExplicitLocalsPass(PassRegistry &);
 void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &);
 void initializeWebAssemblyRegNumberingPass(PassRegistry &);
Index: llvm/lib/Target/WebAssembly/CMakeLists.txt
===================================================================
--- llvm/lib/Target/WebAssembly/CMakeLists.txt
+++ llvm/lib/Target/WebAssembly/CMakeLists.txt
@@ -22,7 +22,6 @@
   WebAssemblyCFGSort.cpp
   WebAssemblyDebugFixup.cpp
   WebAssemblyDebugValueManager.cpp
-  WebAssemblyHandleEHTerminatePads.cpp
   WebAssemblyLateEHPrepare.cpp
   WebAssemblyExceptionInfo.cpp
   WebAssemblyExplicitLocals.cpp
Index: llvm/lib/CodeGen/WasmEHPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/WasmEHPrepare.cpp
+++ llvm/lib/CodeGen/WasmEHPrepare.cpp
@@ -297,8 +297,8 @@
     }
   }
 
-  // Cleanup pads w/o __clang_call_terminate call do not have any of
-  // wasm.get.exception() or wasm.get.ehselector() calls. We need to do nothing.
+  // Cleanup pads do not have any of wasm.get.exception() or
+  // wasm.get.ehselector() calls. We need to do nothing.
   if (!GetExnCI) {
     assert(!GetSelectorCI &&
            "wasm.get.ehselector() cannot exist w/o wasm.get.exception()");
Index: clang/test/CodeGenCXX/wasm-eh.cpp
===================================================================
--- clang/test/CodeGenCXX/wasm-eh.cpp
+++ clang/test/CodeGenCXX/wasm-eh.cpp
@@ -188,13 +188,7 @@
 
 // CHECK: [[TERMINATE_BB]]:
 // CHECK-NEXT:   %[[CLEANUPPAD1:.*]] = cleanuppad within %[[CLEANUPPAD0]] []
-// CHECK-NEXT:   %[[EXN:.*]] = call i8* @llvm.wasm.get.exception(token %[[CLEANUPPAD1]])
-// CHECK-NEXT:   call void @__clang_call_terminate(i8* %[[EXN]]) {{.*}} [ "funclet"(token %[[CLEANUPPAD1]]) ]
-// CHECK-NEXT:   unreachable
-
-// CHECK-LABEL: define {{.*}} void @__clang_call_terminate(i8* %0)
-// CHECK-NEXT:   call i8* @__cxa_begin_catch(i8* %{{.*}})
-// CHECK-NEXT:   call void @_ZSt9terminatev()
+// CHECK-NEXT:   call void @_ZSt9terminatev() {{.*}} [ "funclet"(token %[[CLEANUPPAD1]]) ]
 // CHECK-NEXT:   unreachable
 
 // Try-catch with cleanups
@@ -336,7 +330,7 @@
 // CHECK:   unreachable
 
 // CHECK:   %[[CLEANUPPAD7:.*]] = cleanuppad within %[[CLEANUPPAD4]] []
-// CHECK:   call void @__clang_call_terminate(i8* %{{.*}}) {{.*}} [ "funclet"(token %[[CLEANUPPAD7]]) ]
+// CHECK:   call void @_ZSt9terminatev() {{.*}} [ "funclet"(token %[[CLEANUPPAD7]]) ]
 // CHECK:   unreachable
 
 // Nested try-catches within a catch
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -515,6 +515,9 @@
       : ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true,
                       /*UseARMGuardVarABI=*/true) {}
   void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;
+  llvm::CallInst *
+  emitTerminateForUnexpectedException(CodeGenFunction &CGF,
+                                      llvm::Value *Exn) override;
 
 private:
   bool HasThisReturn(GlobalDecl GD) const override {
@@ -4640,6 +4643,18 @@
   ItaniumCXXABI::emitBeginCatch(CGF, C);
 }
 
+llvm::CallInst *
+WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
+                                                       llvm::Value *Exn) {
+  // Itanium ABI calls __clang_call_terminate(), which __cxa_begin_catch() on
+  // the violating exception to mark it handled, but it is currently hard to do
+  // with wasm EH instruction structure with catch/catch_all, we just call
+  // std::terminate and ignore the violating exception as in CGCXXABI.
+  // TODO Consider code transformation that makes calling __clang_call_terminate
+  // possible.
+  return CGCXXABI::emitTerminateForUnexpectedException(CGF, Exn);
+}
+
 /// Register a global destructor as best as we know how.
 void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
                                   llvm::FunctionCallee dtor,
Index: clang/lib/CodeGen/CGException.cpp
===================================================================
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1552,17 +1552,8 @@
   CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
 
   // Emit the __std_terminate call.
-  llvm::Value *Exn = nullptr;
-  // In case of wasm personality, we need to pass the exception value to
-  // __clang_call_terminate function.
-  if (getLangOpts().CPlusPlus &&
-      EHPersonality::get(*this).isWasmPersonality()) {
-    llvm::Function *GetExnFn =
-        CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);
-    Exn = Builder.CreateCall(GetExnFn, CurrentFuncletPad);
-  }
   llvm::CallInst *terminateCall =
-      CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
+      CGM.getCXXABI().emitTerminateForUnexpectedException(*this, nullptr);
   terminateCall->setDoesNotReturn();
   Builder.CreateUnreachable();
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to