mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-15 00:16:42 +00:00
[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:
parent
a7eae67847
commit
b29d4ba62f
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)>;
|
||||
|
@ -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>;
|
||||
|
@ -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)>;
|
@ -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());
|
||||
|
@ -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"
|
||||
|
25
lib/Target/WebAssembly/WebAssemblyInstrRef.td
Normal file
25
lib/Target/WebAssembly/WebAssemblyInstrRef.td
Normal 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)>;
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)>;
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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!");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user