[WebAssembly] Rename except_ref type to exnref

Summary:
We agreed to rename `except_ref` to `exnref` for consistency with other
reference types in
https://github.com/WebAssembly/exception-handling/issues/79. This also
renames WebAssemblyInstrExceptRef.td to WebAssemblyInstrRef.td in order
to use the file for other reference types in future.

Reviewers: dschuff

Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, jfb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D64703

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366145 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Heejin Ahn 2019-07-15 22:49:25 +00:00
parent a7eae67847
commit b29d4ba62f
27 changed files with 139 additions and 144 deletions

View File

@ -224,7 +224,7 @@ enum : unsigned {
WASM_TYPE_F64 = 0x7C,
WASM_TYPE_V128 = 0x7B,
WASM_TYPE_FUNCREF = 0x70,
WASM_TYPE_EXCEPT_REF = 0x68,
WASM_TYPE_EXNREF = 0x68,
WASM_TYPE_FUNC = 0x60,
WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
};
@ -332,7 +332,7 @@ enum class ValType {
F32 = WASM_TYPE_F32,
F64 = WASM_TYPE_F64,
V128 = WASM_TYPE_V128,
EXCEPT_REF = WASM_TYPE_EXCEPT_REF,
EXNREF = WASM_TYPE_EXNREF,
};
struct WasmSignature {

View File

@ -160,7 +160,7 @@ def x86mmx : ValueType<64 , 125>; // X86 MMX value
def FlagVT : ValueType<0 , 126>; // Pre-RA sched glue
def isVoid : ValueType<0 , 127>; // Produces no value
def untyped: ValueType<8 , 128>; // Produces an untyped value
def ExceptRef: ValueType<0, 129>; // WebAssembly's except_ref type
def exnref: ValueType<0, 129>; // WebAssembly's exnref type
def token : ValueType<0 , 248>; // TokenTy
def MetadataVT: ValueType<0, 249>; // Metadata

View File

@ -206,7 +206,7 @@ namespace llvm {
// unspecified type. The register class
// will be determined by the opcode.
ExceptRef = 129, // WebAssembly's except_ref type
exnref = 129, // WebAssembly's exnref type
FIRST_VALUETYPE = 1, // This is always the beginning of the list.
LAST_VALUETYPE = 130, // This always remains at the end of the list.
@ -811,7 +811,7 @@ namespace llvm {
case v1024f32: return 32768;
case v2048i32:
case v2048f32: return 65536;
case ExceptRef: return 0; // opaque type
case exnref: return 0; // opaque type
}
}

View File

@ -207,7 +207,7 @@ std::string EVT::getEVTString() const {
case MVT::v8f64: return "v8f64";
case MVT::Metadata:return "Metadata";
case MVT::Untyped: return "Untyped";
case MVT::ExceptRef: return "ExceptRef";
case MVT::exnref : return "exnref";
}
}

View File

@ -308,8 +308,8 @@ public:
Type == "i32x4" || Type == "i64x2" || Type == "f32x4" ||
Type == "f64x2")
return wasm::ValType::V128;
if (Type == "except_ref")
return wasm::ValType::EXCEPT_REF;
if (Type == "exnref")
return wasm::ValType::EXNREF;
return Optional<wasm::ValType>();
}
@ -320,7 +320,7 @@ public:
.Case("f32", WebAssembly::ExprType::F32)
.Case("f64", WebAssembly::ExprType::F64)
.Case("v128", WebAssembly::ExprType::V128)
.Case("except_ref", WebAssembly::ExprType::ExceptRef)
.Case("exnref", WebAssembly::ExprType::Exnref)
.Case("void", WebAssembly::ExprType::Void)
.Default(WebAssembly::ExprType::Invalid);
}

View File

