[llvm] f2a43f0 - [WebAssembly] Use llvm utility functions in EH/SjLj
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 4 17:48:33 PST 2022
Author: Heejin Ahn
Date: 2022-01-04T17:47:20-08:00
New Revision: f2a43f06dd0cedc256be23b9b2b38108f7bcfc74
URL: https://github.com/llvm/llvm-project/commit/f2a43f06dd0cedc256be23b9b2b38108f7bcfc74
DIFF: https://github.com/llvm/llvm-project/commit/f2a43f06dd0cedc256be23b9b2b38108f7bcfc74.diff
LOG: [WebAssembly] Use llvm utility functions in EH/SjLj
This uses `changeToCall` and `changeToInvokeAndSplitBasicBlock` from
`lib/Transforms/Utils`, replacing the custom logic. One difference of
those functions from our previous logic is they delete the original
`CallInst`/`InvokeInst`, which makes them tricky to use while iterating
through instructions/BBs. So this CL gathers the candidate calls first
and run them through `changeToInvokeAndSplitBasicBlock` later.
Also this renames some variables.
Reviewed By: dschuff
Differential Revision: https://reviews.llvm.org/D116620
Added:
Modified:
llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index df96c6f437c2e..c95ea54c14fe3 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -279,6 +279,7 @@
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Transforms/Utils/SSAUpdaterBulk.h"
@@ -1118,20 +1119,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runEHOnFunction(Function &F) {
} else {
// This can't throw, and we don't need this invoke, just replace it with a
// call+branch
- SmallVector<Value *, 16> Args(II->args());
- CallInst *NewCall =
- IRB.CreateCall(II->getFunctionType(), II->getCalledOperand(), Args);
- NewCall->takeName(II);
- NewCall->setCallingConv(II->getCallingConv());
- NewCall->setDebugLoc(II->getDebugLoc());
- NewCall->setAttributes(II->getAttributes());
- II->replaceAllUsesWith(NewCall);
- ToErase.push_back(II);
-
- IRB.CreateBr(II->getNormalDest());
-
- // Remove any PHI node entries from the exception destination
- II->getUnwindDest()->removePredecessor(&BB);
+ changeToCall(II);
}
}
@@ -1659,18 +1647,18 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
BasicBlock::Create(C, "setjmp.dispatch", &F, OrigEntry);
cast<BranchInst>(Entry->getTerminator())->setSuccessor(0, SetjmpDispatchBB);
- // Create catch.dispatch.longjmp BB a catchswitch instruction
- BasicBlock *CatchSwitchBB =
+ // Create catch.dispatch.longjmp BB and a catchswitch instruction
+ BasicBlock *CatchDispatchLongjmpBB =
BasicBlock::Create(C, "catch.dispatch.longjmp", &F);
- IRB.SetInsertPoint(CatchSwitchBB);
- CatchSwitchInst *CatchSwitch =
+ IRB.SetInsertPoint(CatchDispatchLongjmpBB);
+ CatchSwitchInst *CatchSwitchLongjmp =
IRB.CreateCatchSwitch(ConstantTokenNone::get(C), nullptr, 1);
// Create catch.longjmp BB and a catchpad instruction
BasicBlock *CatchLongjmpBB = BasicBlock::Create(C, "catch.longjmp", &F);
- CatchSwitch->addHandler(CatchLongjmpBB);
+ CatchSwitchLongjmp->addHandler(CatchLongjmpBB);
IRB.SetInsertPoint(CatchLongjmpBB);
- CatchPadInst *CatchPad = IRB.CreateCatchPad(CatchSwitch, {});
+ CatchPadInst *CatchPad = IRB.CreateCatchPad(CatchSwitchLongjmp, {});
// Wasm throw and catch instructions can throw and catch multiple values, but
// that requires multivalue support in the toolchain, which is currently not
@@ -1736,9 +1724,9 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
// Convert all longjmpable call instructions to invokes that unwind to the
// newly created catch.dispatch.longjmp BB.
- SmallVector<Instruction *, 64> ToErase;
+ SmallVector<CallInst *, 64> LongjmpableCalls;
for (auto *BB = &*F.begin(); BB; BB = BB->getNextNode()) {
- for (Instruction &I : *BB) {
+ for (auto &I : *BB) {
auto *CI = dyn_cast<CallInst>(&I);
if (!CI)
continue;
@@ -1756,32 +1744,18 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForWasmSjLj(
// setjmps in this function. We should not convert this call to an invoke.
if (CI == WasmLongjmpCI)
continue;
- ToErase.push_back(CI);
-
- // Even if the callee function has attribute 'nounwind', which is true for
- // all C functions, it can longjmp, which means it can throw a Wasm
- // exception now.
- CI->removeFnAttr(Attribute::NoUnwind);
- if (Function *CalleeF = CI->getCalledFunction()) {
- CalleeF->removeFnAttr(Attribute::NoUnwind);
- }
-
- IRB.SetInsertPoint(CI);
- BasicBlock *Tail = SplitBlock(BB, CI->getNextNode());
- // We will add a new invoke. So remove the branch created when we split
- // the BB
- ToErase.push_back(BB->getTerminator());
- SmallVector<Value *, 8> Args(CI->args());
- InvokeInst *II =
- IRB.CreateInvoke(CI->getFunctionType(), CI->getCalledOperand(), Tail,
- CatchSwitchBB, Args);
- II->takeName(CI);
- II->setDebugLoc(CI->getDebugLoc());
- II->setAttributes(CI->getAttributes());
- CI->replaceAllUsesWith(II);
+ LongjmpableCalls.push_back(CI);
}
}
-
- for (Instruction *I : ToErase)
- I->eraseFromParent();
+ for (auto *CI : LongjmpableCalls) {
+ // Even if the callee function has attribute 'nounwind', which is true for
+ // all C functions, it can longjmp, which means it can throw a Wasm
+ // exception now.
+ CI->removeFnAttr(Attribute::NoUnwind);
+ if (Function *CalleeF = CI->getCalledFunction())
+ CalleeF->removeFnAttr(Attribute::NoUnwind);
+ // Change it to an invoke and make it unwind to the catch.dispatch.longjmp
+ // BB.
+ changeToInvokeAndSplitBasicBlock(CI, CatchDispatchLongjmpBB);
+ }
}
diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll
index cf66d7d7b4811..1f8ca482c8afb 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll
@@ -52,9 +52,9 @@ entry:
; CHECK-NEXT: %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf8, i32 0, i32 0
; CHECK-NEXT: %env = bitcast %struct.__jmp_buf_tag* %arraydecay1 to i8*
; CHECK-NEXT: invoke void @__wasm_longjmp(i8* %env, i32 1)
-; CHECK-NEXT: to label %entry.split.split.split unwind label %catch.dispatch.longjmp
+; CHECK-NEXT: to label %.noexc unwind label %catch.dispatch.longjmp
-; CHECK: entry.split.split.split:
+; CHECK: .noexc:
; CHECK-NEXT: unreachable
; CHECK: catch.dispatch.longjmp:
@@ -101,7 +101,7 @@ entry:
; CHECK: invoke void @foo()
; CHECK: to label %{{.*}} unwind label %catch.dispatch.longjmp
-; CHECK: entry.split.split.split:
+; CHECK: .noexc:
; CHECK: invoke void @foo()
; CHECK: to label %{{.*}} unwind label %catch.dispatch.longjmp
}
More information about the llvm-commits
mailing list