2015-08-01 01:53:38 +08:00
|
|
|
//===- WebAssemblyInstrControl.td-WebAssembly control-flow ------*- tablegen -*-
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2015-08-01 01:53:38 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \file
|
2018-05-01 23:54:18 +08:00
|
|
|
/// WebAssembly control-flow code-gen constructs.
|
2015-08-01 01:53:38 +08:00
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-09-17 00:51:30 +08:00
|
|
|
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
|
2015-12-05 11:03:35 +08:00
|
|
|
// The condition operand is a boolean value which WebAssembly represents as i32.
|
2018-06-19 05:22:44 +08:00
|
|
|
defm BR_IF : I<(outs), (ins bb_op:$dst, I32:$cond),
|
|
|
|
(outs), (ins bb_op:$dst),
|
|
|
|
[(brcond I32:$cond, bb:$dst)],
|
|
|
|
"br_if \t$dst, $cond", "br_if \t$dst", 0x0d>;
|
2015-12-05 11:03:35 +08:00
|
|
|
let isCodeGenOnly = 1 in
|
2018-06-19 05:22:44 +08:00
|
|
|
defm BR_UNLESS : I<(outs), (ins bb_op:$dst, I32:$cond),
|
|
|
|
(outs), (ins bb_op:$dst), []>;
|
2019-02-06 08:17:03 +08:00
|
|
|
let isBarrier = 1 in
|
2018-06-19 05:22:44 +08:00
|
|
|
defm BR : NRI<(outs), (ins bb_op:$dst),
|
|
|
|
[(br bb:$dst)],
|
|
|
|
"br \t$dst", 0x0c>;
|
2015-09-17 00:51:30 +08:00
|
|
|
} // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
|
|
|
|
|
2015-12-05 11:03:35 +08:00
|
|
|
def : Pat<(brcond (i32 (setne I32:$cond, 0)), bb:$dst),
|
2016-02-09 05:50:13 +08:00
|
|
|
(BR_IF bb_op:$dst, I32:$cond)>;
|
2015-12-05 11:03:35 +08:00
|
|
|
def : Pat<(brcond (i32 (seteq I32:$cond, 0)), bb:$dst),
|
2016-02-09 05:50:13 +08:00
|
|
|
(BR_UNLESS bb_op:$dst, I32:$cond)>;
|
2021-03-31 16:25:18 +08:00
|
|
|
def : Pat<(brcond (i32 (xor bool_node:$cond, (i32 1))), bb:$dst),
|
|
|
|
(BR_UNLESS bb_op:$dst, I32:$cond)>;
|
2015-12-05 11:03:35 +08:00
|
|
|
|
[WebAssembly] Fix assembler parsing of br_table.
Summary:
We use `variable_ops` in the tablegen defs to denote the list of
branch targets in `br_table`, but unlike other uses of `variable_ops`
(e.g. call) the these branch targets need to actually be encoded in the
instruction. The existing tables for `variable_ops` cause not operands
to be accepted by the assembly matcher.
Following the example of ARM:
https://github.com/llvm-mirror/llvm/blob/2cc0a7da876c1d8c32775b0119e1e15aaa759b9e/lib/Target/ARM/ARMInstrInfo.td#L550-L555
we introduce a new operand type to capture this list, and we use the
same {} syntax as ARM as well to differentiate them from regular
integer operands.
Also removed definition and use of TSFlags in tablegen defs, since
`br_table` now has a non-variable_ops immediate operand, so the
previous logic of only the variable_ops arguments being labels didn't
make sense anymore.
Reviewers: dschuff, aheejin, sunfish
Subscribers: javed.absar, sbc100, jgravelle-google, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D55401
llvm-svn: 349405
2018-12-18 06:04:44 +08:00
|
|
|
// A list of branch targets enclosed in {} and separated by comma.
|
|
|
|
// Used by br_table only.
|
|
|
|
def BrListAsmOperand : AsmOperandClass { let Name = "BrList"; }
|
2019-02-06 08:17:03 +08:00
|
|
|
let OperandNamespace = "WebAssembly", OperandType = "OPERAND_BRLIST" in
|
[WebAssembly] Fix assembler parsing of br_table.
Summary:
We use `variable_ops` in the tablegen defs to denote the list of
branch targets in `br_table`, but unlike other uses of `variable_ops`
(e.g. call) the these branch targets need to actually be encoded in the
instruction. The existing tables for `variable_ops` cause not operands
to be accepted by the assembly matcher.
Following the example of ARM:
https://github.com/llvm-mirror/llvm/blob/2cc0a7da876c1d8c32775b0119e1e15aaa759b9e/lib/Target/ARM/ARMInstrInfo.td#L550-L555
we introduce a new operand type to capture this list, and we use the
same {} syntax as ARM as well to differentiate them from regular
integer operands.
Also removed definition and use of TSFlags in tablegen defs, since
`br_table` now has a non-variable_ops immediate operand, so the
previous logic of only the variable_ops arguments being labels didn't
make sense anymore.
Reviewers: dschuff, aheejin, sunfish
Subscribers: javed.absar, sbc100, jgravelle-google, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D55401
llvm-svn: 349405
2018-12-18 06:04:44 +08:00
|
|
|
def brlist : Operand<i32> {
|
|
|
|
let ParserMatchClass = BrListAsmOperand;
|
|
|
|
let PrintMethod = "printBrList";
|
|
|
|
}
|
|
|
|
|
2020-06-12 06:11:45 +08:00
|
|
|
// Duplicating a BR_TABLE is almost never a good idea. In particular, it can
|
|
|
|
// lead to some nasty irreducibility due to tail merging when the br_table is in
|
|
|
|
// a loop.
|
|
|
|
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1, isNotDuplicable = 1 in {
|
|
|
|
|
2019-01-08 09:15:15 +08:00
|
|
|
defm BR_TABLE_I32 : I<(outs), (ins I32:$index, variable_ops),
|
|
|
|
(outs), (ins brlist:$brl),
|
|
|
|
[(WebAssemblybr_table I32:$index)],
|
|
|
|
"br_table \t$index", "br_table \t$brl",
|
|
|
|
0x0e>;
|
2020-06-12 06:11:45 +08:00
|
|
|
// TODO: SelectionDAG's lowering insists on using a pointer as the index for
|
|
|
|
// jump tables, so in practice we don't ever use BR_TABLE_I64 in wasm32 mode
|
|
|
|
// currently.
|
2019-01-08 09:15:15 +08:00
|
|
|
defm BR_TABLE_I64 : I<(outs), (ins I64:$index, variable_ops),
|
|
|
|
(outs), (ins brlist:$brl),
|
|
|
|
[(WebAssemblybr_table I64:$index)],
|
|
|
|
"br_table \t$index", "br_table \t$brl",
|
|
|
|
0x0e>;
|
2020-06-12 06:11:45 +08:00
|
|
|
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1, isNotDuplicable = 1
|
2015-09-17 00:51:30 +08:00
|
|
|
|
2018-05-11 06:16:44 +08:00
|
|
|
// This is technically a control-flow instruction, since all it affects is the
|
|
|
|
// IP.
|
2018-06-19 05:22:44 +08:00
|
|
|
defm NOP : NRI<(outs), (ins), [], "nop", 0x01>;
|
2018-05-11 06:16:44 +08:00
|
|
|
|
2018-03-02 09:03:40 +08:00
|
|
|
// Placemarkers to indicate the start or end of a block or loop scope.
|
2017-06-30 08:43:15 +08:00
|
|
|
// These use/clobber VALUE_STACK to prevent them from being moved into the
|
|
|
|
// middle of an expression tree.
|
2016-10-04 06:43:53 +08:00
|
|
|
let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
|
2018-12-27 06:55:26 +08:00
|
|
|
defm BLOCK : NRI<(outs), (ins Signature:$sig), [], "block \t$sig", 0x02>;
|
|
|
|
defm LOOP : NRI<(outs), (ins Signature:$sig), [], "loop \t$sig", 0x03>;
|
2016-10-25 04:32:04 +08:00
|
|
|
|
2018-12-27 06:55:26 +08:00
|
|
|
defm IF : I<(outs), (ins Signature:$sig, I32:$cond),
|
|
|
|
(outs), (ins Signature:$sig),
|
|
|
|
[], "if \t$sig, $cond", "if \t$sig", 0x04>;
|
|
|
|
defm ELSE : NRI<(outs), (ins), [], "else", 0x05>;
|
|
|
|
|
|
|
|
// END_BLOCK, END_LOOP, END_IF and END_FUNCTION are represented with the same
|
|
|
|
// opcode in wasm.
|
2018-06-19 05:22:44 +08:00
|
|
|
defm END_BLOCK : NRI<(outs), (ins), [], "end_block", 0x0b>;
|
|
|
|
defm END_LOOP : NRI<(outs), (ins), [], "end_loop", 0x0b>;
|
2018-12-27 06:55:26 +08:00
|
|
|
defm END_IF : NRI<(outs), (ins), [], "end_if", 0x0b>;
|
[WebAssembly] Make disassembler always emit most canonical name.
Summary:
There are a few instructions that all map to the same opcode, so
when disassembling, we have to pick one. That was just the first one
before (the except_ref variant in the case of "call"), now it is the
one marked as IsCanonical in tablegen, or failing that, the shortest
name (which is typically the "canonical" one).
Also introduced a canonical "end" instruction for this purpose.
Reviewers: dschuff, tlively
Subscribers: sbc100, jgravelle-google, aheejin, llvm-commits, sunfish
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D57713
llvm-svn: 353131
2019-02-05 09:19:45 +08:00
|
|
|
// Generic instruction, for disassembler.
|
2019-02-06 08:17:03 +08:00
|
|
|
let IsCanonical = 1 in
|
[WebAssembly] Make disassembler always emit most canonical name.
Summary:
There are a few instructions that all map to the same opcode, so
when disassembling, we have to pick one. That was just the first one
before (the except_ref variant in the case of "call"), now it is the
one marked as IsCanonical in tablegen, or failing that, the shortest
name (which is typically the "canonical" one).
Also introduced a canonical "end" instruction for this purpose.
Reviewers: dschuff, tlively
Subscribers: sbc100, jgravelle-google, aheejin, llvm-commits, sunfish
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D57713
llvm-svn: 353131
2019-02-05 09:19:45 +08:00
|
|
|
defm END : NRI<(outs), (ins), [], "end", 0x0b>;
|
2017-02-25 07:18:00 +08:00
|
|
|
let isTerminator = 1, isBarrier = 1 in
|
2018-06-19 05:22:44 +08:00
|
|
|
defm END_FUNCTION : NRI<(outs), (ins), [], "end_function", 0x0b>;
|
2016-10-04 06:43:53 +08:00
|
|
|
} // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
|
2015-09-17 00:51:30 +08:00
|
|
|
|
2016-08-03 07:16:09 +08:00
|
|
|
|
[WebAssembly] Lower llvm.debugtrap properly
Summary:
Unlike normal traps, debug traps are allowed to return and can have
additional instructions in the same basic block. Without explicit
backend support for debug traps, they are lowered in ISel as normal
traps. Since normal traps are lowered in the WebAssembly backend to
the UNREACHABLE instruction, which is a terminator, using debug traps
could lead to invalid MBBs when there are additional instructions
after the trap. This patch fixes the issue by lowering debug traps to
a new version of the UNREACHABLE instruction, DEBUG_UNREACHABLE, that
is not a terminator.
An alternative approach would have been to make UNREACHABLE not a
terminator, but that breaks a large number of tests. In particular, it
would require removing the traps inserted after noreturn calls to
@llvm.wasm.throw because otherwise the terminator throw would be
followed by a non-terminator UNREACHABLE and we would be back to
having invalid MBBs. Overall the approach in this patch seems simpler.
Reviewers: aheejin, dschuff
Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D81055
2020-06-05 04:25:10 +08:00
|
|
|
let hasCtrlDep = 1, isBarrier = 1 in {
|
|
|
|
let isTerminator = 1 in {
|
2015-11-10 08:30:57 +08:00
|
|
|
let isReturn = 1 in {
|
2016-08-03 07:16:09 +08:00
|
|
|
|
2019-10-10 05:42:08 +08:00
|
|
|
defm RETURN : I<(outs), (ins variable_ops), (outs), (ins),
|
|
|
|
[(WebAssemblyreturn)],
|
|
|
|
"return", "return", 0x0f>;
|
|
|
|
// Equivalent to RETURN, for use at the end of a function when wasm
|
|
|
|
// semantics return by falling off the end of the block.
|
|
|
|
let isCodeGenOnly = 1 in
|
|
|
|
defm FALLTHROUGH_RETURN : I<(outs), (ins variable_ops), (outs), (ins), []>;
|
2016-05-21 08:21:56 +08:00
|
|
|
|
2015-11-10 08:30:57 +08:00
|
|
|
} // isReturn = 1
|
2016-10-04 05:33:09 +08:00
|
|
|
|
2020-09-10 13:02:13 +08:00
|
|
|
let IsCanonical = 1, isTrap = 1 in
|
2018-06-19 05:22:44 +08:00
|
|
|
defm UNREACHABLE : NRI<(outs), (ins), [(trap)], "unreachable", 0x00>;
|
[WebAssembly] Lower llvm.debugtrap properly
Summary:
Unlike normal traps, debug traps are allowed to return and can have
additional instructions in the same basic block. Without explicit
backend support for debug traps, they are lowered in ISel as normal
traps. Since normal traps are lowered in the WebAssembly backend to
the UNREACHABLE instruction, which is a terminator, using debug traps
could lead to invalid MBBs when there are additional instructions
after the trap. This patch fixes the issue by lowering debug traps to
a new version of the UNREACHABLE instruction, DEBUG_UNREACHABLE, that
is not a terminator.
An alternative approach would have been to make UNREACHABLE not a
terminator, but that breaks a large number of tests. In particular, it
would require removing the traps inserted after noreturn calls to
@llvm.wasm.throw because otherwise the terminator throw would be
followed by a non-terminator UNREACHABLE and we would be back to
having invalid MBBs. Overall the approach in this patch seems simpler.
Reviewers: aheejin, dschuff
Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D81055
2020-06-05 04:25:10 +08:00
|
|
|
|
|
|
|
} // isTerminator = 1
|
|
|
|
|
|
|
|
// debugtrap explicitly returns despite trapping because it is supposed to just
|
|
|
|
// get the attention of the debugger. Unfortunately, because UNREACHABLE is a
|
|
|
|
// terminator, lowering debugtrap to UNREACHABLE can create an invalid
|
|
|
|
// MachineBasicBlock when there is additional code after it. Lower it to this
|
|
|
|
// non-terminator version instead.
|
|
|
|
// TODO: Actually execute the debugger statement when running on the Web
|
|
|
|
let isTrap = 1 in
|
|
|
|
defm DEBUG_UNREACHABLE : NRI<(outs), (ins), [(debugtrap)], "unreachable", 0x00>;
|
|
|
|
|
|
|
|
} // hasCtrlDep = 1, isBarrier = 1
|
2016-10-04 05:33:09 +08:00
|
|
|
|
2018-03-02 09:03:40 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Exception handling instructions
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2018-07-19 05:42:22 +08:00
|
|
|
let Predicates = [HasExceptionHandling] in {
|
|
|
|
|
2018-03-02 09:03:40 +08:00
|
|
|
// Throwing an exception: throw / rethrow
|
|
|
|
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
|
2021-06-15 16:49:43 +08:00
|
|
|
defm THROW : I<(outs), (ins tag_op:$tag, variable_ops),
|
2021-08-02 10:37:36 +08:00
|
|
|
(outs), (ins tag_op:$tag), [],
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
"throw \t$tag", "throw \t$tag", 0x08>;
|
[WebAssembly] Update basic EH instructions for the new spec
This implements basic instructions for the new spec.
- Adds new versions of instructions: `catch`, `catch_all`, and `rethrow`
- Adds support for instruction selection for the new instructions
- `catch` needs a custom routine for the same reason `throw` needs one,
to encode `__cpp_exception` tag symbol.
- Updates `WebAssembly::isCatch` utility function to include `catch_all`
and Change code that compares an instruction's opcode with `catch` to
use that function.
- LateEHPrepare
- Previously in LateEHPrepare we added `catch` instruction to both
`catchpad`s (for user catches) and `cleanuppad`s (for destructors).
In the new version `catch` is generated from `llvm.catch` intrinsic
in instruction selection phase, so we only need to add `catch_all`
to the beginning of cleanup pads.
- `catch` is generated from instruction selection, but we need to
hoist the `catch` instruction to the beginning of every EH pad,
because `catch` can be in the middle of the EH pad or even in a
split BB from it after various code transformations.
- Removes `addExceptionExtraction` function, which was used to
generate `br_on_exn` before.
- CFGStackfiy: Deletes `fixUnwindMismatches` function. Running this
function on the new instruction causes crashes, and the new version
will be added in a later CL, whose contents will be completely
different. So deleting the whole function will make the diff easier to
read.
- Reenables all disabled tests in exception.ll and eh-lsda.ll and a
single basic test in cfg-stackify-eh.ll.
- Updates existing tests to use the new assembly format. And deletes
`br_on_exn` instructions from the tests and FileCheck lines.
Reviewed By: dschuff, tlively
Differential Revision: https://reviews.llvm.org/D94040
2020-12-26 18:27:44 +08:00
|
|
|
defm RETHROW : NRI<(outs), (ins i32imm:$depth), [], "rethrow \t$depth", 0x09>;
|
2015-11-10 08:30:57 +08:00
|
|
|
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
|
2021-02-12 03:05:41 +08:00
|
|
|
// The depth argument will be computed in CFGStackify. We set it to 0 here for
|
|
|
|
// now.
|
[WebAssembly] Update basic EH instructions for the new spec
This implements basic instructions for the new spec.
- Adds new versions of instructions: `catch`, `catch_all`, and `rethrow`
- Adds support for instruction selection for the new instructions
- `catch` needs a custom routine for the same reason `throw` needs one,
to encode `__cpp_exception` tag symbol.
- Updates `WebAssembly::isCatch` utility function to include `catch_all`
and Change code that compares an instruction's opcode with `catch` to
use that function.
- LateEHPrepare
- Previously in LateEHPrepare we added `catch` instruction to both
`catchpad`s (for user catches) and `cleanuppad`s (for destructors).
In the new version `catch` is generated from `llvm.catch` intrinsic
in instruction selection phase, so we only need to add `catch_all`
to the beginning of cleanup pads.
- `catch` is generated from instruction selection, but we need to
hoist the `catch` instruction to the beginning of every EH pad,
because `catch` can be in the middle of the EH pad or even in a
split BB from it after various code transformations.
- Removes `addExceptionExtraction` function, which was used to
generate `br_on_exn` before.
- CFGStackfiy: Deletes `fixUnwindMismatches` function. Running this
function on the new instruction causes crashes, and the new version
will be added in a later CL, whose contents will be completely
different. So deleting the whole function will make the diff easier to
read.
- Reenables all disabled tests in exception.ll and eh-lsda.ll and a
single basic test in cfg-stackify-eh.ll.
- Updates existing tests to use the new assembly format. And deletes
`br_on_exn` instructions from the tests and FileCheck lines.
Reviewed By: dschuff, tlively
Differential Revision: https://reviews.llvm.org/D94040
2020-12-26 18:27:44 +08:00
|
|
|
def : Pat<(int_wasm_rethrow), (RETHROW 0)>;
|
2015-11-26 03:36:19 +08:00
|
|
|
|
2018-03-02 09:03:40 +08:00
|
|
|
// Region within which an exception is caught: try / end_try
|
|
|
|
let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
|
2018-06-19 05:22:44 +08:00
|
|
|
defm TRY : NRI<(outs), (ins Signature:$sig), [], "try \t$sig", 0x06>;
|
|
|
|
defm END_TRY : NRI<(outs), (ins), [], "end_try", 0x0b>;
|
2018-03-02 09:03:40 +08:00
|
|
|
} // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
|
|
|
|
|
[WebAssembly] Update basic EH instructions for the new spec
This implements basic instructions for the new spec.
- Adds new versions of instructions: `catch`, `catch_all`, and `rethrow`
- Adds support for instruction selection for the new instructions
- `catch` needs a custom routine for the same reason `throw` needs one,
to encode `__cpp_exception` tag symbol.
- Updates `WebAssembly::isCatch` utility function to include `catch_all`
and Change code that compares an instruction's opcode with `catch` to
use that function.
- LateEHPrepare
- Previously in LateEHPrepare we added `catch` instruction to both
`catchpad`s (for user catches) and `cleanuppad`s (for destructors).
In the new version `catch` is generated from `llvm.catch` intrinsic
in instruction selection phase, so we only need to add `catch_all`
to the beginning of cleanup pads.
- `catch` is generated from instruction selection, but we need to
hoist the `catch` instruction to the beginning of every EH pad,
because `catch` can be in the middle of the EH pad or even in a
split BB from it after various code transformations.
- Removes `addExceptionExtraction` function, which was used to
generate `br_on_exn` before.
- CFGStackfiy: Deletes `fixUnwindMismatches` function. Running this
function on the new instruction causes crashes, and the new version
will be added in a later CL, whose contents will be completely
different. So deleting the whole function will make the diff easier to
read.
- Reenables all disabled tests in exception.ll and eh-lsda.ll and a
single basic test in cfg-stackify-eh.ll.
- Updates existing tests to use the new assembly format. And deletes
`br_on_exn` instructions from the tests and FileCheck lines.
Reviewed By: dschuff, tlively
Differential Revision: https://reviews.llvm.org/D94040
2020-12-26 18:27:44 +08:00
|
|
|
// Catching an exception: catch / catch_all
|
|
|
|
let hasCtrlDep = 1, hasSideEffects = 1 in {
|
2021-08-02 10:37:36 +08:00
|
|
|
let variadicOpsAreDefs = 1 in
|
|
|
|
defm CATCH : I<(outs), (ins tag_op:$tag, variable_ops),
|
|
|
|
(outs), (ins tag_op:$tag), [],
|
|
|
|
"catch", "catch \t$tag", 0x07>;
|
2021-02-17 21:27:19 +08:00
|
|
|
defm CATCH_ALL : NRI<(outs), (ins), [], "catch_all", 0x19>;
|
[WebAssembly] Update basic EH instructions for the new spec
This implements basic instructions for the new spec.
- Adds new versions of instructions: `catch`, `catch_all`, and `rethrow`
- Adds support for instruction selection for the new instructions
- `catch` needs a custom routine for the same reason `throw` needs one,
to encode `__cpp_exception` tag symbol.
- Updates `WebAssembly::isCatch` utility function to include `catch_all`
and Change code that compares an instruction's opcode with `catch` to
use that function.
- LateEHPrepare
- Previously in LateEHPrepare we added `catch` instruction to both
`catchpad`s (for user catches) and `cleanuppad`s (for destructors).
In the new version `catch` is generated from `llvm.catch` intrinsic
in instruction selection phase, so we only need to add `catch_all`
to the beginning of cleanup pads.
- `catch` is generated from instruction selection, but we need to
hoist the `catch` instruction to the beginning of every EH pad,
because `catch` can be in the middle of the EH pad or even in a
split BB from it after various code transformations.
- Removes `addExceptionExtraction` function, which was used to
generate `br_on_exn` before.
- CFGStackfiy: Deletes `fixUnwindMismatches` function. Running this
function on the new instruction causes crashes, and the new version
will be added in a later CL, whose contents will be completely
different. So deleting the whole function will make the diff easier to
read.
- Reenables all disabled tests in exception.ll and eh-lsda.ll and a
single basic test in cfg-stackify-eh.ll.
- Updates existing tests to use the new assembly format. And deletes
`br_on_exn` instructions from the tests and FileCheck lines.
Reviewed By: dschuff, tlively
Differential Revision: https://reviews.llvm.org/D94040
2020-12-26 18:27:44 +08:00
|
|
|
}
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
|
2020-12-28 21:10:22 +08:00
|
|
|
// Delegating an exception: delegate
|
|
|
|
let isTerminator = 1, hasCtrlDep = 1, hasSideEffects = 1 in
|
|
|
|
defm DELEGATE : NRI<(outs), (ins bb_op:$dst), [], "delegate \t $dst", 0x18>;
|
|
|
|
|
[WebAssembly] Support instruction selection for catching exceptions
Summary:
This lowers exception catching-related instructions:
1. Lowers `wasm.catch` intrinsic to `catch` instruction
2. Removes `catchpad` and `cleanuppad` instructions; they are not
necessary after isel phase. (`MachineBasicBlock::isEHFuncletEntry()` or
`MachineBasicBlock::isEHPad()` can be used instead.)
3. Lowers `catchret` and `cleanupret` instructions to pseudo `catchret`
and `cleanupret` instructions in isel, which will be replaced with other
instructions in `WebAssemblyExceptionPrepare` pass.
4. Adds 'WebAssemblyExceptionPrepare` pass, which is for running various
transformation for EH. Currently this pass only replaces `catchret` and
`cleanupret` instructions into appropriate wasm instructions to make
this patch successfully run until the end.
Currently this does not handle lowering of intrinsics related to LSDA
info generation (`wasm.landingpad.index` and `wasm.lsda`), because they
cannot be tested without implementing `EHStreamer`'s wasm-specific
handlers. They are marked as TODO, which is needed to make isel pass.
Also this does not generate `try` and `end_try` markers yet, which will
be handled in later patches.
This patch is based on the first wasm EH proposal.
(https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md)
Reviewers: dschuff, majnemer
Subscribers: jfb, sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D44090
llvm-svn: 333705
2018-06-01 06:25:54 +08:00
|
|
|
// Pseudo instructions: cleanupret / catchret
|
|
|
|
let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
isPseudo = 1, isEHScopeReturn = 1 in {
|
|
|
|
defm CLEANUPRET : NRI<(outs), (ins), [(cleanupret)], "cleanupret", 0>;
|
2018-06-19 05:22:44 +08:00
|
|
|
defm CATCHRET : NRI<(outs), (ins bb_op:$dst, bb_op:$from),
|
[WebAssembly] Exception handling: Switch to the new proposal
Summary:
This switches the EH implementation to the new proposal:
https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md
(The previous proposal was
https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md)
- Instruction changes
- Now we have one single `catch` instruction that returns a except_ref
value
- `throw` now can take variable number of operations
- `rethrow` does not have 'depth' argument anymore
- `br_on_exn` queries an except_ref to see if it matches the tag and
branches to the given label if true.
- `extract_exception` is a pseudo instruction that simulates popping
values from wasm stack. This is to make `br_on_exn`, a very special
instruction, work: `br_on_exn` puts values onto the stack only if it
is taken, and the # of values can vay depending on the tag.
- Now there's only one `catch` per `try`, this patch removes all special
handling for terminate pad with a call to `__clang_call_terminate`.
Before it was the only case there are two catch clauses (a normal
`catch` and `catch_all` per `try`).
- Make `rethrow` act as a terminator like `throw`. This splits BB after
`rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable`
after `rethrow` in LateEHPrepare.
- Now we stop at all catchpads (because we add wasm `catch` instruction
that catches all exceptions), this creates new
`findWasmUnwindDestinations` function in SelectionDAGBuilder.
- Now we use `br_on_exn` instrution to figure out if an except_ref
matches the current tag or not, LateEHPrepare generates this sequence
for catch pads:
```
catch
block i32
br_on_exn $__cpp_exception
end_block
extract_exception
```
- Branch analysis for `br_on_exn` in WebAssemblyInstrInfo
- Other various misc. changes to switch to the new proposal.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D57134
llvm-svn: 352598
2019-01-30 11:21:57 +08:00
|
|
|
[(catchret bb:$dst, bb:$from)], "catchret", 0>;
|
|
|
|
} // isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
|
|
|
|
// isPseudo = 1, isEHScopeReturn = 1
|
2019-02-06 08:17:03 +08:00
|
|
|
} // Predicates = [HasExceptionHandling]
|