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)>;
|
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";
|
|
|
|
}
|
|
|
|
|
2015-09-17 00:51:30 +08:00
|
|
|
// TODO: SelectionDAG's lowering insists on using a pointer as the index for
|
2016-03-08 11:18:12 +08:00
|
|
|
// jump tables, so in practice we don't ever use BR_TABLE_I64 in wasm32 mode
|
2015-09-17 00:51:30 +08:00
|
|
|
// currently.
|
|
|
|
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 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>;
|
|
|
|
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>;
|
2015-09-17 00:51:30 +08:00
|
|
|
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
|
|
|
|
|
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
|
|
|
|
2015-08-01 12:48:44 +08:00
|
|
|
multiclass RETURN<WebAssemblyRegClass vt> {
|
2018-06-19 05:22:44 +08:00
|
|
|
defm RETURN_#vt : I<(outs), (ins vt:$val), (outs), (ins),
|
|
|
|
[(WebAssemblyreturn vt:$val)],
|
|
|
|
"return \t$val", "return", 0x0f>;
|
2016-05-21 08:21:56 +08:00
|
|
|
// Equivalent to RETURN_#vt, for use at the end of a function when wasm
|
|
|
|
// semantics return by falling off the end of the block.
|
|
|
|
let isCodeGenOnly = 1 in
|
2018-06-19 05:22:44 +08:00
|
|
|
defm FALLTHROUGH_RETURN_#vt : I<(outs), (ins vt:$val), (outs), (ins), []>;
|
2015-08-01 12:48:44 +08:00
|
|
|
}
|
2015-11-10 08:30:57 +08:00
|
|
|
|
2016-08-03 07:16:09 +08:00
|
|
|
multiclass SIMD_RETURN<ValueType vt> {
|
2018-08-15 03:03:36 +08:00
|
|
|
defm RETURN_#vt : I<(outs), (ins V128:$val), (outs), (ins),
|
|
|
|
[(WebAssemblyreturn (vt V128:$val))],
|
|
|
|
"return \t$val", "return", 0x0f>,
|
|
|
|
Requires<[HasSIMD128]>;
|
2016-08-03 07:16:09 +08:00
|
|
|
// Equivalent to RETURN_#vt, for use at the end of a function when wasm
|
|
|
|
// semantics return by falling off the end of the block.
|
|
|
|
let isCodeGenOnly = 1 in
|
2018-08-15 03:03:36 +08:00
|
|
|
defm FALLTHROUGH_RETURN_#vt : I<(outs), (ins V128:$val), (outs), (ins),
|
|
|
|
[]>,
|
2019-02-06 08:17:03 +08:00
|
|
|
Requires<[HasSIMD128]>;
|
2016-08-03 07:16:09 +08:00
|
|
|
}
|
|
|
|
|
2015-11-10 08:30:57 +08:00
|
|
|
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
|
2016-10-04 05:33:09 +08:00
|
|
|
|
2015-11-10 08:30:57 +08:00
|
|
|
let isReturn = 1 in {
|
2018-06-05 00:59:26 +08:00
|
|
|
defm "": RETURN<I32>;
|
|
|
|
defm "": RETURN<I64>;
|
|
|
|
defm "": RETURN<F32>;
|
|
|
|
defm "": RETURN<F64>;
|
|
|
|
defm "": RETURN<EXCEPT_REF>;
|
|
|
|
defm "": SIMD_RETURN<v16i8>;
|
|
|
|
defm "": SIMD_RETURN<v8i16>;
|
|
|
|
defm "": SIMD_RETURN<v4i32>;
|
2018-08-08 05:24:01 +08:00
|
|
|
defm "": SIMD_RETURN<v2i64>;
|
2018-06-05 00:59:26 +08:00
|
|
|
defm "": SIMD_RETURN<v4f32>;
|
2018-08-08 05:24:01 +08:00
|
|
|
defm "": SIMD_RETURN<v2f64>;
|
2016-08-03 07:16:09 +08:00
|
|
|
|
2018-06-19 05:22:44 +08:00
|
|
|
defm RETURN_VOID : NRI<(outs), (ins), [(WebAssemblyreturn)], "return", 0x0f>;
|
2016-05-21 08:21:56 +08:00
|
|
|
|
|
|
|
// This is to RETURN_VOID what FALLTHROUGH_RETURN_#vt is to RETURN_#vt.
|
|
|
|
let isCodeGenOnly = 1 in
|
2018-06-19 05:22:44 +08:00
|
|
|
defm FALLTHROUGH_RETURN_VOID : NRI<(outs), (ins), []>;
|
2015-11-10 08:30:57 +08:00
|
|
|
} // isReturn = 1
|
2016-10-04 05:33:09 +08:00
|
|
|
|
2018-06-19 05:22:44 +08:00
|
|
|
defm UNREACHABLE : NRI<(outs), (ins), [(trap)], "unreachable", 0x00>;
|
2018-03-02 09:03:40 +08:00
|
|
|
} // isTerminator = 1, 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 {
|
[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
|
|
|
defm THROW : I<(outs), (ins event_op:$tag, variable_ops),
|
|
|
|
(outs), (ins event_op:$tag),
|
|
|
|
[(WebAssemblythrow (WebAssemblywrapper texternalsym:$tag))],
|
|
|
|
"throw \t$tag", "throw \t$tag", 0x08>;
|
[WebAssembly] Make rethrow take an except_ref type argument
Summary:
In the new wasm EH proposal, `rethrow` takes an `except_ref` argument.
This change was missing in r352598.
This patch adds `llvm.wasm.rethrow.in.catch` intrinsic. This is an
intrinsic that's gonna eventually be lowered to wasm `rethrow`
instruction, but this intrinsic can appear only within a catchpad or a
cleanuppad scope. Also this intrinsic needs to be invokable - otherwise
EH pad successor for it will not be correctly generated in clang.
This also adds lowering logic for this intrinsic in
`SelectionDAGBuilder::visitInvoke`. This routine is basically a
specialized and simplified version of
`SelectionDAGBuilder::visitTargetIntrinsic`, but we can't use it
because if is only for `CallInst`s.
This deletes the previous `llvm.wasm.rethrow` intrinsic and related
tests, which was meant to be used within a `__cxa_rethrow` library
function. Turned out this needs some more logic, so the intrinsic for
this purpose will be added later.
LateEHPrepare takes a result value of `catch` and inserts it into
matching `rethrow` as an argument.
`RETHROW_IN_CATCH` is a pseudo instruction that serves as a link between
`llvm.wasm.rethrow.in.catch` and the real wasm `rethrow` instruction. To
generate a `rethrow` instruction, we need an `except_ref` argument,
which is generated from `catch` instruction. But `catch` instrutions are
added in LateEHPrepare pass, so we use `RETHROW_IN_CATCH`, which takes
no argument, until we are able to correctly lower it to `rethrow` in
LateEHPrepare.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59352
llvm-svn: 356316
2019-03-16 13:38:57 +08:00
|
|
|
defm RETHROW : I<(outs), (ins EXCEPT_REF:$exn), (outs), (ins),
|
|
|
|
[], "rethrow \t$exn", "rethrow", 0x09>;
|
|
|
|
// Pseudo instruction to be the lowering target of int_wasm_rethrow_in_catch
|
|
|
|
// intrinsic. Will be converted to the real rethrow instruction later.
|
|
|
|
let isPseudo = 1 in
|
|
|
|
defm RETHROW_IN_CATCH : NRI<(outs), (ins), [(int_wasm_rethrow_in_catch)],
|
|
|
|
"rethrow_in_catch", 0>;
|
2015-11-10 08:30:57 +08:00
|
|
|
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
|
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] 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
|
|
|
// Catching an exception: catch / extract_exception
|
|
|
|
let hasCtrlDep = 1, hasSideEffects = 1 in
|
|
|
|
defm CATCH : I<(outs EXCEPT_REF:$dst), (ins), (outs), (ins), [],
|
|
|
|
"catch \t$dst", "catch", 0x07>;
|
|
|
|
|
|
|
|
// Querying / extracing exception: br_on_exn
|
|
|
|
// br_on_exn queries an except_ref to see if it matches the corresponding
|
|
|
|
// exception tag index. If true it branches to the given label and pushes the
|
|
|
|
// corresponding argument values of the exception onto the stack.
|
|
|
|
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in
|
|
|
|
defm BR_ON_EXN : I<(outs), (ins bb_op:$dst, event_op:$tag, EXCEPT_REF:$exn),
|
|
|
|
(outs), (ins bb_op:$dst, event_op:$tag), [],
|
|
|
|
"br_on_exn \t$dst, $tag, $exn", "br_on_exn \t$dst, $tag",
|
|
|
|
0x0a>;
|
|
|
|
// This is a pseudo instruction that simulates popping a value from stack, which
|
|
|
|
// has been pushed by br_on_exn
|
|
|
|
let isCodeGenOnly = 1, hasSideEffects = 1 in
|
|
|
|
defm EXTRACT_EXCEPTION_I32 : NRI<(outs I32:$dst), (ins),
|
|
|
|
[(set I32:$dst, (int_wasm_extract_exception))],
|
|
|
|
"extract_exception\t$dst">;
|
2017-06-30 08:43:15 +08:00
|
|
|
|
[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]
|