summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@google.com>2016-08-18 15:27:25 +0000
committerDerek Schuff <dschuff@google.com>2016-08-18 15:27:25 +0000
commitccdceda1282fa48f304e0cd0c1b6f6861be7dcd3 (patch)
tree3fa7cd28e40ef1908073833b2025ee80cf0c33e6
parent1d0560b14dc214d108072057dfe7ab5d79bd7e67 (diff)
downloadbcm5719-llvm-ccdceda1282fa48f304e0cd0c1b6f6861be7dcd3.tar.gz
bcm5719-llvm-ccdceda1282fa48f304e0cd0c1b6f6861be7dcd3.zip
[WebAssembly] Refactor WebAssemblyLowerEmscriptenException pass for setjmp/longjmp
This patch changes the code structure of WebAssemblyLowerEmscriptenException pass to support both exception handling and setjmp/longjmp. It also changes the name of the pass and the source file. 1. Change the file/pass name to WebAssemblyLowerEmscriptenExceptions -> WebAssemblyLowerEmscriptenEHSjLj to make it clear that it supports both EH and SjLj 2. List function / global variable names at the top so they can be changed easily 3. Some cosmetic changes Patch by Heejin Ahn Differential Revision: https://reviews.llvm.org/D23588 llvm-svn: 279075
-rw-r--r--llvm/lib/Target/WebAssembly/CMakeLists.txt2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssembly.h4
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp (renamed from llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp)285
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp15
-rw-r--r--llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll2
-rw-r--r--llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll16
6 files changed, 191 insertions, 133 deletions
diff --git a/llvm/lib/Target/WebAssembly/CMakeLists.txt b/llvm/lib/Target/WebAssembly/CMakeLists.txt
index 2ce8364b844..61c1d38f882 100644
--- a/llvm/lib/Target/WebAssembly/CMakeLists.txt
+++ b/llvm/lib/Target/WebAssembly/CMakeLists.txt
@@ -20,7 +20,7 @@ add_llvm_target(WebAssemblyCodeGen
WebAssemblyISelLowering.cpp
WebAssemblyInstrInfo.cpp
WebAssemblyLowerBrUnless.cpp
- WebAssemblyLowerEmscriptenExceptions.cpp
+ WebAssemblyLowerEmscriptenEHSjLj.cpp
WebAssemblyMachineFunctionInfo.cpp
WebAssemblyMCInstLower.cpp
WebAssemblyOptimizeLiveIntervals.cpp
diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h
index e3c7b42b19d..c40e6c41e40 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.h
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -26,8 +26,8 @@ class ModulePass;
class FunctionPass;
// LLVM IR passes.
-ModulePass *createWebAssemblyLowerEmscriptenExceptions();
-void initializeWebAssemblyLowerEmscriptenExceptionsPass(PassRegistry &);
+ModulePass *createWebAssemblyLowerEmscriptenEHSjLj(bool DoEH, bool DoSjLj);
+void initializeWebAssemblyLowerEmscriptenEHSjLjPass(PassRegistry &);
FunctionPass *createWebAssemblyOptimizeReturned();
// ISel and immediate followup passes.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
index a6a8cc5fe4a..8512b20770b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenExceptions.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -1,4 +1,4 @@
-// WebAssemblyLowerEmscriptenExceptions.cpp - Lower exceptions for Emscripten //
+//=== WebAssemblyLowerEmscriptenEHSjLj.cpp - Lower exceptions for Emscripten =//
//
// The LLVM Compiler Infrastructure
//
@@ -23,9 +23,9 @@
///
/// This pass does following things:
///
-/// 1) Create three global variables: __THREW__, threwValue, and tempRet0.
+/// 1) Create three global variables: __THREW__, __threwValue, and tempRet0.
/// tempRet0 will be set within __cxa_find_matching_catch() function in
-/// JS library, and __THREW__ and threwValue will be set in invoke wrappers
+/// JS library, and __THREW__ and __threwValue will be set in invoke wrappers
/// in JS glue code. For what invoke wrappers are, refer to 3).
///
/// 2) Create setThrew and setTempRet0 functions.
@@ -38,7 +38,7 @@
/// function setThrew(threw, value) {
/// if (__THREW__ == 0) {
/// __THREW__ = threw;
-/// threwValue = value;
+/// __threwValue = value;
/// }
/// }
///
@@ -107,22 +107,49 @@
using namespace llvm;
-#define DEBUG_TYPE "wasm-lower-em-exceptions"
+#define DEBUG_TYPE "wasm-lower-em-ehsjlj"
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);
+ EHWhitelist("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 {
+class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass {
+ static const char *ThrewGVName;
+ static const char *ThrewValueGVName;
+ static const char *TempRet0GVName;
+ static const char *ResumeFName;
+ static const char *EHTypeIDFName;
+ static const char *SetThrewFName;
+ static const char *SetTempRet0FName;
+ static const char *FindMatchingCatchPrefix;
+ static const char *InvokePrefix;
+
+ bool DoEH; // Enable exception handling
+ bool DoSjLj; // Enable setjmp/longjmp handling
+
+ GlobalVariable *ThrewGV;
+ GlobalVariable *ThrewValueGV;
+ GlobalVariable *TempRet0GV;
+ Function *ResumeF;
+ Function *EHTypeIDF;
+ // __cxa_find_matching_catch_N functions.
+ // Indexed by the number of clauses in an original landingpad instruction.
+ DenseMap<int, Function *> FindMatchingCatches;
+ // Map of <function signature string, invoke_ wrappers>
+ StringMap<Function *> InvokeWrappers;
+ // Set of whitelisted function names for exception handling
+ std::set<std::string> EHWhitelistSet;
+
const char *getPassName() const override {
return "WebAssembly Lower Emscripten Exceptions";
}
- bool runOnFunction(Function &F);
+ bool runEHOnFunction(Function &F);
+ bool runSjLjOnFunction(Function &F);
// Returns __cxa_find_matching_catch_N function, where N = NumClauses + 2.
// This is because a landingpad instruction contains two more arguments,
// a personality function and a cleanup bit, and __cxa_find_matching_catch_N
@@ -131,39 +158,41 @@ 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
- GlobalVariable *TempRet0GV; // tempRet0
- Function *ResumeF; // __resumeException
- Function *EHTypeIdF; // llvm_eh_typeid_for
- // __cxa_find_matching_catch_N functions.
- // Indexed by the number of clauses in an original landingpad instruction.
- DenseMap<int, Function *> FindMatchingCatches;
- // Map of <function signature string, invoke_ wrappers>
- StringMap<Function *> InvokeWrappers;
- // Set of whitelisted function names
- std::set<std::string> WhitelistSet;
+ bool areAllExceptionsAllowed() const { return EHWhitelistSet.empty(); }
public:
static char ID;
- WebAssemblyLowerEmscriptenExceptions()
- : ModulePass(ID), ThrewGV(nullptr), ThrewValueGV(nullptr),
- TempRet0GV(nullptr) {
- WhitelistSet.insert(Whitelist.begin(), Whitelist.end());
+ WebAssemblyLowerEmscriptenEHSjLj(bool DoEH = true, bool DoSjLj = true)
+ : ModulePass(ID), DoEH(DoEH), DoSjLj(DoSjLj), ThrewGV(nullptr),
+ ThrewValueGV(nullptr), TempRet0GV(nullptr), ResumeF(nullptr),
+ EHTypeIDF(nullptr) {
+ EHWhitelistSet.insert(EHWhitelist.begin(), EHWhitelist.end());
}
bool runOnModule(Module &M) override;
};
} // End anonymous namespace
-char WebAssemblyLowerEmscriptenExceptions::ID = 0;
-INITIALIZE_PASS(WebAssemblyLowerEmscriptenExceptions, DEBUG_TYPE,
- "WebAssembly Lower Emscripten Exceptions", false, false)
-
-ModulePass *llvm::createWebAssemblyLowerEmscriptenExceptions() {
- return new WebAssemblyLowerEmscriptenExceptions();
+const char *WebAssemblyLowerEmscriptenEHSjLj::ThrewGVName = "__THREW__";
+const char *WebAssemblyLowerEmscriptenEHSjLj::ThrewValueGVName = "__threwValue";
+const char *WebAssemblyLowerEmscriptenEHSjLj::TempRet0GVName = "__tempRet0";
+const char *WebAssemblyLowerEmscriptenEHSjLj::ResumeFName = "__resumeException";
+const char *WebAssemblyLowerEmscriptenEHSjLj::EHTypeIDFName =
+ "llvm_eh_typeid_for";
+const char *WebAssemblyLowerEmscriptenEHSjLj::SetThrewFName = "setThrew";
+const char *WebAssemblyLowerEmscriptenEHSjLj::SetTempRet0FName = "setTempRet0";
+const char *WebAssemblyLowerEmscriptenEHSjLj::FindMatchingCatchPrefix =
+ "__cxa_find_matching_catch_";
+const char *WebAssemblyLowerEmscriptenEHSjLj::InvokePrefix = "__invoke_";
+
+char WebAssemblyLowerEmscriptenEHSjLj::ID = 0;
+INITIALIZE_PASS(WebAssemblyLowerEmscriptenEHSjLj, DEBUG_TYPE,
+ "WebAssembly Lower Emscripten Exceptions / Setjmp / Longjmp",
+ false, false)
+
+ModulePass *llvm::createWebAssemblyLowerEmscriptenEHSjLj(bool DoEH,
+ bool DoSjLj) {
+ return new WebAssemblyLowerEmscriptenEHSjLj(DoEH, DoSjLj);
}
static bool canThrow(const Value *V) {
@@ -212,23 +241,23 @@ static std::string getSignature(FunctionType *FTy) {
return Sig;
}
-Function *WebAssemblyLowerEmscriptenExceptions::getFindMatchingCatch(
- Module &M, unsigned NumClauses) {
+Function *
+WebAssemblyLowerEmscriptenEHSjLj::getFindMatchingCatch(Module &M,
+ unsigned NumClauses) {
if (FindMatchingCatches.count(NumClauses))
return FindMatchingCatches[NumClauses];
PointerType *Int8PtrTy = Type::getInt8PtrTy(M.getContext());
SmallVector<Type *, 16> Args(NumClauses, Int8PtrTy);
FunctionType *FTy = FunctionType::get(Int8PtrTy, Args, false);
- Function *F = Function::Create(
- FTy, GlobalValue::ExternalLinkage,
- "__cxa_find_matching_catch_" + Twine(NumClauses + 2), &M);
+ Function *F =
+ Function::Create(FTy, GlobalValue::ExternalLinkage,
+ FindMatchingCatchPrefix + Twine(NumClauses + 2), &M);
FindMatchingCatches[NumClauses] = F;
return F;
}
-Function *
-WebAssemblyLowerEmscriptenExceptions::getInvokeWrapper(Module &M,
- InvokeInst *II) {
+Function *WebAssemblyLowerEmscriptenEHSjLj::getInvokeWrapper(Module &M,
+ InvokeInst *II) {
SmallVector<Type *, 16> ArgTys;
Value *Callee = II->getCalledValue();
FunctionType *CalleeFTy;
@@ -251,58 +280,77 @@ WebAssemblyLowerEmscriptenExceptions::getInvokeWrapper(Module &M,
FunctionType *FTy = FunctionType::get(CalleeFTy->getReturnType(), ArgTys,
CalleeFTy->isVarArg());
Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage,
- "__invoke_" + Sig, &M);
+ InvokePrefix + Sig, &M);
InvokeWrappers[Sig] = F;
return F;
}
-bool WebAssemblyLowerEmscriptenExceptions::runOnModule(Module &M) {
+bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) {
LLVMContext &C = M.getContext();
- IRBuilder<> Builder(C);
- IntegerType *Int1Ty = Builder.getInt1Ty();
- PointerType *Int8PtrTy = Builder.getInt8PtrTy();
- IntegerType *Int32Ty = Builder.getInt32Ty();
- Type *VoidTy = Builder.getVoidTy();
-
- // Create global variables __THREW__, threwValue, and tempRet0
- ThrewGV = new GlobalVariable(M, Int1Ty, false, GlobalValue::ExternalLinkage,
- Builder.getFalse(),
- createGlobalValueName(M, "__THREW__"));
+ IRBuilder<> IRB(C);
+ IntegerType *Int1Ty = IRB.getInt1Ty();
+ PointerType *Int8PtrTy = IRB.getInt8PtrTy();
+ IntegerType *Int32Ty = IRB.getInt32Ty();
+ Type *VoidTy = IRB.getVoidTy();
+
+ // Create global variables __THREW__, threwValue, and tempRet0, which are
+ // used in common for both exception handling and setjmp/longjmp handling
+ ThrewGV =
+ new GlobalVariable(M, Int1Ty, false, GlobalValue::ExternalLinkage,
+ IRB.getFalse(), createGlobalValueName(M, ThrewGVName));
ThrewValueGV = new GlobalVariable(
- M, Int32Ty, false, GlobalValue::ExternalLinkage, Builder.getInt32(0),
- createGlobalValueName(M, "threwValue"));
- TempRet0GV = new GlobalVariable(
- M, Int32Ty, false, GlobalValue::ExternalLinkage, Builder.getInt32(0),
- createGlobalValueName(M, "tempRet0"));
-
- // Register __resumeException function
- FunctionType *ResumeFTy = FunctionType::get(VoidTy, Int8PtrTy, false);
- ResumeF = Function::Create(ResumeFTy, GlobalValue::ExternalLinkage,
- "__resumeException", &M);
-
- // Register llvm_eh_typeid_for function
- FunctionType *EHTypeIdTy = FunctionType::get(Int32Ty, Int8PtrTy, false);
- EHTypeIdF = Function::Create(EHTypeIdTy, GlobalValue::ExternalLinkage,
- "llvm_eh_typeid_for", &M);
+ M, Int32Ty, false, GlobalValue::ExternalLinkage, IRB.getInt32(0),
+ createGlobalValueName(M, ThrewValueGVName));
+ TempRet0GV = new GlobalVariable(M, Int32Ty, false,
+ GlobalValue::ExternalLinkage, IRB.getInt32(0),
+ createGlobalValueName(M, TempRet0GVName));
bool Changed = false;
- for (Function &F : M) {
- if (F.isDeclaration())
- continue;
- Changed |= runOnFunction(F);
+
+ // Exception handling
+ if (DoEH) {
+ // Register __resumeException function
+ FunctionType *ResumeFTy = FunctionType::get(VoidTy, Int8PtrTy, false);
+ ResumeF = Function::Create(ResumeFTy, GlobalValue::ExternalLinkage,
+ ResumeFName, &M);
+
+ // Register llvm_eh_typeid_for function
+ FunctionType *EHTypeIDTy = FunctionType::get(Int32Ty, Int8PtrTy, false);
+ EHTypeIDF = Function::Create(EHTypeIDTy, GlobalValue::ExternalLinkage,
+ EHTypeIDFName, &M);
+
+ for (Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+ Changed |= runEHOnFunction(F);
+ }
+ }
+
+ // TODO: Run CFGSimplify like the emscripten JSBackend?
+
+ // Setjmp/longjmp handling
+ if (DoSjLj) {
+ for (Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+ Changed |= runSjLjOnFunction(F);
+ }
}
if (!Changed)
return false;
- assert(!M.getNamedGlobal("setThrew") && "setThrew already exists");
- assert(!M.getNamedGlobal("setTempRet0") && "setTempRet0 already exists");
+ // If we have made any changes while doing exception handling or
+ // setjmp/longjmp handling, we have to create these functions for JavaScript
+ // to call.
+ assert(!M.getNamedGlobal(SetThrewFName) && "setThrew already exists");
+ assert(!M.getNamedGlobal(SetTempRet0FName) && "setTempRet0 already exists");
// Create setThrew function
SmallVector<Type *, 2> Params = {Int1Ty, Int32Ty};
FunctionType *FTy = FunctionType::get(VoidTy, Params, false);
Function *F =
- Function::Create(FTy, GlobalValue::ExternalLinkage, "setThrew", &M);
+ Function::Create(FTy, GlobalValue::ExternalLinkage, SetThrewFName, &M);
Argument *Arg1 = &*(F->arg_begin());
Argument *Arg2 = &*(++F->arg_begin());
Arg1->setName("threw");
@@ -311,41 +359,41 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnModule(Module &M) {
BasicBlock *ThenBB = BasicBlock::Create(C, "if.then", F);
BasicBlock *EndBB = BasicBlock::Create(C, "if.end", F);
- Builder.SetInsertPoint(EntryBB);
- Value *Threw = Builder.CreateLoad(ThrewGV, ThrewGV->getName() + ".val");
- Value *Cmp = Builder.CreateICmpEQ(Threw, Builder.getFalse(), "cmp");
- Builder.CreateCondBr(Cmp, ThenBB, EndBB);
+ IRB.SetInsertPoint(EntryBB);
+ Value *Threw = IRB.CreateLoad(ThrewGV, ThrewGV->getName() + ".val");
+ Value *Cmp = IRB.CreateICmpEQ(Threw, IRB.getFalse(), "cmp");
+ IRB.CreateCondBr(Cmp, ThenBB, EndBB);
- Builder.SetInsertPoint(ThenBB);
- Builder.CreateStore(Arg1, ThrewGV);
- Builder.CreateStore(Arg2, ThrewValueGV);
- Builder.CreateBr(EndBB);
+ IRB.SetInsertPoint(ThenBB);
+ IRB.CreateStore(Arg1, ThrewGV);
+ IRB.CreateStore(Arg2, ThrewValueGV);
+ IRB.CreateBr(EndBB);
- Builder.SetInsertPoint(EndBB);
- Builder.CreateRetVoid();
+ IRB.SetInsertPoint(EndBB);
+ IRB.CreateRetVoid();
// Create setTempRet0 function
Params = {Int32Ty};
FTy = FunctionType::get(VoidTy, Params, false);
- F = Function::Create(FTy, GlobalValue::ExternalLinkage, "setTempRet0", &M);
+ F = Function::Create(FTy, GlobalValue::ExternalLinkage, SetTempRet0FName, &M);
F->arg_begin()->setName("value");
EntryBB = BasicBlock::Create(C, "entry", F);
- Builder.SetInsertPoint(EntryBB);
- Builder.CreateStore(&*F->arg_begin(), TempRet0GV);
- Builder.CreateRetVoid();
+ IRB.SetInsertPoint(EntryBB);
+ IRB.CreateStore(&*F->arg_begin(), TempRet0GV);
+ IRB.CreateRetVoid();
return true;
}
-bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
+bool WebAssemblyLowerEmscriptenEHSjLj::runEHOnFunction(Function &F) {
Module &M = *F.getParent();
LLVMContext &C = F.getContext();
- IRBuilder<> Builder(C);
+ IRBuilder<> IRB(C);
bool Changed = false;
SmallVector<Instruction *, 64> ToErase;
SmallPtrSet<LandingPadInst *, 32> LandingPads;
bool AllowExceptions =
- areAllExceptionsAllowed() || WhitelistSet.count(F.getName());
+ areAllExceptionsAllowed() || EHWhitelistSet.count(F.getName());
for (BasicBlock &BB : F) {
auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
@@ -353,7 +401,7 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
continue;
Changed = true;
LandingPads.insert(II->getLandingPadInst());
- Builder.SetInsertPoint(II);
+ IRB.SetInsertPoint(II);
bool NeedInvoke = AllowExceptions && canThrow(II->getCalledValue());
if (NeedInvoke) {
@@ -371,7 +419,7 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
// Pre-invoke
// __THREW__ = 0;
- Builder.CreateStore(Builder.getFalse(), ThrewGV);
+ IRB.CreateStore(IRB.getFalse(), ThrewGV);
// Invoke function wrapper in JavaScript
SmallVector<Value *, 16> CallArgs;
@@ -379,7 +427,7 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
// within the invoke wrapper later
CallArgs.push_back(II->getCalledValue());
CallArgs.append(II->arg_begin(), II->arg_end());
- CallInst *NewCall = Builder.CreateCall(getInvokeWrapper(M, II), CallArgs);
+ CallInst *NewCall = IRB.CreateCall(getInvokeWrapper(M, II), CallArgs);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setDebugLoc(II->getDebugLoc());
@@ -413,17 +461,17 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
// Post-invoke
// %__THREW__.val = __THREW__; __THREW__ = 0;
- Value *Threw = Builder.CreateLoad(ThrewGV, ThrewGV->getName() + ".val");
- Builder.CreateStore(Builder.getFalse(), ThrewGV);
+ Value *Threw = IRB.CreateLoad(ThrewGV, ThrewGV->getName() + ".val");
+ IRB.CreateStore(IRB.getFalse(), ThrewGV);
// Insert a branch based on __THREW__ variable
- Builder.CreateCondBr(Threw, II->getUnwindDest(), II->getNormalDest());
+ IRB.CreateCondBr(Threw, II->getUnwindDest(), II->getNormalDest());
} else {
// This can't throw, and we don't need this invoke, just replace it with a
// call+branch
SmallVector<Value *, 16> CallArgs(II->arg_begin(), II->arg_end());
- CallInst *NewCall = Builder.CreateCall(II->getCalledValue(), CallArgs);
+ CallInst *NewCall = IRB.CreateCall(II->getCalledValue(), CallArgs);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setDebugLoc(II->getDebugLoc());
@@ -431,7 +479,7 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
II->replaceAllUsesWith(NewCall);
ToErase.push_back(II);
- Builder.CreateBr(II->getNormalDest());
+ IRB.CreateBr(II->getNormalDest());
// Remove any PHI node entries from the exception destination
II->getUnwindDest()->removePredecessor(&BB);
@@ -448,15 +496,15 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
// Split the input into legal values
Value *Input = RI->getValue();
- Builder.SetInsertPoint(RI);
- Value *Low = Builder.CreateExtractValue(Input, 0, "low");
+ IRB.SetInsertPoint(RI);
+ Value *Low = IRB.CreateExtractValue(Input, 0, "low");
// Create a call to __resumeException function
Value *Args[] = {Low};
- Builder.CreateCall(ResumeF, Args);
+ IRB.CreateCall(ResumeF, Args);
// Add a terminator to the block
- Builder.CreateUnreachable();
+ IRB.CreateUnreachable();
ToErase.push_back(RI);
}
}
@@ -473,9 +521,9 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
if (Callee->getIntrinsicID() != Intrinsic::eh_typeid_for)
continue;
- Builder.SetInsertPoint(CI);
+ IRB.SetInsertPoint(CI);
CallInst *NewCI =
- Builder.CreateCall(EHTypeIdF, CI->getArgOperand(0), "typeid");
+ IRB.CreateCall(EHTypeIDF, CI->getArgOperand(0), "typeid");
CI->replaceAllUsesWith(NewCI);
ToErase.push_back(CI);
}
@@ -491,7 +539,7 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
// Handle all the landingpad for this function together, as multiple invokes
// may share a single lp
for (LandingPadInst *LPI : LandingPads) {
- Builder.SetInsertPoint(LPI);
+ IRB.SetInsertPoint(LPI);
SmallVector<Value *, 16> FMCArgs;
for (unsigned i = 0, e = LPI->getNumClauses(); i < e; ++i) {
Constant *Clause = LPI->getClause(i);
@@ -501,8 +549,7 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
if (LPI->isFilter(i)) {
ArrayType *ATy = cast<ArrayType>(Clause->getType());
for (unsigned j = 0, e = ATy->getNumElements(); j < e; ++j) {
- Value *EV =
- Builder.CreateExtractValue(Clause, makeArrayRef(j), "filter");
+ Value *EV = IRB.CreateExtractValue(Clause, makeArrayRef(j), "filter");
FMCArgs.push_back(EV);
}
} else
@@ -511,12 +558,11 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
// Create a call to __cxa_find_matching_catch_N function
Function *FMCF = getFindMatchingCatch(M, FMCArgs.size());
- CallInst *FMCI = Builder.CreateCall(FMCF, FMCArgs, "fmc");
+ CallInst *FMCI = IRB.CreateCall(FMCF, FMCArgs, "fmc");
Value *Undef = UndefValue::get(LPI->getType());
- Value *Pair0 = Builder.CreateInsertValue(Undef, FMCI, 0, "pair0");
- Value *TempRet0 =
- Builder.CreateLoad(TempRet0GV, TempRet0GV->getName() + "val");
- Value *Pair1 = Builder.CreateInsertValue(Pair0, TempRet0, 1, "pair1");
+ Value *Pair0 = IRB.CreateInsertValue(Undef, FMCI, 0, "pair0");
+ Value *TempRet0 = IRB.CreateLoad(TempRet0GV, TempRet0GV->getName() + "val");
+ Value *Pair1 = IRB.CreateInsertValue(Pair0, TempRet0, 1, "pair1");
LPI->replaceAllUsesWith(Pair1);
ToErase.push_back(LPI);
@@ -528,3 +574,8 @@ bool WebAssemblyLowerEmscriptenExceptions::runOnFunction(Function &F) {
return Changed;
}
+
+bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
+ // TODO
+ return false;
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index e442cb1cded..1d21f2b33fd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -30,18 +30,24 @@ using namespace llvm;
#define DEBUG_TYPE "wasm"
// Emscripten's asm.js-style exception handling
-static cl::opt<bool> EnableEmExceptionHandling(
+static cl::opt<bool> EnableEmException(
"enable-emscripten-cxx-exceptions",
cl::desc("WebAssembly Emscripten-style exception handling"),
cl::init(false));
+// Emscripten's asm.js-style setjmp/longjmp handling
+static cl::opt<bool> EnableEmSjLj(
+ "enable-emscripten-sjlj",
+ cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
+ cl::init(false));
+
extern "C" void LLVMInitializeWebAssemblyTarget() {
// Register the target.
RegisterTargetMachine<WebAssemblyTargetMachine> X(TheWebAssemblyTarget32);
RegisterTargetMachine<WebAssemblyTargetMachine> Y(TheWebAssemblyTarget64);
// Register exception handling pass to opt
- initializeWebAssemblyLowerEmscriptenExceptionsPass(
+ initializeWebAssemblyLowerEmscriptenEHSjLjPass(
*PassRegistry::getPassRegistry());
}
@@ -160,8 +166,9 @@ void WebAssemblyPassConfig::addIRPasses() {
addPass(createWebAssemblyOptimizeReturned());
// Handle exceptions.
- if (EnableEmExceptionHandling)
- addPass(createWebAssemblyLowerEmscriptenExceptions());
+ if (EnableEmException || EnableEmSjLj)
+ addPass(createWebAssemblyLowerEmscriptenEHSjLj(EnableEmException,
+ EnableEmSjLj));
TargetPassConfig::addIRPasses();
}
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll
index ad8cfa28e15..e510bc9fca7 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions-whitelist.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -wasm-lower-em-exceptions -emscripten-cxx-exceptions-whitelist=do_catch -S | FileCheck %s
+; RUN: opt < %s -wasm-lower-em-ehsjlj -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(
diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll
index 5e9431d3cca..e9eb2540ccc 100644
--- a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll
+++ b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll
@@ -1,10 +1,10 @@
-; RUN: opt < %s -wasm-lower-em-exceptions -S | FileCheck %s
+; RUN: opt < %s -wasm-lower-em-ehsjlj -S | FileCheck %s
@_ZTIi = external constant i8*
@_ZTIc = external constant i8*
; CHECK: @[[__THREW__:__THREW__.*]] = global i1 false
-; CHECK: @[[THREWVALUE:threwValue.*]] = global i32 0
-; CHECK: @[[TEMPRET0:tempRet0.*]] = global i32 0
+; CHECK: @[[THREWVALUE:__threwValue.*]] = global i32 0
+; CHECK: @[[TEMPRET0:__tempRet0.*]] = global i32 0
; Test invoke instruction with clauses (try-catch block)
define void @clause() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
@@ -170,12 +170,12 @@ declare void @__cxa_call_unexpected(i8*)
; setThrew function creation
; CHECK-LABEL: define void @setThrew(i1 %threw, i32 %value) {
; CHECK: entry:
-; CHECK-NEXT: %__THREW__.val = load i1, i1* @__THREW__
-; CHECK-NEXT: %cmp = icmp eq i1 %__THREW__.val, false
+; CHECK-NEXT: %[[__THREW__]].val = load i1, i1* @[[__THREW__]]
+; CHECK-NEXT: %cmp = icmp eq i1 %[[__THREW__]].val, false
; CHECK-NEXT: br i1 %cmp, label %if.then, label %if.end
; CHECK: if.then:
-; CHECK-NEXT: store i1 %threw, i1* @__THREW__
-; CHECK-NEXT: store i32 %value, i32* @threwValue
+; CHECK-NEXT: store i1 %threw, i1* @[[__THREW__]]
+; CHECK-NEXT: store i32 %value, i32* @[[THREWVALUE]]
; CHECK-NEXT: br label %if.end
; CHECK: if.end:
; CHECK-NEXT: ret void
@@ -184,6 +184,6 @@ declare void @__cxa_call_unexpected(i8*)
; setTempRet0 function creation
; CHECK-LABEL: define void @setTempRet0(i32 %value) {
; CHECK: entry:
-; CHECK-NEXT: store i32 %value, i32* @tempRet0
+; CHECK-NEXT: store i32 %value, i32* @[[TEMPRET0]]
; CHECK-NEXT: ret void
; CHECK: }
OpenPOWER on IntegriCloud