diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h @@ -25,13 +25,9 @@ class WebAssemblyInstPrinter final : public MCInstPrinter { uint64_t ControlFlowCounter = 0; - uint64_t EHPadStackCounter = 0; SmallVector, 4> ControlFlowStack; SmallVector EHPadStack; - enum EHInstKind { TRY, CATCH, END_TRY }; - EHInstKind LastSeenEHInst = END_TRY; - public: WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI); diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp @@ -94,19 +94,18 @@ case WebAssembly::LOOP_S: printAnnotation(OS, "label" + utostr(ControlFlowCounter) + ':'); ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, true)); - break; + return; case WebAssembly::BLOCK: case WebAssembly::BLOCK_S: ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false)); - break; + return; case WebAssembly::TRY: case WebAssembly::TRY_S: - ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false)); - EHPadStack.push_back(EHPadStackCounter++); - LastSeenEHInst = TRY; - break; + ControlFlowStack.push_back(std::make_pair(ControlFlowCounter, false)); + EHPadStack.push_back(ControlFlowCounter++); + return; case WebAssembly::END_LOOP: case WebAssembly::END_LOOP_S: @@ -115,7 +114,7 @@ } else { ControlFlowStack.pop_back(); } - break; + return; case WebAssembly::END_BLOCK: case WebAssembly::END_BLOCK_S: @@ -125,7 +124,7 @@ printAnnotation( OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); } - break; + return; case WebAssembly::END_TRY: case WebAssembly::END_TRY_S: @@ -134,60 +133,60 @@ } else { printAnnotation( OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); - LastSeenEHInst = END_TRY; } - break; + return; case WebAssembly::CATCH: case WebAssembly::CATCH_S: + case WebAssembly::CATCH_ALL: + case WebAssembly::CATCH_ALL_S: if (EHPadStack.empty()) { printAnnotation(OS, "try-catch mismatch!"); } else { printAnnotation(OS, "catch" + utostr(EHPadStack.pop_back_val()) + ':'); } - break; - } - - // Annotate any control flow label references. + return; - // rethrow instruction does not take any depth argument and rethrows to the - // nearest enclosing catch scope, if any. If there's no enclosing catch - // scope, it throws up to the caller. - if (Opc == WebAssembly::RETHROW || Opc == WebAssembly::RETHROW_S) { + case WebAssembly::RETHROW: + case WebAssembly::RETHROW_S: + // 'rethrow' rethrows to the nearest enclosing catch scope, if any. If + // there's no enclosing catch scope, it throws up to the caller. if (EHPadStack.empty()) { printAnnotation(OS, "to caller"); } else { printAnnotation(OS, "down to catch" + utostr(EHPadStack.back())); } + return; + } - } else { - unsigned NumFixedOperands = Desc.NumOperands; - SmallSet Printed; - for (unsigned I = 0, E = MI->getNumOperands(); I < E; ++I) { - // See if this operand denotes a basic block target. - if (I < NumFixedOperands) { - // A non-variable_ops operand, check its type. - if (Desc.OpInfo[I].OperandType != WebAssembly::OPERAND_BASIC_BLOCK) - continue; - } else { - // A variable_ops operand, which currently can be immediates (used in - // br_table) which are basic block targets, or for call instructions - // when using -wasm-keep-registers (in which case they are registers, - // and should not be processed). - if (!MI->getOperand(I).isImm()) - continue; - } - uint64_t Depth = MI->getOperand(I).getImm(); - if (!Printed.insert(Depth).second) + // Annotate any control flow label references. + + unsigned NumFixedOperands = Desc.NumOperands; + SmallSet Printed; + for (unsigned I = 0, E = MI->getNumOperands(); I < E; ++I) { + // See if this operand denotes a basic block target. + if (I < NumFixedOperands) { + // A non-variable_ops operand, check its type. + if (Desc.OpInfo[I].OperandType != WebAssembly::OPERAND_BASIC_BLOCK) continue; - if (Depth >= ControlFlowStack.size()) { - printAnnotation(OS, "Invalid depth argument!"); - } else { - const auto &Pair = ControlFlowStack.rbegin()[Depth]; - printAnnotation(OS, utostr(Depth) + ": " + - (Pair.second ? "up" : "down") + " to label" + - utostr(Pair.first)); - } + } else { + // A variable_ops operand, which currently can be immediates (used in + // br_table) which are basic block targets, or for call instructions + // when using -wasm-keep-registers (in which case they are registers, + // and should not be processed). + if (!MI->getOperand(I).isImm()) + continue; + } + uint64_t Depth = MI->getOperand(I).getImm(); + if (!Printed.insert(Depth).second) + continue; + if (Depth >= ControlFlowStack.size()) { + printAnnotation(OS, "Invalid depth argument!"); + } else { + const auto &Pair = ControlFlowStack.rbegin()[Depth]; + printAnnotation(OS, utostr(Depth) + ": " + + (Pair.second ? "up" : "down") + " to label" + + utostr(Pair.first)); } } } diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll @@ -1,8 +1,8 @@ ; REQUIRES: asserts ; TODO Reenable disabled lines after updating the backend to the new spec -; R UN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling | FileCheck %s +; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling | FileCheck %s ; RUN: llc < %s -disable-wasm-fallthrough-return-opt -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling -; R UN: llc < %s -O0 -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -verify-machineinstrs -exception-model=wasm -mattr=+exception-handling | FileCheck %s --check-prefix=NOOPT +; RUN: llc < %s -O0 -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -verify-machineinstrs -exception-model=wasm -mattr=+exception-handling | FileCheck %s --check-prefix=NOOPT ; R UN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling -wasm-disable-ehpad-sort | FileCheck %s --check-prefix=NOSORT ; R UN: llc < %s -disable-wasm-fallthrough-return-opt -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling -wasm-disable-ehpad-sort | FileCheck %s --check-prefix=NOSORT-LOCALS ; R UN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling -wasm-disable-ehpad-sort -stats 2>&1 | FileCheck %s --check-prefix=NOSORT-STAT @@ -43,7 +43,7 @@ ; CHECK: call __cxa_end_catch ; CHECK: br 1 # 1: down to label[[L1]] ; CHECK: end_block # label[[L2]]: -; CHECK: rethrow {{.*}} # to caller +; CHECK: rethrow 0 # to caller ; CHECK: end_try # label[[L1]]: define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { entry: @@ -118,19 +118,19 @@ ; CHECK: br 2 # 2: down to label[[L3:[0-9]+]] ; CHECK: catch ; CHECK: call __cxa_end_catch -; CHECK: rethrow {{.*}} # down to catch[[C0:[0-9]+]] +; CHECK: rethrow 0 # down to catch[[C0:[0-9]+]] ; CHECK: end_try ; CHECK: end_block # label[[L2]]: -; CHECK: rethrow {{.*}} # down to catch[[C0]] -; CHECK: catch {{.*}} # catch[[C0]]: +; CHECK: rethrow 0 # down to catch[[C0]] +; CHECK: catch_all # catch[[C0]]: ; CHECK: call __cxa_end_catch -; CHECK: rethrow {{.*}} # to caller +; CHECK: rethrow 0 # to caller ; CHECK: end_try # label[[L3]]: ; CHECK: call __cxa_end_catch ; CHECK: br 2 # 2: down to label[[L1]] ; CHECK: end_try ; CHECK: end_block # label[[L0]]: -; CHECK: rethrow {{.*}} # to caller +; CHECK: rethrow 0 # to caller ; CHECK: end_block # label[[L1]]: ; CHECK: call __cxa_end_catch ; CHECK: end_try @@ -237,7 +237,7 @@ ; CHECK: call __clang_call_terminate ; CHECK: unreachable ; CHECK: end_try -; CHECK: rethrow {{.*}} # to caller +; CHECK: rethrow 0 # to caller ; CHECK: end_try ; CHECK: end_block # label[[L1]]: ; CHECK: call __cxa_end_catch @@ -658,7 +658,7 @@ ; NOSORT: br_on_exn 0, {{.*}} # 0: down to label[[L2:[0-9]+]] ; --- Nested try/catch/end_try starts ; NOSORT: try -; NOSORT: rethrow {{.*}} # down to catch[[C0:[0-9]+]] +; NOSORT: rethrow 0 # down to catch[[C0:[0-9]+]] ; NOSORT: catch $[[REG1:[0-9]+]]= # catch[[C0]]: ; NOSORT: br 5 # 5: down to label[[L3:[0-9]+]] ; NOSORT: end_try diff --git a/llvm/test/MC/WebAssembly/annotations.s b/llvm/test/MC/WebAssembly/annotations.s --- a/llvm/test/MC/WebAssembly/annotations.s +++ b/llvm/test/MC/WebAssembly/annotations.s @@ -24,8 +24,7 @@ block try br 0 - catch __cpp_exception - local.set 0 + catch_all end_try end_block rethrow 0 @@ -45,13 +44,12 @@ # CHECK-NEXT: end_loop # CHECK-NEXT: end_block # label1: # CHECK-NEXT: try -# CHECK-NEXT: rethrow 0 # down to catch1 -# CHECK-NEXT: catch __cpp_exception # catch1: +# CHECK-NEXT: rethrow 0 # down to catch3 +# CHECK-NEXT: catch __cpp_exception # catch3: # CHECK-NEXT: block # CHECK-NEXT: try # CHECK-NEXT: br 0 # 0: down to label5 -# CHECK-NEXT: catch __cpp_exception # catch2: -# CHECK-NEXT: local.set 0 +# CHECK-NEXT: catch_all # catch5: # CHECK-NEXT: end_try # label5: # CHECK-NEXT: end_block # label4: # CHECK-NEXT: rethrow 0 # to caller