Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: lib/Transforms/NaCl/LowerEmSetjmp.cpp

Issue 1151093004: Changes from 3.7 merge to files not in upstream (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- LowerEmSetjmp - Lower setjmp/longjmp for Emscripten/JS -----------===// 1 //===- LowerEmSetjmp - Lower setjmp/longjmp for Emscripten/JS -----------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // Lowers setjmp to a reasonably-performant approach for emscripten. The idea 10 // Lowers setjmp to a reasonably-performant approach for emscripten. The idea
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 FunctionPhisMap SetjmpOutputPhis; 206 FunctionPhisMap SetjmpOutputPhis;
207 std::vector<Instruction*> ToErase; 207 std::vector<Instruction*> ToErase;
208 208
209 if (Setjmp) { 209 if (Setjmp) {
210 for (Instruction::user_iterator UI = Setjmp->user_begin(), UE = Setjmp->user _end(); UI != UE; ++UI) { 210 for (Instruction::user_iterator UI = Setjmp->user_begin(), UE = Setjmp->user _end(); UI != UE; ++UI) {
211 User *U = *UI; 211 User *U = *UI;
212 if (CallInst *CI = dyn_cast<CallInst>(U)) { 212 if (CallInst *CI = dyn_cast<CallInst>(U)) {
213 BasicBlock *SJBB = CI->getParent(); 213 BasicBlock *SJBB = CI->getParent();
214 // The tail is everything right after the call, and will be reached once when setjmp is 214 // The tail is everything right after the call, and will be reached once when setjmp is
215 // called, and later when longjmp returns to the setjmp 215 // called, and later when longjmp returns to the setjmp
216 BasicBlock *Tail = SplitBlock(SJBB, CI->getNextNode(), this); 216 BasicBlock *Tail = SplitBlock(SJBB, CI->getNextNode());
217 // Add a phi to the tail, which will be the output of setjmp, which indi cates if this is the 217 // Add a phi to the tail, which will be the output of setjmp, which indi cates if this is the
218 // first call or a longjmp back. The phi directly uses the right value b ased on where we 218 // first call or a longjmp back. The phi directly uses the right value b ased on where we
219 // arrive from 219 // arrive from
220 PHINode *SetjmpOutput = PHINode::Create(i32, 2, "", Tail->getFirstNonPHI ()); 220 PHINode *SetjmpOutput = PHINode::Create(i32, 2, "", Tail->getFirstNonPHI ());
221 SetjmpOutput->addIncoming(ConstantInt::get(i32, 0), SJBB); // setjmp ini tial call returns 0 221 SetjmpOutput->addIncoming(ConstantInt::get(i32, 0), SJBB); // setjmp ini tial call returns 0
222 CI->replaceAllUsesWith(SetjmpOutput); // The proper output is now this, not the setjmp call itself 222 CI->replaceAllUsesWith(SetjmpOutput); // The proper output is now this, not the setjmp call itself
223 // longjmp returns to the setjmp will add themselves to this phi 223 // longjmp returns to the setjmp will add themselves to this phi
224 Phis& P = SetjmpOutputPhis[SJBB->getParent()]; 224 Phis& P = SetjmpOutputPhis[SJBB->getParent()];
225 P.push_back(SetjmpOutput); 225 P.push_back(SetjmpOutput);
226 // fix call target 226 // fix call target
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 if (Function *CF = dyn_cast<Function>(V)) if (CF->isIntrinsic()) conti nue; 261 if (Function *CF = dyn_cast<Function>(V)) if (CF->isIntrinsic()) conti nue;
262 // TODO: proper analysis of what can actually longjmp. Currently we as sume anything but setjmp can. 262 // TODO: proper analysis of what can actually longjmp. Currently we as sume anything but setjmp can.
263 // This may longjmp, so we need to check if it did. Split at that poin t, and 263 // This may longjmp, so we need to check if it did. Split at that poin t, and
264 // envelop the call in pre/post invoke, if we need to 264 // envelop the call in pre/post invoke, if we need to
265 CallInst *After; 265 CallInst *After;
266 Instruction *Check = NULL; 266 Instruction *Check = NULL;
267 if (Iter != E && (After = dyn_cast<CallInst>(Iter)) && After->getCalle dValue() == PostInvoke) { 267 if (Iter != E && (After = dyn_cast<CallInst>(Iter)) && After->getCalle dValue() == PostInvoke) {
268 // use the pre|postinvoke that exceptions lowering already made 268 // use the pre|postinvoke that exceptions lowering already made
269 Check = Iter++; 269 Check = Iter++;
270 } 270 }
271 BasicBlock *Tail = SplitBlock(BB, Iter, this); // Iter already points to the next instruction, as we need 271 BasicBlock *Tail = SplitBlock(BB, Iter); // Iter already points to the next instruction, as we need
272 TerminatorInst *TI = BB->getTerminator(); 272 TerminatorInst *TI = BB->getTerminator();
273 if (!Check) { 273 if (!Check) {
274 // no existing pre|postinvoke, create our own 274 // no existing pre|postinvoke, create our own
275 CallInst::Create(PreInvoke, "", CI); 275 CallInst::Create(PreInvoke, "", CI);
276 Check = CallInst::Create(PostInvoke, "", TI); // CI is at the end of the block 276 Check = CallInst::Create(PostInvoke, "", TI); // CI is at the end of the block
277 277
278 // If we are calling a function that is noreturn, we must remove tha t attribute. The code we 278 // If we are calling a function that is noreturn, we must remove tha t attribute. The code we
279 // insert here does expect it to return, after we catch the exceptio n. 279 // insert here does expect it to return, after we catch the exceptio n.
280 if (CI->doesNotReturn()) { 280 if (CI->doesNotReturn()) {
281 if (Function *F = dyn_cast<Function>(CI->getCalledValue())) { 281 if (Function *F = dyn_cast<Function>(CI->getCalledValue())) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 doRegToMem(*F); 340 doRegToMem(*F);
341 doMemToReg(*F); 341 doMemToReg(*F);
342 } 342 }
343 343
344 return true; 344 return true;
345 } 345 }
346 346
347 ModulePass *llvm::createLowerEmSetjmpPass() { 347 ModulePass *llvm::createLowerEmSetjmpPass() {
348 return new LowerEmSetjmp(); 348 return new LowerEmSetjmp();
349 } 349 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698