summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2019-01-30 03:21:57 +0000
committerHeejin Ahn <aheejin@gmail.com>2019-01-30 03:21:57 +0000
commitd6f487863dc951d467b545b86b9ea62980569b5a (patch)
treef0e3f8ee6a6f6060ed36e9b63320fbd2499f93df /llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
parent6d8e1b456a23d6c75be160fc67b0889e2bfe2170 (diff)
downloadbcm5719-llvm-d6f487863dc951d467b545b86b9ea62980569b5a.tar.gz
bcm5719-llvm-d6f487863dc951d467b545b86b9ea62980569b5a.zip
[WebAssembly] Exception handling: Switch to the new proposal
Summary: This switches the EH implementation to the new proposal: https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md (The previous proposal was https://github.com/WebAssembly/exception-handling/blob/master/proposals/old/Exceptions.md) - Instruction changes - Now we have one single `catch` instruction that returns a except_ref value - `throw` now can take variable number of operations - `rethrow` does not have 'depth' argument anymore - `br_on_exn` queries an except_ref to see if it matches the tag and branches to the given label if true. - `extract_exception` is a pseudo instruction that simulates popping values from wasm stack. This is to make `br_on_exn`, a very special instruction, work: `br_on_exn` puts values onto the stack only if it is taken, and the # of values can vay depending on the tag. - Now there's only one `catch` per `try`, this patch removes all special handling for terminate pad with a call to `__clang_call_terminate`. Before it was the only case there are two catch clauses (a normal `catch` and `catch_all` per `try`). - Make `rethrow` act as a terminator like `throw`. This splits BB after `rethrow` in WasmEHPrepare, and deletes an unnecessary `unreachable` after `rethrow` in LateEHPrepare. - Now we stop at all catchpads (because we add wasm `catch` instruction that catches all exceptions), this creates new `findWasmUnwindDestinations` function in SelectionDAGBuilder. - Now we use `br_on_exn` instrution to figure out if an except_ref matches the current tag or not, LateEHPrepare generates this sequence for catch pads: ``` catch block i32 br_on_exn $__cpp_exception end_block extract_exception ``` - Branch analysis for `br_on_exn` in WebAssemblyInstrInfo - Other various misc. changes to switch to the new proposal. Reviewers: dschuff Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D57134 llvm-svn: 352598
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp76
1 files changed, 35 insertions, 41 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 7cb7f2750ff..52d9d282159 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -884,13 +884,13 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
return LowerFRAMEADDR(Op, DAG);
case ISD::CopyToReg:
return LowerCopyToReg(Op, DAG);
- case ISD::INTRINSIC_WO_CHAIN:
- return LowerINTRINSIC_WO_CHAIN(Op, DAG);
case ISD::EXTRACT_VECTOR_ELT:
case ISD::INSERT_VECTOR_ELT:
return LowerAccessVectorElement(Op, DAG);
case ISD::INTRINSIC_VOID:
- return LowerINTRINSIC_VOID(Op, DAG);
+ case ISD::INTRINSIC_WO_CHAIN:
+ case ISD::INTRINSIC_W_CHAIN:
+ return LowerIntrinsic(Op, DAG);
case ISD::SIGN_EXTEND_INREG:
return LowerSIGN_EXTEND_INREG(Op, DAG);
case ISD::BUILD_VECTOR:
@@ -1035,17 +1035,28 @@ SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op,
MachinePointerInfo(SV), 0);
}
-SDValue
-WebAssemblyTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
- SelectionDAG &DAG) const {
- unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
+SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
+ SelectionDAG &DAG) const {
+ MachineFunction &MF = DAG.getMachineFunction();
+ unsigned IntNo;
+ switch (Op.getOpcode()) {
+ case ISD::INTRINSIC_VOID:
+ case ISD::INTRINSIC_W_CHAIN:
+ IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
+ break;
+ case ISD::INTRINSIC_WO_CHAIN:
+ IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
+ break;
+ default:
+ llvm_unreachable("Invalid intrinsic");
+ }
SDLoc DL(Op);
+
switch (IntNo) {
default:
return {}; // Don't custom lower most intrinsics.
case Intrinsic::wasm_lsda: {
- MachineFunction &MF = DAG.getMachineFunction();
EVT VT = Op.getValueType();
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
@@ -1055,43 +1066,26 @@ WebAssemblyTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
DAG.getMCSymbol(S, PtrVT));
}
- }
-}
-
-SDValue
-WebAssemblyTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
- SelectionDAG &DAG) const {
- MachineFunction &MF = DAG.getMachineFunction();
- unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
- SDLoc DL(Op);
-
- switch (IntNo) {
- default:
- return {}; // Don't custom lower most intrinsics.
case Intrinsic::wasm_throw: {
+ // We only support C++ exceptions for now
int Tag = cast<ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
- switch (Tag) {
- case CPP_EXCEPTION: {
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
- const char *SymName = MF.createExternalSymbolName("__cpp_exception");
- SDValue SymNode =
- DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
- DAG.getTargetExternalSymbol(
- SymName, PtrVT, WebAssemblyII::MO_SYMBOL_EVENT));
- return DAG.getNode(WebAssemblyISD::THROW, DL,
- MVT::Other, // outchain type
- {
- Op.getOperand(0), // inchain
- SymNode, // exception symbol
- Op.getOperand(3) // thrown value
- });
- }
- default:
+ if (Tag != CPP_EXCEPTION)
llvm_unreachable("Invalid tag!");
- }
- break;
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
+ const char *SymName = MF.createExternalSymbolName("__cpp_exception");
+ SDValue SymNode =
+ DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
+ DAG.getTargetExternalSymbol(
+ SymName, PtrVT, WebAssemblyII::MO_SYMBOL_EVENT));
+ return DAG.getNode(WebAssemblyISD::THROW, DL,
+ MVT::Other, // outchain type
+ {
+ Op.getOperand(0), // inchain
+ SymNode, // exception symbol
+ Op.getOperand(3) // thrown value
+ });
}
}
}
OpenPOWER on IntegriCloud