diff options
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp | 17 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll | 62 |
2 files changed, 77 insertions, 2 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp index c906767458b..7a7587b02db 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp @@ -109,6 +109,13 @@ using namespace llvm; #define DEBUG_TYPE "wasm-lower-em-exceptions" +static cl::list<std::string> + Whitelist("emscripten-cxx-exceptions-whitelist", + cl::desc("The list of function names in which Emscripten-style " + "exception handling is enabled (see emscripten " + "EMSCRIPTEN_CATCHING_WHITELIST options)"), + cl::CommaSeparated); + namespace { class WebAssemblyLowerEmscriptenExceptions final : public ModulePass { const char *getPassName() const override { @@ -124,6 +131,7 @@ class WebAssemblyLowerEmscriptenExceptions final : public ModulePass { Function *getFindMatchingCatch(Module &M, unsigned NumClauses); Function *getInvokeWrapper(Module &M, InvokeInst *II); + bool areAllExceptionsAllowed() const { return WhitelistSet.empty(); } GlobalVariable *ThrewGV; // __THREW__ GlobalVariable *ThrewValueGV; // threwValue @@ -135,13 +143,17 @@ class WebAssemblyLowerEmscriptenExceptions final : public ModulePass { DenseMap<int, Function *> FindMatchingCatches; // Map of <function signature string, invoke_ wrappers> StringMap<Function *> InvokeWrappers; + // Set of whitelisted function names + std::set<std::string> WhitelistSet; public: static char ID; WebAssemblyLowerEmscriptenExceptions() : ModulePass(ID), ThrewGV(nullptr), ThrewValueGV(nullptr), - TempRet0GV(nullptr) {} + TempRet0GV(nullptr) { + WhitelistSet.insert(Whitelist.begin(), Whitelist.end()); + } bool runOnModule(Module &M) override; }; } // End anonymous namespace @@ -332,7 +344,8 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) { bool Changed = false; SmallVector<Instruction *, 64> ToErase; SmallPtrSet<LandingPadInst *, 32> LandingPads; - bool AllowExceptions = true; // will later change based on whitelist option + bool AllowExceptions = + areAllExceptionsAllowed() || WhitelistSet.count(F.getName()); for (BasicBlock &BB : F) { auto *II = dyn_cast<InvokeInst>(BB.getTerminator()); diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll new file mode 100644 index 00000000000..ad8cfa28e15 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll @@ -0,0 +1,62 @@ +; RUN: opt < %s -wasm-lower-em-exceptions -emscripten-cxx-exceptions-whitelist=do_catch -S | FileCheck %s + +define void @dont_catch() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; CHECK-LABEL: @dont_catch( +entry: + invoke void @foo() + to label %invoke.cont unwind label %lpad +; CHECK: entry: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label %invoke.cont + +invoke.cont: ; preds = %entry + br label %try.cont + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = extractvalue { i8*, i32 } %0, 1 + br label %catch + +catch: ; preds = %lpad + %3 = call i8* @__cxa_begin_catch(i8* %1) + call void @__cxa_end_catch() + br label %try.cont + +try.cont: ; preds = %catch, %invoke.cont + ret void +} + +define void @do_catch() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; CHECK-LABEL: @do_catch( +entry: + invoke void @foo() + to label %invoke.cont unwind label %lpad +; CHECK: entry: +; CHECK-NEXT: store i1 false, i1* +; CHECK-NEXT: call void @__invoke_void(void ()* @foo) + +invoke.cont: ; preds = %entry + br label %try.cont + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = extractvalue { i8*, i32 } %0, 1 + br label %catch + +catch: ; preds = %lpad + %3 = call i8* @__cxa_begin_catch(i8* %1) + call void @__cxa_end_catch() + br label %try.cont + +try.cont: ; preds = %catch, %invoke.cont + ret void +} + +declare void @foo() +declare i32 @__gxx_personality_v0(...) +declare i8* @__cxa_begin_catch(i8*) +declare void @__cxa_end_catch() |