diff options
| author | Heejin Ahn <aheejin@gmail.com> | 2024-09-10 21:32:24 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-10 21:32:24 -0700 |
| commit | 6bbf7f06d8e4e84bbda9027252b26a0d9ae10cde (patch) | |
| tree | 08c236102c715509394ed7f5587348f2b3c8d8ef /llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h | |
| parent | 3dad29b677e427bf69c035605a16efd065576829 (diff) | |
[WebAssembly] Add assembly support for final EH proposal (#107917)
This adds the basic assembly generation support for the final EH
proposal, which was newly adopted in Sep 2023 and advanced into Phase 4
in Jul 2024:
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
This adds support for the generation of new `try_table` and `throw_ref`
instruction in .s asesmbly format. This does NOT yet include
- Block annotation comment generation for .s format
- .o object file generation
- .s assembly parsing
- Type checking (AsmTypeCheck)
- Disassembler
- Fixing unwind mismatches in CFGStackify
These will be added as follow-up PRs.
---
The format for `TRY_TABLE`, both for `MachineInstr` and `MCInst`, is as
follows:
```
TRY_TABLE type number_of_catches catch_clauses*
```
where `catch_clause` is
```
catch_opcode tag+ destination
```
`catch_opcode` should be one of 0/1/2/3, which denotes
`CATCH`/`CATCH_REF`/`CATCH_ALL`/`CATCH_ALL_REF` respectively. (See
`BinaryFormat/Wasm.h`) `tag` exists when the catch is one of `CATCH` or
`CATCH_REF`.
The MIR format is printed as just the list of raw operands. The
(stack-based) assembly instruction supports pretty-printing, including
printing `catch` clauses by name, in InstPrinter.
In addition to the new instructions `TRY_TABLE` and `THROW_REF`, this
adds four pseudo instructions: `CATCH`, `CATCH_REF`, `CATCH_ALL`, and
`CATCH_ALL_REF`. These are pseudo instructions to simulate block return
values of `catch`, `catch_ref`, `catch_all`, `catch_all_ref` clauses in
`try_table` respectively, given that we don't support block return
values except for one case (`fixEndsAtEndOfFunction` in CFGStackify).
These will be omitted when we lower the instructions to `MCInst` at the
end.
LateEHPrepare now will have one more stage to covert
`CATCH`/`CATCH_ALL`s to `CATCH_REF`/`CATCH_ALL_REF`s when there is a
`RETHROW` to rethrow its exception. The pass also converts `RETHROW`s
into `THROW_REF`. Note that we still use `RETHROW` as an interim pseudo
instruction until we convert them to `THROW_REF` in LateEHPrepare.
CFGStackify has a new `placeTryTableMarker` function, which places
`try_table`/`end_try_table` markers with a necessary `catch` clause and
also `block`/`end_block` markers for the destination of the `catch`
clause.
In MCInstLower, now we need to support one more case for the multivalue
block signature (`catch_ref`'s destination's `(i32, exnref)` return
type).
InstPrinter has a new routine to print the `catch_list` type, which is
used to print `try_table` instructions.
The new test, `exception.ll`'s source is the same as
`exception-legacy.ll`, with the FileCheck expectations changed. One
difference is the commands in this file have `-wasm-enable-exnref` to
test the new format, and don't have `-wasm-disable-explicit-locals
-wasm-keep-registers`, because the new custom InstPrinter routine to
print `catch_list` only works for the stack-based instructions (`_S`),
and we can't use `-wasm-keep-registers` for them.
As in `exception-legacy.ll`, the FileCheck lines for the new tests do
not contain the whole program; they mostly contain only the control flow
instructions for readability.
Diffstat (limited to 'llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h')
| -rw-r--r-- | llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index 00f15e1db5e1..e3a60fa4812d 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -87,6 +87,8 @@ enum OperandType { OPERAND_BRLIST, /// 32-bit unsigned table number. OPERAND_TABLE, + /// A list of catch clauses for try_table. + OPERAND_CATCH_LIST, }; } // end namespace WebAssembly @@ -119,6 +121,10 @@ enum TOF { // address relative the __table_base wasm global. // Only applicable to function symbols. MO_TABLE_BASE_REL, + + // On a block signature operand this indicates that this is a destination + // block of a (catch_ref) clause in try_table. + MO_CATCH_BLOCK_SIG, }; } // end namespace WebAssemblyII @@ -462,6 +468,22 @@ inline bool isMarker(unsigned Opc) { case WebAssembly::TRY_S: case WebAssembly::END_TRY: case WebAssembly::END_TRY_S: + case WebAssembly::TRY_TABLE: + case WebAssembly::TRY_TABLE_S: + case WebAssembly::END_TRY_TABLE: + case WebAssembly::END_TRY_TABLE_S: + return true; + default: + return false; + } +} + +inline bool isTry(unsigned Opc) { + switch (Opc) { + case WebAssembly::TRY: + case WebAssembly::TRY_S: + case WebAssembly::TRY_TABLE: + case WebAssembly::TRY_TABLE_S: return true; default: return false; @@ -474,6 +496,14 @@ inline bool isCatch(unsigned Opc) { case WebAssembly::CATCH_LEGACY_S: case WebAssembly::CATCH_ALL_LEGACY: case WebAssembly::CATCH_ALL_LEGACY_S: + case WebAssembly::CATCH: + case WebAssembly::CATCH_S: + case WebAssembly::CATCH_REF: + case WebAssembly::CATCH_REF_S: + case WebAssembly::CATCH_ALL: + case WebAssembly::CATCH_ALL_S: + case WebAssembly::CATCH_ALL_REF: + case WebAssembly::CATCH_ALL_REF_S: return true; default: return false; |
