forked from OSchip/llvm-project
[WebAssembly] Add -emscripten-cxx-exceptions-whitelist option
This patch adds -emscripten-cxx-exceptions-whitelist option to WebAssemblyLowerEmscriptenExceptions pass. This options is the list of function names in which Emscripten-style exception handling is enabled. This is to support emscripten's EXCEPTION_CATCHING_WHITELIST which exists because of the performance impact of emscripten's non-zero-cost EH method. Patch by Heejin Ahn Differential Revision: https://reviews.llvm.org/D23292 llvm-svn: 278171
This commit is contained in:
parent
e7c2875dc3
commit
66641322ce
|
@ -109,6 +109,13 @@ using namespace llvm;
|
||||||
|
|
||||||
#define DEBUG_TYPE "wasm-lower-em-exceptions"
|
#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 {
|
namespace {
|
||||||
class WebAssemblyLowerEmscriptenExceptions final : public ModulePass {
|
class WebAssemblyLowerEmscriptenExceptions final : public ModulePass {
|
||||||
const char *getPassName() const override {
|
const char *getPassName() const override {
|
||||||
|
@ -124,6 +131,7 @@ class WebAssemblyLowerEmscriptenExceptions final : public ModulePass {
|
||||||
Function *getFindMatchingCatch(Module &M, unsigned NumClauses);
|
Function *getFindMatchingCatch(Module &M, unsigned NumClauses);
|
||||||
|
|
||||||
Function *getInvokeWrapper(Module &M, InvokeInst *II);
|
Function *getInvokeWrapper(Module &M, InvokeInst *II);
|
||||||
|
bool areAllExceptionsAllowed() const { return WhitelistSet.empty(); }
|
||||||
|
|
||||||
GlobalVariable *ThrewGV; // __THREW__
|
GlobalVariable *ThrewGV; // __THREW__
|
||||||
GlobalVariable *ThrewValueGV; // threwValue
|
GlobalVariable *ThrewValueGV; // threwValue
|
||||||
|
@ -135,13 +143,17 @@ class WebAssemblyLowerEmscriptenExceptions final : public ModulePass {
|
||||||
DenseMap<int, Function *> FindMatchingCatches;
|
DenseMap<int, Function *> FindMatchingCatches;
|
||||||
// Map of <function signature string, invoke_ wrappers>
|
// Map of <function signature string, invoke_ wrappers>
|
||||||
StringMap<Function *> InvokeWrappers;
|
StringMap<Function *> InvokeWrappers;
|
||||||
|
// Set of whitelisted function names
|
||||||
|
std::set<std::string> WhitelistSet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
|
|
||||||
WebAssemblyLowerEmscriptenExceptions()
|
WebAssemblyLowerEmscriptenExceptions()
|
||||||
: ModulePass(ID), ThrewGV(nullptr), ThrewValueGV(nullptr),
|
: ModulePass(ID), ThrewGV(nullptr), ThrewValueGV(nullptr),
|
||||||
TempRet0GV(nullptr) {}
|
TempRet0GV(nullptr) {
|
||||||
|
WhitelistSet.insert(Whitelist.begin(), Whitelist.end());
|
||||||
|
}
|
||||||
bool runOnModule(Module &M) override;
|
bool runOnModule(Module &M) override;
|
||||||
};
|
};
|
||||||
} // End anonymous namespace
|
} // End anonymous namespace
|
||||||
|
@ -332,7 +344,8 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
SmallVector<Instruction *, 64> ToErase;
|
SmallVector<Instruction *, 64> ToErase;
|
||||||
SmallPtrSet<LandingPadInst *, 32> LandingPads;
|
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) {
|
for (BasicBlock &BB : F) {
|
||||||
auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
|
auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
|
||||||
|
|
|
@ -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()
|
Loading…
Reference in New Issue