From 9f96a58cccb63110ca9515644c454620c86c566d Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Mon, 15 Jul 2019 22:49:25 +0000 Subject: [PATCH] [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 llvm-svn: 366145 --- lld/wasm/WriterUtils.cpp | 4 ++-- llvm/include/llvm/BinaryFormat/Wasm.h | 4 ++-- llvm/include/llvm/CodeGen/ValueTypes.td | 2 +- llvm/include/llvm/Support/MachineValueType.h | 4 ++-- llvm/lib/CodeGen/ValueTypes.cpp | 2 +- .../WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 6 ++--- .../MCTargetDesc/WebAssemblyInstPrinter.cpp | 4 ++-- .../MCTargetDesc/WebAssemblyMCTargetDesc.cpp | 4 ++-- .../MCTargetDesc/WebAssemblyMCTargetDesc.h | 22 +++++++++--------- .../Target/WebAssembly/WebAssemblyCFGStackify.cpp | 21 ++++++++--------- .../WebAssembly/WebAssemblyCallIndirectFixup.cpp | 4 ++-- .../WebAssembly/WebAssemblyExplicitLocals.cpp | 20 ++++++++-------- .../lib/Target/WebAssembly/WebAssemblyFastISel.cpp | 26 ++++++++++----------- .../lib/Target/WebAssembly/WebAssemblyInstrCall.td | 12 ++++------ .../Target/WebAssembly/WebAssemblyInstrControl.td | 14 +++++------ .../WebAssembly/WebAssemblyInstrExceptRef.td | 26 --------------------- .../Target/WebAssembly/WebAssemblyInstrInfo.cpp | 4 ++-- .../lib/Target/WebAssembly/WebAssemblyInstrInfo.td | 6 ++--- llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td | 25 ++++++++++++++++++++ .../WebAssembly/WebAssemblyLateEHPrepare.cpp | 27 +++++++++++----------- .../Target/WebAssembly/WebAssemblyRegStackify.cpp | 6 ++--- .../Target/WebAssembly/WebAssemblyRegisterInfo.td | 4 ++-- llvm/test/CodeGen/WebAssembly/exception.ll | 12 +++++----- llvm/test/MC/Disassembler/WebAssembly/wasm.txt | 2 +- llvm/test/MC/WebAssembly/basic-assembly.s | 4 ++-- llvm/test/MC/WebAssembly/objdump.s | 4 ++-- .../WebAssembly/WebAssemblyExceptionInfoTest.cpp | 16 ++++++------- llvm/utils/TableGen/CodeGenTarget.cpp | 2 +- 28 files changed, 141 insertions(+), 146 deletions(-) delete mode 100644 llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td create mode 100644 llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td diff --git a/lld/wasm/WriterUtils.cpp b/lld/wasm/WriterUtils.cpp index d45f6a4..913723c 100644 --- a/lld/wasm/WriterUtils.cpp +++ b/lld/wasm/WriterUtils.cpp @@ -182,8 +182,8 @@ std::string lld::toString(ValType type) { return "f64"; case ValType::V128: return "v128"; - case ValType::EXCEPT_REF: - return "except_ref"; + case ValType::EXNREF: + return "exnref"; } llvm_unreachable("Invalid wasm::ValType"); } diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h index 0ff52cb..4f6c24b 100644 --- a/llvm/include/llvm/BinaryFormat/Wasm.h +++ b/llvm/include/llvm/BinaryFormat/Wasm.h @@ -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 { diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td index feea7e5..5818ac1 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/llvm/include/llvm/CodeGen/ValueTypes.td @@ -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 diff --git a/llvm/include/llvm/Support/MachineValueType.h b/llvm/include/llvm/Support/MachineValueType.h index a9b130f..b94d2c4 100644 --- a/llvm/include/llvm/Support/MachineValueType.h +++ b/llvm/include/llvm/Support/MachineValueType.h @@ -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 } } diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp index ac08877..a911cdc 100644 --- a/llvm/lib/CodeGen/ValueTypes.cpp +++ b/llvm/lib/CodeGen/ValueTypes.cpp @@ -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"; } } diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index e9a7f69..09628e8 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -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(); } @@ -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); } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp index cfa808b..a439b72 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp @@ -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: diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp index 21545c3..9c8ca1f 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp @@ -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"); } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index a0d526b..31ad88b 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -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"); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp index a23a47d..e6bfc52 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp @@ -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> UnwindDestToTryRanges; // In new CFG, DenseMap> BrDestToTryRanges; - // In new CFG, + // In new CFG, DenseMap 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"); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCallIndirectFixup.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCallIndirectFixup.cpp index 313147c..2537e60 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyCallIndirectFixup.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyCallIndirectFixup.cpp @@ -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: diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index de7e912..dbd6217 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -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"); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index 4fff49f..1a24f74 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -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; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td index bcff9f2..703c15d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td @@ -59,7 +59,7 @@ defm "" : CALL; defm "" : CALL; defm "" : CALL; defm "" : CALL; -defm "" : CALL; +defm "" : CALL; defm "" : CALL; defm "" : CALL; defm "" : CALL; @@ -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)>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td index 574cb09..1870c5b 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td @@ -114,7 +114,7 @@ let isReturn = 1 in { defm "": RETURN; defm "": RETURN; defm "": RETURN; - defm "": RETURN; + defm "": RETURN; defm "": SIMD_RETURN; defm "": SIMD_RETURN; defm "": SIMD_RETURN; @@ -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>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td deleted file mode 100644 index 33a4f25..0000000 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td +++ /dev/null @@ -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)>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp index ee69811..d7022ce 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -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()); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td index 859cb9b..73ddbe8 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -224,7 +224,7 @@ defm "": ARGUMENT; defm "": ARGUMENT; defm "": ARGUMENT; defm "": ARGUMENT; -defm "": ARGUMENT; +defm "": ARGUMENT; // 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; defm "" : LOCAL; defm "" : LOCAL; defm "" : LOCAL, Requires<[HasSIMD128]>; -defm "" : LOCAL, Requires<[HasExceptionHandling]>; +defm "" : LOCAL, 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" diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td new file mode 100644 index 0000000..afe89de --- /dev/null +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrRef.td @@ -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)>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp index 49258de..e92b344 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp @@ -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: diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp index 31ba6f0..a120a64 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp @@ -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 diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td index 4d202f7..6d3d6c7 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td @@ -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)>; diff --git a/llvm/test/CodeGen/WebAssembly/exception.ll b/llvm/test/CodeGen/WebAssembly/exception.ll index 8f7687e..fc61f40 100644 --- a/llvm/test/CodeGen/WebAssembly/exception.ll +++ b/llvm/test/CodeGen/WebAssembly/exception.ll @@ -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: diff --git a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt index e979bac..08cc954 100644 --- a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt +++ b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt @@ -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 diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s index c3b7e9d..23b1a09 100644 --- a/llvm/test/MC/WebAssembly/basic-assembly.s +++ b/llvm/test/MC/WebAssembly/basic-assembly.s @@ -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: diff --git a/llvm/test/MC/WebAssembly/objdump.s b/llvm/test/MC/WebAssembly/objdump.s index f1cedc7..4030ba9 100644 --- a/llvm/test/MC/WebAssembly/objdump.s +++ b/llvm/test/MC/WebAssembly/objdump.s @@ -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 diff --git a/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp index ec94637..49a469b 100644 --- a/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp +++ b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp @@ -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: diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index dc45b1d..7023172 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -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!"); } } -- 2.7.4