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/AsmParser/WebAssemblyAsmParser.cpp | |
parent | 3dad29b677e427bf69c035605a16efd065576829 (diff) | |
download | llvm-6bbf7f06d8e4e84bbda9027252b26a0d9ae10cde.zip llvm-6bbf7f06d8e4e84bbda9027252b26a0d9ae10cde.tar.gz llvm-6bbf7f06d8e4e84bbda9027252b26a0d9ae10cde.tar.bz2 |
[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/AsmParser/WebAssemblyAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 24a9ad6..5299e6e 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -45,7 +45,7 @@ namespace { /// WebAssemblyOperand - Instances of this class represent the operands in a /// parsed Wasm machine instruction. struct WebAssemblyOperand : public MCParsedAsmOperand { - enum KindTy { Token, Integer, Float, Symbol, BrList } Kind; + enum KindTy { Token, Integer, Float, Symbol, BrList, CatchList } Kind; SMLoc StartLoc, EndLoc; @@ -99,6 +99,7 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { bool isMem() const override { return false; } bool isReg() const override { return false; } bool isBrList() const { return Kind == BrList; } + bool isCatchList() const { return Kind == CatchList; } MCRegister getReg() const override { llvm_unreachable("Assembly inspects a register operand"); @@ -151,6 +152,10 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createImm(Br)); } + void addCatchListOperands(MCInst &Inst, unsigned N) const { + // TODO + } + void print(raw_ostream &OS) const override { switch (Kind) { case Token: @@ -168,6 +173,9 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { case BrList: OS << "BrList:" << BrL.List.size(); break; + case CatchList: + // TODO + break; } } }; |