Author: Heejin Ahn Date: 2021-01-09T02:42:35-08:00 New Revision: 0d8dfbb42a7d5e152bb98e50f170317ba60c47ef
URL: https://github.com/llvm/llvm-project/commit/0d8dfbb42a7d5e152bb98e50f170317ba60c47ef DIFF: https://github.com/llvm/llvm-project/commit/0d8dfbb42a7d5e152bb98e50f170317ba60c47ef.diff LOG: [WebAssembly] Update InstPrinter support for EH - Updates InstPrinter to handle `catch_all`. - Makes `rethrow` condition an early exit from the function to make the rest simpler. - Unify label and catch counters. They don't need to be counted separately and this will help `delegate` instruction later. - Removes `LastSeenEHInst` field. This was first introduced to handle when there are more than one `catch` blocks per `try`, but this was not implemented correctly and not being used at the moment anyway. - Reenables all tests in cfg-stackify-eh.ll that don't deal with unwind destination mismatches, which will be handled in a later CL. Reviewed By: dschuff, tlively, aardappel Differential Revision: https://reviews.llvm.org/D94043 Added: Modified: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll llvm/test/MC/WebAssembly/annotations.s Removed: ################################################################################ diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp index 37296c1f6679..fb8b0c364f30 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp @@ -94,19 +94,18 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, 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 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, } else { ControlFlowStack.pop_back(); } - break; + return; case WebAssembly::END_BLOCK: case WebAssembly::END_BLOCK_S: @@ -125,7 +124,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, printAnnotation( OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); } - break; + return; case WebAssembly::END_TRY: case WebAssembly::END_TRY_S: @@ -134,60 +133,60 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address, } 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<uint64_t, 8> 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<uint64_t, 8> 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/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h index c46411b10b09..2ed6d562acff 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h @@ -25,13 +25,9 @@ class MCSubtargetInfo; class WebAssemblyInstPrinter final : public MCInstPrinter { uint64_t ControlFlowCounter = 0; - uint64_t EHPadStackCounter = 0; SmallVector<std::pair<uint64_t, bool>, 4> ControlFlowStack; SmallVector<uint64_t, 4> 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/test/CodeGen/WebAssembly/cfg-stackify-eh.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll index f55e23a4d7c4..3079d9e15b82 100644 --- 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 @@ target triple = "wasm32-unknown-unknown" ; 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 @@ try.cont: ; preds = %catch, %catch2, %en ; 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 @@ unreachable: ; preds = %rethrow5 ; 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 @@ try.cont: ; preds = %catch.start ; 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 index f2636ec45bee..04c3eefa4e4a 100644 --- a/llvm/test/MC/WebAssembly/annotations.s +++ b/llvm/test/MC/WebAssembly/annotations.s @@ -24,8 +24,7 @@ test_annotation: block try br 0 - catch __cpp_exception - local.set 0 + catch_all end_try end_block rethrow 0 @@ -45,13 +44,12 @@ test_annotation: # 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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits