diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-01-10 16:32:25 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-01-10 16:32:25 -0800 |
commit | 59962e958c83ac9427723a365751405212b3ffb3 (patch) | |
tree | 87a20737c6dd841f124c271dfab0eb988af21da5 | |
parent | edd6359a2814bef32cf76796bea9b1d7b5a00160 (diff) |
lower resume
-rw-r--r-- | lib/Target/JSBackend/JSBackend.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/NaCl/ExpandVarArgs.cpp | 3 | ||||
-rw-r--r-- | lib/Transforms/NaCl/LowerEmExceptionsPass.cpp | 34 |
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 |