summaryrefslogtreecommitdiff
path: root/lib/CodeGen/WasmEHPrepare.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
commitd8e91e46262bc44006913e6796843909f1ac7bcd (patch)
tree7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/CodeGen/WasmEHPrepare.cpp
parentb7eb8e35e481a74962664b63dfb09483b200209a (diff)
Notes
Diffstat (limited to 'lib/CodeGen/WasmEHPrepare.cpp')
-rw-r--r--lib/CodeGen/WasmEHPrepare.cpp64
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);