aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-01-10 16:32:25 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-01-10 16:32:25 -0800
commit59962e958c83ac9427723a365751405212b3ffb3 (patch)
tree87a20737c6dd841f124c271dfab0eb988af21da5
parentedd6359a2814bef32cf76796bea9b1d7b5a00160 (diff)
lower resume
-rw-r--r--lib/Target/JSBackend/JSBackend.cpp4
-rw-r--r--lib/Transforms/NaCl/ExpandVarArgs.cpp3
-rw-r--r--lib/Transforms/NaCl/LowerEmExceptionsPass.cpp34
3 files changed, 32 insertions, 9 deletions
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp
index 617f33b011..ca1d132351 100644
--- a/lib/Target/JSBackend/JSBackend.cpp
+++ b/lib/Target/JSBackend/JSBackend.cpp
@@ -1239,10 +1239,6 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod
Code << ";";
break;
}
- case Instruction::Resume: {
- Code << "___resumeException(" + getValueAsStr(I->getOperand(0)) + "|0);";
- break;
- }
}
// append debug info
if (MDNode *N = I->getMetadata("dbg")) {
diff --git a/lib/Transforms/NaCl/ExpandVarArgs.cpp b/lib/Transforms/NaCl/ExpandVarArgs.cpp
index a24f0d111d..99c200c9f0 100644
--- a/lib/Transforms/NaCl/ExpandVarArgs.cpp
+++ b/lib/Transforms/NaCl/ExpandVarArgs.cpp
@@ -69,7 +69,8 @@ INITIALIZE_PASS(ExpandVarArgs, "expand-varargs",
static bool isEmscriptenJSArgsFunc(StringRef Name) {
return Name.equals("emscripten_asm_const_int") ||
Name.equals("emscripten_asm_const_double") ||
- Name.equals("emscripten_landingpad");
+ Name.equals("emscripten_landingpad") ||
+ Name.equals("emscripten_resume");
}
static void ExpandVarArgFunc(Function *Func) {
diff --git a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp b/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
index ea5bb7b2cd..480506dcf0 100644
--- a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
+++ b/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
@@ -21,8 +21,9 @@
// invoke-landingpad for our special purposes (as they are checked very
// carefully by llvm)
//
-// 2) Lower landingpads to return a single i8*, avoid the structural type
-// which is unneeded anyhow.
+// 2) Lower landingpads to a call to emscripten_landingpad
+//
+// 3) Lower resume to emscripten_resume which receives non-aggregate inputs
//
//===----------------------------------------------------------------------===//
@@ -63,12 +64,12 @@ using namespace llvm;
namespace {
class LowerEmExceptions : public ModulePass {
- Function *GetHigh, *PreInvoke, *PostInvoke, *LandingPad;
+ Function *GetHigh, *PreInvoke, *PostInvoke, *LandingPad, *Resume;
Module *TheModule;
public:
static char ID; // Pass identification, replacement for typeid
- explicit LowerEmExceptions() : ModulePass(ID), GetHigh(NULL), PreInvoke(NULL), PostInvoke(NULL), LandingPad(NULL), TheModule(NULL) {
+ explicit LowerEmExceptions() : ModulePass(ID), GetHigh(NULL), PreInvoke(NULL), PostInvoke(NULL), LandingPad(NULL), Resume(NULL), TheModule(NULL) {
initializeLowerEmExceptionsPass(*PassRegistry::getPassRegistry());
}
bool runOnModule(Module &M);
@@ -106,6 +107,9 @@ bool LowerEmExceptions::runOnModule(Module &M) {
FunctionType *LandingPadFunc = FunctionType::get(i8P, true);
LandingPad = Function::Create(LandingPadFunc, GlobalValue::ExternalLinkage, "emscripten_landingpad", TheModule);
+ FunctionType *ResumeFunc = FunctionType::get(Void, true);
+ Resume = Function::Create(ResumeFunc, GlobalValue::ExternalLinkage, "emscripten_resume", TheModule);
+
// Process
bool Changed = false;
@@ -117,6 +121,7 @@ bool LowerEmExceptions::runOnModule(Module &M) {
std::set<LandingPadInst*> LandingPads;
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
+ // check terminator for invokes
if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
// Insert a normal call instruction folded in between pre- and post-invoke
CallInst *Pre = CallInst::Create(PreInvoke, "", II);
@@ -140,6 +145,27 @@ bool LowerEmExceptions::runOnModule(Module &M) {
Changed = true;
}
+ // scan the body of the basic block for resumes
+ for (BasicBlock::iterator Iter = BB->begin(), E = BB->end();
+ Iter != E; ) {
+ Instruction *I = Iter++;
+ if (ResumeInst *R = dyn_cast<ResumeInst>(I)) {
+ // split the input into legal values
+ Value *Input = R->getValue();
+ ExtractValueInst *Low = ExtractValueInst::Create(Input, 0, "", R);
+ ExtractValueInst *High = ExtractValueInst::Create(Input, 1, "", R);
+
+ // create a resume call
+ SmallVector<Value*,2> CallArgs;
+ CallArgs.push_back(Low);
+ CallArgs.push_back(High);
+ CallInst *NewR = CallInst::Create(Resume, CallArgs, "", R);
+
+ UnreachableInst *U = new UnreachableInst(TheModule->getContext(), R); // add a terminator to the block
+
+ ToErase.push_back(R);
+ }
+ }
}
// Handle all the landingpad for this function together, as multiple invokes may share a single lp