diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/CodeGen/WasmEHPrepare.cpp | |
parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/WasmEHPrepare.cpp')
-rw-r--r-- | lib/CodeGen/WasmEHPrepare.cpp | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/lib/CodeGen/WasmEHPrepare.cpp b/lib/CodeGen/WasmEHPrepare.cpp index 83d04da5dd0c..e5002eb95346 100644 --- a/lib/CodeGen/WasmEHPrepare.cpp +++ b/lib/CodeGen/WasmEHPrepare.cpp @@ -137,6 +137,7 @@ class WasmEHPrepare : public FunctionPass { Value *LSDAField = nullptr; // lsda field Value *SelectorField = nullptr; // selector + Function *ThrowF = nullptr; // wasm.throw() intrinsic Function *CatchF = nullptr; // wasm.catch.extract() intrinsic Function *LPadIndexF = nullptr; // wasm.landingpad.index() intrinsic Function *LSDAF = nullptr; // wasm.lsda() intrinsic @@ -145,6 +146,9 @@ class WasmEHPrepare : public FunctionPass { Function *CallPersonalityF = nullptr; // _Unwind_CallPersonality() wrapper Function *ClangCallTermF = nullptr; // __clang_call_terminate() function + bool prepareEHPads(Function &F); + bool prepareThrows(Function &F); + void prepareEHPad(BasicBlock *BB, unsigned Index); void prepareTerminateCleanupPad(BasicBlock *BB); @@ -177,7 +181,62 @@ bool WasmEHPrepare::doInitialization(Module &M) { return false; } +// Erase the specified BBs if the BB does not have any remaining predecessors, +// and also all its dead children. +template <typename Container> +static void eraseDeadBBsAndChildren(const Container &BBs) { + SmallVector<BasicBlock *, 8> WL(BBs.begin(), BBs.end()); + while (!WL.empty()) { + auto *BB = WL.pop_back_val(); + if (pred_begin(BB) != pred_end(BB)) + continue; + WL.append(succ_begin(BB), succ_end(BB)); + DeleteDeadBlock(BB); + } +} + bool WasmEHPrepare::runOnFunction(Function &F) { + bool Changed = false; + Changed |= prepareThrows(F); + Changed |= prepareEHPads(F); + return Changed; +} + +bool WasmEHPrepare::prepareThrows(Function &F) { + Module &M = *F.getParent(); + IRBuilder<> IRB(F.getContext()); + bool Changed = false; + + // wasm.throw() intinsic, which will be lowered to wasm 'throw' instruction. + ThrowF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_throw); + + // 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 + // __builtin_wasm_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; +} + +bool WasmEHPrepare::prepareEHPads(Function &F) { + Module &M = *F.getParent(); + IRBuilder<> IRB(F.getContext()); + SmallVector<BasicBlock *, 16> CatchPads; SmallVector<BasicBlock *, 16> CleanupPads; for (BasicBlock &BB : F) { @@ -194,9 +253,6 @@ bool WasmEHPrepare::runOnFunction(Function &F) { return false; assert(F.hasPersonalityFn() && "Personality function not found"); - Module &M = *F.getParent(); - IRBuilder<> IRB(F.getContext()); - // __wasm_lpad_context global variable LPadContextGV = cast<GlobalVariable>( M.getOrInsertGlobal("__wasm_lpad_context", LPadContextTy)); @@ -300,7 +356,7 @@ void WasmEHPrepare::prepareEHPad(BasicBlock *BB, unsigned Index) { // This is to create a map of <landingpad EH label, landingpad index> in // SelectionDAGISel, which is to be used in EHStreamer to emit LSDA tables. // Pseudocode: wasm.landingpad.index(Index); - IRB.CreateCall(LPadIndexF, IRB.getInt32(Index)); + IRB.CreateCall(LPadIndexF, {FPI, IRB.getInt32(Index)}); // Pseudocode: __wasm_lpad_context.lpad_index = index; IRB.CreateStore(IRB.getInt32(Index), LPadIndexField); |