@ -282,8 +282,8 @@ const char *llvm::WebAssembly::anyTypeToString(unsigned Ty) {
return "funcref";
case wasm::WASM_TYPE_FUNC:
return "func";
case wasm::WASM_TYPE_EXCEPT_REF:
return "except_ref";
case wasm::WASM_TYPE_EXNREF:
return "exnref";
case wasm::WASM_TYPE_NORESULT:
return "void";
default:

View File

@ -146,8 +146,8 @@ wasm::ValType WebAssembly::toValType(const MVT &Ty) {
case MVT::v4f32:
case MVT::v2f64:
return wasm::ValType::V128;
case MVT::ExceptRef:
return wasm::ValType::EXCEPT_REF;
case MVT::exnref:
return wasm::ValType::EXNREF;
default:
llvm_unreachable("unexpected type");
}

View File

@ -130,7 +130,7 @@ enum class ExprType : unsigned {
F32 = 0x7D,
F64 = 0x7C,
V128 = 0x7B,
ExceptRef = 0x68,
Exnref = 0x68,
Invalid = 0x00
};
@ -403,8 +403,8 @@ inline bool isCopy(unsigned Opc) {
case WebAssembly::COPY_F64_S:
case WebAssembly::COPY_V128:
case WebAssembly::COPY_V128_S:
case WebAssembly::COPY_EXCEPT_REF:
case WebAssembly::COPY_EXCEPT_REF_S:
case WebAssembly::COPY_EXNREF:
case WebAssembly::COPY_EXNREF_S:
return true;
default:
return false;
@ -453,8 +453,8 @@ inline bool isCallDirect(unsigned Opc) {
case WebAssembly::CALL_v4f32_S:
case WebAssembly::CALL_v2f64:
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_ExceptRef:
case WebAssembly::CALL_ExceptRef_S:
case WebAssembly::CALL_exnref:
case WebAssembly::CALL_exnref_S:
case WebAssembly::RET_CALL:
case WebAssembly::RET_CALL_S:
return true;
@ -487,8 +487,8 @@ inline bool isCallIndirect(unsigned Opc) {
case WebAssembly::CALL_INDIRECT_v4f32_S:
case WebAssembly::CALL_INDIRECT_v2f64:
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_ExceptRef:
case WebAssembly::CALL_INDIRECT_ExceptRef_S:
case WebAssembly::CALL_INDIRECT_exnref:
case WebAssembly::CALL_INDIRECT_exnref_S:
case WebAssembly::RET_CALL_INDIRECT:
case WebAssembly::RET_CALL_INDIRECT_S:
return true;
@ -530,8 +530,8 @@ inline unsigned getCalleeOpNo(unsigned Opc) {
case WebAssembly::CALL_v4f32_S:
case WebAssembly::CALL_v2f64:
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_ExceptRef:
case WebAssembly::CALL_ExceptRef_S:
case WebAssembly::CALL_exnref:
case WebAssembly::CALL_exnref_S:
case WebAssembly::CALL_INDIRECT_i32:
case WebAssembly::CALL_INDIRECT_i32_S:
case WebAssembly::CALL_INDIRECT_i64:
@ -552,8 +552,8 @@ inline unsigned getCalleeOpNo(unsigned Opc) {
case WebAssembly::CALL_INDIRECT_v4f32_S:
case WebAssembly::CALL_INDIRECT_v2f64:
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_ExceptRef:
case WebAssembly::CALL_INDIRECT_ExceptRef_S:
case WebAssembly::CALL_INDIRECT_exnref:
case WebAssembly::CALL_INDIRECT_exnref_S:
return 1;
default:
llvm_unreachable("Not a call instruction");

View File

@ -308,7 +308,7 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
// Add the BLOCK.
// 'br_on_exn' extracts except_ref object and pushes variable number of values
// 'br_on_exn' extracts exnref object and pushes variable number of values
// depending on its tag. For C++ exception, its a single i32 value, and the
// generated code will be in the form of:
// block i32
@ -766,11 +766,11 @@ bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
// Note that the new wrapping block/end_block will be generated later in
// placeBlockMarker.
//
// TODO Currently local.set and local.gets are generated to move except_ref
// value created by catches. That's because we don't support yielding values
// from a block in LLVM machine IR yet, even though it is supported by wasm.
// Delete unnecessary local.get/local.sets once yielding values from a block
// is supported. The full EH spec requires multi-value support to do this, but
// TODO Currently local.set and local.gets are generated to move exnref value
// created by catches. That's because we don't support yielding values from a
// block in LLVM machine IR yet, even though it is supported by wasm. Delete
// unnecessary local.get/local.sets once yielding values from a block is
// supported. The full EH spec requires multi-value support to do this, but
// for C++ we don't yet need it because we only throw a single i32.
//
// ---
@ -834,7 +834,7 @@ bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
DenseMap<MachineBasicBlock *, SmallVector<TryRange, 4>> UnwindDestToTryRanges;
// In new CFG, <destination to branch to, a vector of try ranges>
DenseMap<MachineBasicBlock *, SmallVector<TryRange, 4>> BrDestToTryRanges;
// In new CFG, <destination to branch to, register containing except_ref>
// In new CFG, <destination to branch to, register containing exnref>
DenseMap<MachineBasicBlock *, unsigned> BrDestToExnReg;
// Gather possibly throwing calls (i.e., previously invokes) whose current
@ -936,8 +936,7 @@ bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
// of the function with a local.get and a rethrow instruction.
if (NeedAppendixBlock) {
auto *AppendixBB = getAppendixBlock(MF);
unsigned ExnReg =
MRI.createVirtualRegister(&WebAssembly::EXCEPT_REFRegClass);
unsigned ExnReg = MRI.createVirtualRegister(&WebAssembly::EXNREFRegClass);
BuildMI(AppendixBB, DebugLoc(), TII.get(WebAssembly::RETHROW))
.addReg(ExnReg);
// These instruction ranges should branch to this appendix BB.
@ -1225,8 +1224,8 @@ void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
case MVT::v2f64:
RetType = WebAssembly::ExprType::V128;
break;
case MVT::ExceptRef:
RetType = WebAssembly::ExprType::ExceptRef;
case MVT::exnref:
RetType = WebAssembly::ExprType::Exnref;
break;
default:
llvm_unreachable("unexpected return type");

View File

@ -85,8 +85,8 @@ static unsigned getNonPseudoCallIndirectOpcode(const MachineInstr &MI) {
return CALL_INDIRECT_v4f32;
case PCALL_INDIRECT_v2f64:
return CALL_INDIRECT_v2f64;
case PCALL_INDIRECT_ExceptRef:
return CALL_INDIRECT_ExceptRef;
case PCALL_INDIRECT_exnref:
return CALL_INDIRECT_exnref;
case PRET_CALL_INDIRECT:
return RET_CALL_INDIRECT;
default:

View File

@ -90,8 +90,8 @@ static unsigned getDropOpcode(const TargetRegisterClass *RC) {
return WebAssembly::DROP_F64;
if (RC == &WebAssembly::V128RegClass)
return WebAssembly::DROP_V128;
if (RC == &WebAssembly::EXCEPT_REFRegClass)
return WebAssembly::DROP_EXCEPT_REF;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::DROP_EXNREF;
llvm_unreachable("Unexpected register class");
}
@ -107,8 +107,8 @@ static unsigned getLocalGetOpcode(const TargetRegisterClass *RC) {
return WebAssembly::LOCAL_GET_F64;
if (RC == &WebAssembly::V128RegClass)
return WebAssembly::LOCAL_GET_V128;
if (RC == &WebAssembly::EXCEPT_REFRegClass)
return WebAssembly::LOCAL_GET_EXCEPT_REF;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_GET_EXNREF;
llvm_unreachable("Unexpected register class");
}
@ -124,8 +124,8 @@ static unsigned getLocalSetOpcode(const TargetRegisterClass *RC) {
return WebAssembly::LOCAL_SET_F64;
if (RC == &WebAssembly::V128RegClass)
return WebAssembly::LOCAL_SET_V128;
if (RC == &WebAssembly::EXCEPT_REFRegClass)
return WebAssembly::LOCAL_SET_EXCEPT_REF;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_SET_EXNREF;
llvm_unreachable("Unexpected register class");
}
@ -141,8 +141,8 @@ static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC) {
return WebAssembly::LOCAL_TEE_F64;
if (RC == &WebAssembly::V128RegClass)
return WebAssembly::LOCAL_TEE_V128;
if (RC == &WebAssembly::EXCEPT_REFRegClass)
return WebAssembly::LOCAL_TEE_EXCEPT_REF;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_TEE_EXNREF;
llvm_unreachable("Unexpected register class");
}
@ -158,8 +158,8 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {
return MVT::f64;
if (RC == &WebAssembly::V128RegClass)
return MVT::v16i8;
if (RC == &WebAssembly::EXCEPT_REFRegClass)
return MVT::ExceptRef;
if (RC == &WebAssembly::EXNREFRegClass)
return MVT::exnref;
llvm_unreachable("unrecognized register class");
}

View File

@ -129,7 +129,7 @@ private:
case MVT::i64:
case MVT::f32:
case MVT::f64:
case MVT::ExceptRef:
case MVT::exnref:
return VT;
case MVT::f16:
return MVT::f32;
@ -698,9 +698,9 @@ bool WebAssemblyFastISel::fastLowerArguments() {
Opc = WebAssembly::ARGUMENT_v2f64;
RC = &WebAssembly::V128RegClass;
break;
case MVT::ExceptRef:
Opc = WebAssembly::ARGUMENT_ExceptRef;
RC = &WebAssembly::EXCEPT_REFRegClass;
case MVT::exnref:
Opc = WebAssembly::ARGUMENT_exnref;
RC = &WebAssembly::EXNREFRegClass;
break;
default:
return false;
@ -815,10 +815,10 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
: WebAssembly::PCALL_INDIRECT_v2f64;
ResultReg = createResultReg(&WebAssembly::V128RegClass);
break;
case MVT::ExceptRef:
Opc = IsDirect ? WebAssembly::CALL_ExceptRef
: WebAssembly::PCALL_INDIRECT_ExceptRef;
ResultReg = createResultReg(&WebAssembly::EXCEPT_REFRegClass);
case MVT::exnref:
Opc = IsDirect ? WebAssembly::CALL_exnref
: WebAssembly::PCALL_INDIRECT_exnref;
ResultReg = createResultReg(&WebAssembly::EXNREFRegClass);
break;
default:
return false;
@ -921,9 +921,9 @@ bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
Opc = WebAssembly::SELECT_F64;
RC = &WebAssembly::F64RegClass;
break;
case MVT::ExceptRef:
Opc = WebAssembly::SELECT_EXCEPT_REF;
RC = &WebAssembly::EXCEPT_REFRegClass;
case MVT::exnref:
Opc = WebAssembly::SELECT_EXNREF;
RC = &WebAssembly::EXNREFRegClass;
break;
default:
return false;
@ -1341,8 +1341,8 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) {
case MVT::v2f64:
Opc = WebAssembly::RETURN_v2f64;
break;
case MVT::ExceptRef:
Opc = WebAssembly::RETURN_EXCEPT_REF;
case MVT::exnref:
Opc = WebAssembly::RETURN_EXNREF;
break;
default:
return false;

View File

@ -59,7 +59,7 @@ defm "" : CALL<i32, I32, "i32.">;
defm "" : CALL<i64, I64, "i64.">;
defm "" : CALL<f32, F32, "f32.">;
defm "" : CALL<f64, F64, "f64.">;
defm "" : CALL<ExceptRef, EXCEPT_REF, "except_ref.", [HasExceptionHandling]>;
defm "" : CALL<exnref, EXNREF, "exnref.", [HasExceptionHandling]>;
defm "" : CALL<v16i8, V128, "v128.", [HasSIMD128]>;
defm "" : CALL<v8i16, V128, "v128.", [HasSIMD128]>;
defm "" : CALL<v4i32, V128, "v128.", [HasSIMD128]>;
@ -139,9 +139,8 @@ def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
(CALL_v4f32 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
def : Pat<(v2f64 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
(CALL_v2f64 tglobaladdr:$callee)>, Requires<[HasSIMD128]>;
def : Pat<(ExceptRef
(WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
(CALL_ExceptRef tglobaladdr:$callee)>,
def : Pat<(exnref (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
(CALL_exnref tglobaladdr:$callee)>,
Requires<[HasExceptionHandling]>;
def : Pat<(WebAssemblycall0 (WebAssemblywrapper tglobaladdr:$callee)),
(CALL_VOID tglobaladdr:$callee)>;
@ -169,9 +168,8 @@ def : Pat<(v4f32 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
(CALL_v4f32 texternalsym:$callee)>, Requires<[HasSIMD128]>;
def : Pat<(v2f64 (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
(CALL_v2f64 texternalsym:$callee)>, Requires<[HasSIMD128]>;
def : Pat<(ExceptRef
(WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
(CALL_ExceptRef texternalsym:$callee)>,
def : Pat<(exnref (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
(CALL_exnref texternalsym:$callee)>,
Requires<[HasExceptionHandling]>;
def : Pat<(WebAssemblycall0 (WebAssemblywrapper texternalsym:$callee)),
(CALL_VOID texternalsym:$callee)>;

View File

@ -114,7 +114,7 @@ let isReturn = 1 in {
defm "": RETURN<I64>;
defm "": RETURN<F32>;
defm "": RETURN<F64>;
defm "": RETURN<EXCEPT_REF>;
defm "": RETURN<EXNREF>;
defm "": SIMD_RETURN<v16i8>;
defm "": SIMD_RETURN<v8i16>;
defm "": SIMD_RETURN<v4i32>;
@ -144,8 +144,8 @@ 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>;
defm RETHROW : I<(outs), (ins EXCEPT_REF:$exn), (outs), (ins),
[], "rethrow \t$exn", "rethrow", 0x09>;
defm RETHROW : I<(outs), (ins EXNREF:$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
@ -161,15 +161,15 @@ defm END_TRY : NRI<(outs), (ins), [], "end_try", 0x0b>;
// Catching an exception: catch / extract_exception
let hasCtrlDep = 1, hasSideEffects = 1 in
defm CATCH : I<(outs EXCEPT_REF:$dst), (ins), (outs), (ins), [],
defm CATCH : I<(outs EXNREF:$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
// br_on_exn queries an exnref 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),
defm BR_ON_EXN : I<(outs), (ins bb_op:$dst, event_op:$tag, EXNREF:$exn),
(outs), (ins bb_op:$dst, event_op:$tag), [],
"br_on_exn \t$dst, $tag, $exn", "br_on_exn \t$dst, $tag",
0x0a>;

View File

@ -1,26 +0,0 @@
// WebAssemblyInstrExceptRef.td-WebAssembly except_ref codegen --*- tablegen -*-
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// WebAssembly except_ref operand code-gen constructs.
///
//===----------------------------------------------------------------------===//
defm SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst),
(ins EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond),
(outs), (ins),
[(set EXCEPT_REF:$dst,
(select I32:$cond, EXCEPT_REF:$lhs,
EXCEPT_REF:$rhs))],
"except_ref.select\t$dst, $lhs, $rhs, $cond",
"except_ref.select", 0x1b>;
def : Pat<(select (i32 (setne I32:$cond, 0)), EXCEPT_REF:$lhs, EXCEPT_REF:$rhs),
(SELECT_EXCEPT_REF EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond)>;
def : Pat<(select (i32 (seteq I32:$cond, 0)), EXCEPT_REF:$lhs, EXCEPT_REF:$rhs),
(SELECT_EXCEPT_REF EXCEPT_REF:$rhs, EXCEPT_REF:$lhs, I32:$cond)>;

View File

@ -192,7 +192,7 @@ unsigned WebAssemblyInstrInfo::insertBranch(
MachineFunction &MF = *MBB.getParent();
auto &MRI = MF.getRegInfo();
bool IsBrOnExn = Cond[1].isReg() && MRI.getRegClass(Cond[1].getReg()) ==
&WebAssembly::EXCEPT_REFRegClass;
&WebAssembly::EXNREFRegClass;
if (Cond[0].getImm()) {
if (IsBrOnExn) {
@ -222,7 +222,7 @@ bool WebAssemblyInstrInfo::reverseBranchCondition(
MachineFunction &MF = *Cond[1].getParent()->getParent()->getParent();
auto &MRI = MF.getRegInfo();
if (Cond[1].isReg() &&
MRI.getRegClass(Cond[1].getReg()) == &WebAssembly::EXCEPT_REFRegClass)
MRI.getRegClass(Cond[1].getReg()) == &WebAssembly::EXNREFRegClass)
return true;
Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm());

View File

@ -224,7 +224,7 @@ defm "": ARGUMENT<I32, i32>;
defm "": ARGUMENT<I64, i64>;
defm "": ARGUMENT<F32, f32>;
defm "": ARGUMENT<F64, f64>;
defm "": ARGUMENT<EXCEPT_REF, ExceptRef>;
defm "": ARGUMENT<EXNREF, exnref>;
// local.get and local.set are not generated by instruction selection; they
// are implied by virtual register uses and defs.
@ -294,7 +294,7 @@ defm "" : LOCAL<I64>;
defm "" : LOCAL<F32>;
defm "" : LOCAL<F64>;
defm "" : LOCAL<V128>, Requires<[HasSIMD128]>;
defm "" : LOCAL<EXCEPT_REF>, Requires<[HasExceptionHandling]>;
defm "" : LOCAL<EXNREF>, Requires<[HasExceptionHandling]>;
let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
defm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
@ -345,5 +345,5 @@ include "WebAssemblyInstrConv.td"
include "WebAssemblyInstrFloat.td"
include "WebAssemblyInstrAtomics.td"
include "WebAssemblyInstrSIMD.td"
include "WebAssemblyInstrExceptRef.td"
include "WebAssemblyInstrRef.td"
include "WebAssemblyInstrBulkMemory.td"

View File

@ -0,0 +1,25 @@
// WebAssemblyInstrRef.td - WebAssembly reference type codegen --*- tablegen -*-
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// WebAssembly refence type operand codegen constructs.
///
//===----------------------------------------------------------------------===//
defm SELECT_EXNREF : I<(outs EXNREF:$dst),
(ins EXNREF:$lhs, EXNREF:$rhs, I32:$cond),
(outs), (ins),
[(set EXNREF:$dst,
(select I32:$cond, EXNREF:$lhs, EXNREF:$rhs))],
"exnref.select\t$dst, $lhs, $rhs, $cond",
"exnref.select", 0x1b>;
def : Pat<(select (i32 (setne I32:$cond, 0)), EXNREF:$lhs, EXNREF:$rhs),
(SELECT_EXNREF EXNREF:$lhs, EXNREF:$rhs, I32:$cond)>;
def : Pat<(select (i32 (seteq I32:$cond, 0)), EXNREF:$lhs, EXNREF:$rhs),
(SELECT_EXNREF EXNREF:$rhs, EXNREF:$lhs, I32:$cond)>;

View File

@ -131,8 +131,7 @@ bool WebAssemblyLateEHPrepare::addCatches(MachineFunction &MF) {
auto InsertPos = MBB.begin();
if (InsertPos->isEHLabel()) // EH pad starts with an EH label
++InsertPos;
unsigned DstReg =
MRI.createVirtualRegister(&WebAssembly::EXCEPT_REFRegClass);
unsigned DstReg = MRI.createVirtualRegister(&WebAssembly::EXNREFRegClass);
BuildMI(MBB, InsertPos, MBB.begin()->getDebugLoc(),
TII.get(WebAssembly::CATCH), DstReg);
}
@ -209,23 +208,23 @@ bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables(
}
// Wasm uses 'br_on_exn' instruction to check the tag of an exception. It takes
// except_ref type object returned by 'catch', and branches to the destination
// if it matches a given tag. We currently use __cpp_exception symbol to
// represent the tag for all C++ exceptions.
// exnref type object returned by 'catch', and branches to the destination if it
// matches a given tag. We currently use __cpp_exception symbol to represent the
// tag for all C++ exceptions.
//
// block $l (result i32)
// ...
// ;; except_ref $e is on the stack at this point
// ;; exnref $e is on the stack at this point
// br_on_exn $l $e ;; branch to $l with $e's arguments
// ...
// end
// ;; Here we expect the extracted values are on top of the wasm value stack
// ... Handle exception using values ...
//
// br_on_exn takes an except_ref object and branches if it matches the given
// tag. There can be multiple br_on_exn instructions if we want to match for
// another tag, but for now we only test for __cpp_exception tag, and if it does
// not match, i.e., it is a foreign exception, we rethrow it.
// br_on_exn takes an exnref object and branches if it matches the given tag.
// There can be multiple br_on_exn instructions if we want to match for another
// tag, but for now we only test for __cpp_exception tag, and if it does not
// match, i.e., it is a foreign exception, we rethrow it.
//
// In the destination BB that's the target of br_on_exn, extracted exception
// values (in C++'s case a single i32, which represents an exception pointer)
@ -279,13 +278,13 @@ bool WebAssemblyLateEHPrepare::addExceptionExtraction(MachineFunction &MF) {
// - Before:
// ehpad:
// %exnref:except_ref = catch
// %exnref:exnref = catch
// %exn:i32 = extract_exception
// ... use exn ...
//
// - After:
// ehpad:
// %exnref:except_ref = catch
// %exnref:exnref = catch
// br_on_exn %thenbb, $__cpp_exception, %exnref
// br %elsebb
// elsebb:
@ -317,14 +316,14 @@ bool WebAssemblyLateEHPrepare::addExceptionExtraction(MachineFunction &MF) {
//
// - Before:
// ehpad:
// %exnref:except_ref = catch
// %exnref:exnref = catch
// %exn:i32 = extract_exception
// call @__clang_call_terminate(%exn)
// unreachable
//
// - After:
// ehpad:
// %exnref:except_ref = catch
// %exnref:exnref = catch
// br_on_exn %thenbb, $__cpp_exception, %exnref
// br %elsebb
// elsebb:

View File

@ -834,9 +834,9 @@ bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
// entering blocks, which is a part of multi-value proposal.
//
// Once we support live-in values of wasm blocks, this can be:
// catch ; push except_ref value onto stack
// block except_ref -> i32
// br_on_exn $__cpp_exception ; pop the except_ref value
// catch ; push exnref value onto stack
// block exnref -> i32
// br_on_exn $__cpp_exception ; pop the exnref value
// end_block
//
// But because we don't support it yet, the catch instruction's dst

View File

@ -43,7 +43,7 @@ def F64_0 : WebAssemblyReg<"%f64.0">;
def V128_0: WebAssemblyReg<"%v128">;
def EXCEPT_REF_0 : WebAssemblyReg<"%except_ref.0">;
def EXNREF_0 : WebAssemblyReg<"%exnref.0">;
// The value stack "register". This is an opaque entity which serves to order
// uses and defs that must remain in LIFO order.
@ -64,4 +64,4 @@ def F32 : WebAssemblyRegClass<[f32], 32, (add F32_0)>;
def F64 : WebAssemblyRegClass<[f64], 64, (add F64_0)>;
def V128 : WebAssemblyRegClass<[v4f32, v2f64, v2i64, v4i32, v16i8, v8i16], 128,
(add V128_0)>;
def EXCEPT_REF : WebAssemblyRegClass<[ExceptRef], 0, (add EXCEPT_REF_0)>;
def EXNREF : WebAssemblyRegClass<[exnref], 0, (add EXNREF_0)>;

View File

@ -31,11 +31,11 @@ define void @test_throw(i8* %p) {
; CHECK: global.get ${{.+}}=, __stack_pointer
; CHECK: try
; CHECK: call foo
; CHECK: catch $[[EXCEPT_REF:[0-9]+]]=
; CHECK: catch $[[EXNREF:[0-9]+]]=
; CHECK: global.set __stack_pointer
; CHECK: block i32
; CHECK: br_on_exn 0, __cpp_exception, $[[EXCEPT_REF]]
; CHECK: rethrow $[[EXCEPT_REF]]
; CHECK: br_on_exn 0, __cpp_exception, $[[EXNREF]]
; CHECK: rethrow $[[EXNREF]]
; CHECK: end_block
; CHECK: extract_exception $[[EXN:[0-9]+]]=
; CHECK-DAG: i32.store __wasm_lpad_context
@ -47,7 +47,7 @@ define void @test_throw(i8* %p) {
; CHECK: call __cxa_end_catch
; CHECK: br 1
; CHECK: end_block
; CHECK: rethrow $[[EXCEPT_REF]]
; CHECK: rethrow $[[EXNREF]]
; CHECK: end_try
define void @test_catch() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
entry:
@ -92,10 +92,10 @@ try.cont: ; preds = %entry, %catch
; CHECK-LABEL: test_cleanup:
; CHECK: try
; CHECK: call foo
; CHECK: catch $[[EXCEPT_REF:[0-9]+]]=
; CHECK: catch $[[EXNREF:[0-9]+]]=
; CHECK: global.set __stack_pointer
; CHECK: i32.call $drop=, _ZN4TempD2Ev
; CHECK: rethrow $[[EXCEPT_REF]]
; CHECK: rethrow $[[EXNREF]]
; CHECK: end_try
define void @test_cleanup() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
entry:

View File

@ -23,7 +23,7 @@
0x11 0x80 0x01 0x00
# CHECK: call 0
# CHECK-NOT: except_ref.call 0
# CHECK-NOT: exnref.call 0
0x10 0x00
# CHECK: local.get 128

View File

@ -70,7 +70,7 @@ test0:
# TODO: enable once instruction has been added.
#i32x4.trunc_sat_f32x4_s
i32.trunc_f32_s
try except_ref
try exnref
i32.atomic.load 0
atomic.notify 0
.LBB0_3:
@ -172,7 +172,7 @@ test0:
# CHECK-NEXT: end_if
# CHECK-NEXT: f32x4.add
# CHECK-NEXT: i32.trunc_f32_s
# CHECK-NEXT: try except_ref
# CHECK-NEXT: try exnref
# CHECK-NEXT: i32.atomic.load 0
# CHECK-NEXT: atomic.notify 0
# CHECK-NEXT: .LBB0_3:

View File

@ -9,7 +9,7 @@ test0:
test1:
.functype test1 (i32, i64) -> (i32)
.local i32, i64, except_ref
.local i32, i64, exnref
local.get 3
end_function
@ -21,6 +21,6 @@ test1:
# CHECK-NEXT: 9: 20 02 local.get 2
# CHECK-NEXT: b: 0b end
# CHECK-LABEL: test1:
# CHECK-NEXT: .local i32, i64, except_ref
# CHECK-NEXT: .local i32, i64, exnref
# CHECK-NEXT: 14: 20 03 local.get 3
# CHECK-NEXT: 16: 0b end

View File

@ -100,14 +100,14 @@ body: |
; predecessors: %bb.0
successors: %bb.3, %bb.9
liveins: $value_stack
%0:except_ref = CATCH implicit-def $arguments
%0:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.3 (landing-pad):
; predecessors: %bb.2
successors: %bb.4, %bb.6
liveins: $value_stack
%1:except_ref = CATCH implicit-def $arguments
%1:exnref = CATCH implicit-def $arguments
BR_IF %bb.4, %58:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
BR %bb.6, implicit-def $arguments
@ -138,13 +138,13 @@ body: |
; predecessors: %bb.4
successors: %bb.9
liveins: $value_stack
%2:except_ref = CATCH implicit-def $arguments
%2:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.9 (landing-pad):
; predecessors: %bb.2, %bb.6, %bb.8
liveins: $value_stack
%3:except_ref = CATCH implicit-def $arguments
%3:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.10:
@ -257,7 +257,7 @@ body: |
; predecessors: %bb.0
successors: %bb.2, %bb.8
liveins: $value_stack
%0:except_ref = CATCH implicit-def $arguments
%0:exnref = CATCH implicit-def $arguments
BR_IF %bb.2, %32:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
BR %bb.8, implicit-def $arguments
@ -271,7 +271,7 @@ body: |
; predecessors: %bb.2
successors: %bb.4, %bb.6
liveins: $value_stack
%1:except_ref = CATCH implicit-def $arguments
%1:exnref = CATCH implicit-def $arguments
BR_IF %bb.4, %43:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
BR %bb.6, implicit-def $arguments
@ -313,13 +313,13 @@ body: |
; predecessors: %bb.4
successors: %bb.11
liveins: $value_stack
%2:except_ref = CATCH implicit-def $arguments
%2:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.11 (landing-pad):
; predecessors: %bb.2, %bb.6, %bb.10
liveins: $value_stack
%3:except_ref = CATCH implicit-def $arguments
%3:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.12:

View File

@ -191,7 +191,7 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::iPTR: return "MVT::iPTR";
case MVT::iPTRAny: return "MVT::iPTRAny";
case MVT::Untyped: return "MVT::Untyped";
case MVT::ExceptRef: return "MVT::ExceptRef";
case MVT::exnref: return "MVT::exnref";
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
}
}