[llvm] 0d8dfbb - [WebAssembly] Update InstPrinter support for EH
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 9 02:43:05 PST 2021
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
More information about the llvm-commits
mailing list