diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/CodeGen/WasmEHPrepare.cpp | 55 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp | 19 |
5 files changed, 61 insertions, 38 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 31768b2f9b2..6a88948ac6b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2697,6 +2697,20 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { case Intrinsic::experimental_gc_statepoint: LowerStatepoint(ImmutableStatepoint(&I), EHPadBB); break; + case Intrinsic::wasm_rethrow_in_catch: { + // This is usually done in visitTargetIntrinsic, but this intrinsic is + // special because it can be invoked, so we manually lower it to a DAG + // node here. + SmallVector<SDValue, 8> Ops; + Ops.push_back(getRoot()); // inchain + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + Ops.push_back( + DAG.getTargetConstant(Intrinsic::wasm_rethrow_in_catch, getCurSDLoc(), + TLI.getPointerTy(DAG.getDataLayout()))); + SDVTList VTs = DAG.getVTList(ArrayRef<EVT>({MVT::Other})); // outchain + DAG.setRoot(DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops)); + break; + } } } else if (I.countOperandBundlesOfType(LLVMContext::OB_deopt)) { // Currently we do not lower any intrinsic calls with deopt operand bundles. diff --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp index a58da13d9b0..865a1cfbf43 100644 --- a/llvm/lib/CodeGen/WasmEHPrepare.cpp +++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp @@ -104,15 +104,14 @@ class WasmEHPrepare : public FunctionPass { Value *LSDAField = nullptr; // lsda field Value *SelectorField = nullptr; // selector - Function *ThrowF = nullptr; // wasm.throw() intrinsic - Function *RethrowF = nullptr; // wasm.rethrow() intrinsic - Function *LPadIndexF = nullptr; // wasm.landingpad.index() intrinsic - Function *LSDAF = nullptr; // wasm.lsda() intrinsic - Function *GetExnF = nullptr; // wasm.get.exception() intrinsic - Function *ExtractExnF = nullptr; // wasm.extract.exception() intrinsic - Function *GetSelectorF = nullptr; // wasm.get.ehselector() intrinsic + Function *ThrowF = nullptr; // wasm.throw() intrinsic + Function *LPadIndexF = nullptr; // wasm.landingpad.index() intrinsic + Function *LSDAF = nullptr; // wasm.lsda() intrinsic + Function *GetExnF = nullptr; // wasm.get.exception() intrinsic + Function *ExtractExnF = nullptr; // wasm.extract.exception() intrinsic + Function *GetSelectorF = nullptr; // wasm.get.ehselector() intrinsic FunctionCallee CallPersonalityF = - nullptr; // _Unwind_CallPersonality() wrapper + nullptr; // _Unwind_CallPersonality() wrapper bool prepareEHPads(Function &F); bool prepareThrows(Function &F); @@ -177,29 +176,23 @@ bool WasmEHPrepare::prepareThrows(Function &F) { // wasm.throw() intinsic, which will be lowered to wasm 'throw' instruction. ThrowF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_throw); - // wasm.rethrow() intinsic, which will be lowered to wasm 'rethrow' - // instruction. - RethrowF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_rethrow); - - // Insert an unreachable instruction after a call to @llvm.wasm.throw / - // @llvm.wasm.rethrow and delete all following instructions within the BB, and - // delete all the dead children of the BB as well. - for (auto L : {ThrowF->users(), RethrowF->users()}) { - for (User *U : L) { - // A call to @llvm.wasm.throw() is only generated from __cxa_throw() - // builtin call within libcxxabi, and cannot be an InvokeInst. - auto *ThrowI = cast<CallInst>(U); - if (ThrowI->getFunction() != &F) - continue; - Changed = true; - auto *BB = ThrowI->getParent(); - SmallVector<BasicBlock *, 4> Succs(succ_begin(BB), succ_end(BB)); - auto &InstList = BB->getInstList(); - InstList.erase(std::next(BasicBlock::iterator(ThrowI)), InstList.end()); - IRB.SetInsertPoint(BB); - IRB.CreateUnreachable(); - eraseDeadBBsAndChildren(Succs); - } + // Insert an unreachable instruction after a call to @llvm.wasm.throw and + // delete all following instructions within the BB, and delete all the dead + // children of the BB as well. + for (User *U : ThrowF->users()) { + // A call to @llvm.wasm.throw() is only generated from __cxa_throw() + // builtin call within libcxxabi, and cannot be an InvokeInst. + auto *ThrowI = cast<CallInst>(U); + if (ThrowI->getFunction() != &F) + continue; + Changed = true; + auto *BB = ThrowI->getParent(); + SmallVector<BasicBlock *, 4> Succs(succ_begin(BB), succ_end(BB)); + auto &InstList = BB->getInstList(); + InstList.erase(std::next(BasicBlock::iterator(ThrowI)), InstList.end()); + IRB.SetInsertPoint(BB); + IRB.CreateUnreachable(); + eraseDeadBBsAndChildren(Succs); } return Changed; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 2ef091b7666..ae76e315bf5 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -4026,7 +4026,8 @@ void Verifier::visitInstruction(Instruction &I) { F->getIntrinsicID() == Intrinsic::coro_destroy || F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void || F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 || - F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint, + F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint || + F->getIntrinsicID() == Intrinsic::wasm_rethrow_in_catch, "Cannot invoke an intrinsic other than donothing, patchpoint, " "statepoint, coro_resume or coro_destroy", &I); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td index d44458f790a..574cb09ff33 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td @@ -144,7 +144,13 @@ 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 : NRI<(outs), (ins), [(int_wasm_rethrow)], "rethrow", 0x09>; +defm RETHROW : I<(outs), (ins EXCEPT_REF:$exn), (outs), (ins), + [], "rethrow \t$exn", "rethrow", 0x09>; +// Pseudo instruction to be the lowering target of int_wasm_rethrow_in_catch +// intrinsic. Will be converted to the real rethrow instruction later. +let isPseudo = 1 in +defm RETHROW_IN_CATCH : NRI<(outs), (ins), [(int_wasm_rethrow_in_catch)], + "rethrow_in_catch", 0>; } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 // Region within which an exception is caught: try / end_try diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp index 5b6fdb86c6d..f365aa73792 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp @@ -161,9 +161,17 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) { Changed = true; break; } - case WebAssembly::CLEANUPRET: { - // Replace a cleanupret with a rethrow - BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::RETHROW)); + case WebAssembly::CLEANUPRET: + case WebAssembly::RETHROW_IN_CATCH: { + // Replace a cleanupret/rethrow_in_catch with a rethrow + auto *EHPad = getMatchingEHPad(TI); + auto CatchPos = EHPad->begin(); + if (CatchPos->isEHLabel()) // EH pad starts with an EH label + ++CatchPos; + MachineInstr *Catch = &*CatchPos; + unsigned ExnReg = Catch->getOperand(0).getReg(); + BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::RETHROW)) + .addReg(ExnReg); TI->eraseFromParent(); Changed = true; break; @@ -191,7 +199,8 @@ bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables( SmallVector<MachineBasicBlock *, 8> Succs(MBB.succ_begin(), MBB.succ_end()); for (auto *Succ : Succs) - MBB.removeSuccessor(Succ); + if (!Succ->isEHPad()) + MBB.removeSuccessor(Succ); eraseDeadBBsAndChildren(Succs); } } @@ -337,7 +346,7 @@ bool WebAssemblyLateEHPrepare::addExceptionExtraction(MachineFunction &MF) { BuildMI(ElseMBB, DL, TII.get(WebAssembly::UNREACHABLE)); } else { - BuildMI(ElseMBB, DL, TII.get(WebAssembly::RETHROW)); + BuildMI(ElseMBB, DL, TII.get(WebAssembly::RETHROW)).addReg(ExnReg); if (EHInfo->hasEHPadUnwindDest(EHPad)) ElseMBB->addSuccessor(EHInfo->getEHPadUnwindDest(EHPad)); } |