Skip to content

Commit 99d60e0

Browse files
committed
[WebAssembly] Add Wasm exception handling prepare pass
Summary: This adds a pass that transforms a program to be prepared for Wasm exception handling. This is using Windows EH instructions and based on the previous Wasm EH proposal. (https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md) Reviewers: dschuff, majnemer Subscribers: jfb, mgorny, sbc100, jgravelle-google, JDevlieghere, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D43746 llvm-svn: 333696
1 parent 2ae1ab3 commit 99d60e0

File tree

10 files changed

+698
-9
lines changed

10 files changed

+698
-9
lines changed

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,17 @@ namespace llvm {
329329

330330
/// createWinEHPass - Prepares personality functions used by MSVC on Windows,
331331
/// in addition to the Itanium LSDA based personalities.
332-
FunctionPass *createWinEHPass();
332+
FunctionPass *createWinEHPass(bool DemoteCatchSwitchPHIOnly = false);
333333

334334
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
335335
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
336336
///
337337
FunctionPass *createSjLjEHPreparePass();
338338

339+
/// createWasmEHPass - This pass adapts exception handling code to use
340+
/// WebAssembly's exception handling scheme.
341+
FunctionPass *createWasmEHPass();
342+
339343
/// LocalStackSlotAllocation - This pass assigns local frame indices to stack
340344
/// slots relative to one another and allocates base registers to access them
341345
/// when it is estimated by the target to be out of range of normal frame

llvm/include/llvm/IR/IntrinsicsWebAssembly.td

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,21 @@ def int_wasm_rethrow : Intrinsic<[], [], [Throws, IntrNoReturn]>;
4242

4343
// Since wasm does not use landingpad instructions, these instructions return
4444
// exception pointer and selector values until we lower them in WasmEHPrepare.
45-
def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [], [IntrHasSideEffects]>;
46-
def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [],
45+
def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [llvm_token_ty],
46+
[IntrHasSideEffects]>;
47+
def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [llvm_token_ty],
4748
[IntrHasSideEffects]>;
49+
50+
// wasm.catch returns the pointer to the exception object caught by wasm 'catch'
51+
// instruction.
52+
def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty],
53+
[IntrHasSideEffects]>;
54+
55+
// WebAssembly EH must maintain the landingpads in the order assigned to them
56+
// by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is
57+
// used in order to give them the indices in WasmEHPrepare.
58+
def int_wasm_landingpad_index: Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>;
59+
60+
// Returns LSDA address of the current function.
61+
def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
4862
}

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ void initializeUnreachableMachineBlockElimPass(PassRegistry&);
389389
void initializeVerifierLegacyPassPass(PassRegistry&);
390390
void initializeVirtRegMapPass(PassRegistry&);
391391
void initializeVirtRegRewriterPass(PassRegistry&);
392+
void initializeWasmEHPreparePass(PassRegistry&);
392393
void initializeWholeProgramDevirtPass(PassRegistry&);
393394
void initializeWinEHPreparePass(PassRegistry&);
394395
void initializeWriteBitcodePassPass(PassRegistry&);

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ add_llvm_library(LLVMCodeGen
158158
UnreachableBlockElim.cpp
159159
ValueTypes.cpp
160160
VirtRegMap.cpp
161+
WasmEHPrepare.cpp
161162
WinEHPrepare.cpp
162163
XRayInstrumentation.cpp
163164

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
102102
initializeUnreachableMachineBlockElimPass(Registry);
103103
initializeVirtRegMapPass(Registry);
104104
initializeVirtRegRewriterPass(Registry);
105+
initializeWasmEHPreparePass(Registry);
105106
initializeWinEHPreparePass(Registry);
106107
initializeXRayInstrumentationPass(Registry);
107108
initializeMIRCanonicalizerPass(Registry);

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,12 @@ void TargetPassConfig::addPassesToHandleExceptions() {
656656
addPass(createDwarfEHPass());
657657
break;
658658
case ExceptionHandling::Wasm:
659-
// TODO to prevent warning
659+
// Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
660+
// on catchpads and cleanuppads because it does not outline them into
661+
// funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
662+
// should remove PHIs there.
663+
addPass(createWinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
664+
addPass(createWasmEHPass());
660665
break;
661666
case ExceptionHandling::None:
662667
addPass(createLowerInvokePass());

0 commit comments

Comments
 (0)