Deleted Added
full compact
48a49,50
> Constant *StackAddrFn;
> Constant *StackRestoreFn;
72c74
< void splitLiveRangesLiveAcrossInvokes(SmallVector<InvokeInst*,16> &Invokes);
---
> void splitLiveRangesAcrossInvokes(SmallVector<InvokeInst*,16> &Invokes);
109a112,113
> StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave);
> StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore);
177a182,183
> /// FIXME: Move this function to a common utility file (Local.cpp?) so
> /// both SjLj and LowerInvoke can use it.
179c185
< splitLiveRangesLiveAcrossInvokes(SmallVector<InvokeInst*,16> &Invokes) {
---
> splitLiveRangesAcrossInvokes(SmallVector<InvokeInst*,16> &Invokes) {
201,210c207,233
< // This is always a no-op cast because we're casting AI to AI->getType() so
< // src and destination types are identical. BitCast is the only possibility.
< CastInst *NC = new BitCastInst(
< AI, AI->getType(), AI->getName()+".tmp", AfterAllocaInsertPt);
< AI->replaceAllUsesWith(NC);
< // Normally its is forbidden to replace a CastInst's operand because it
< // could cause the opcode to reflect an illegal conversion. However, we're
< // replacing it here with the same value it was constructed with to simply
< // make NC its user.
< NC->setOperand(0, AI);
---
> const Type *Ty = AI->getType();
> // Aggregate types can't be cast, but are legal argument types, so we have
> // to handle them differently. We use an extract/insert pair as a
> // lightweight method to achieve the same goal.
> if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) {
> Instruction *EI = ExtractValueInst::Create(AI, 0, "",AfterAllocaInsertPt);
> Instruction *NI = InsertValueInst::Create(AI, EI, 0);
> NI->insertAfter(EI);
> AI->replaceAllUsesWith(NI);
> // Set the operand of the instructions back to the AllocaInst.
> EI->setOperand(0, AI);
> NI->setOperand(0, AI);
> } else {
> // This is always a no-op cast because we're casting AI to AI->getType()
> // so src and destination types are identical. BitCast is the only
> // possibility.
> CastInst *NC = new BitCastInst(
> AI, AI->getType(), AI->getName()+".tmp", AfterAllocaInsertPt);
> AI->replaceAllUsesWith(NC);
> // Set the operand of the cast instruction back to the AllocaInst.
> // Normally it's forbidden to replace a CastInst's operand because it
> // could cause the opcode to reflect an illegal conversion. However,
> // we're replacing it here with the same value it was constructed with.
> // We do this because the above replaceAllUsesWith() clobbered the
> // operand, but we want this one to remain.
> NC->setOperand(0, AI);
> }
268a292,294
> // FIXME: Spilling this way is overkill, as it forces all uses of
> // the value to be reloaded from the stack slot, even those that aren't
> // in the unwind blocks. We should be more selective.
297,300c323,330
< // Find the eh.selector.* and eh.exception calls. We'll use the first
< // eh.selector to determine the right personality function to use. For
< // SJLJ, we always use the same personality for the whole function,
< // not on a per-selector basis.
---
> // Find the eh.selector.*, eh.exception and alloca calls.
> //
> // Remember any allocas() that aren't in the entry block, as the
> // jmpbuf saved SP will need to be updated for them.
> //
> // We'll use the first eh.selector to determine the right personality
> // function to use. For SJLJ, we always use the same personality for the
> // whole function, not on a per-selector basis.
304c334,338
< for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
---
> SmallVector<Instruction*,16> JmpbufUpdatePoints;
> // Note: Skip the entry block since there's nothing there that interests
> // us. eh.selector and eh.exception shouldn't ever be there, and we
> // want to disregard any allocas that are there.
> for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) {
308c342
< if (!PersonalityFn) PersonalityFn = CI->getOperand(2);
---
> if (!PersonalityFn) PersonalityFn = CI->getArgOperand(1);
311a346,347
> } else if (CI->getCalledFunction() == StackRestoreFn) {
> JmpbufUpdatePoints.push_back(CI);
312a349,350
> } else if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
> JmpbufUpdatePoints.push_back(AI);
332c370
< splitLiveRangesLiveAcrossInvokes(Invokes);
---
> splitLiveRangesAcrossInvokes(Invokes);
422c460
< // 3. jmpbuf (save FP and call eh.sjlj.setjmp)
---
> // 3. jmpbuf (save SP, FP and call eh.sjlj.setjmp)
443c481
< // Save the frame pointer.
---
> // Save the frame pointer.
445c483
< Value *FieldPtr
---
> Value *JBufPtr
450,451c488,489
< Value *ElemPtr =
< GetElementPtrInst::Create(FieldPtr, Idxs, Idxs+2, "jbuf_fp_gep",
---
> Value *FramePtr =
> GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_fp_gep",
458,459c496,507
< new StoreInst(Val, ElemPtr, true, EntryBB->getTerminator());
< // Call the setjmp instrinsic. It fills in the rest of the jmpbuf
---
> new StoreInst(Val, FramePtr, true, EntryBB->getTerminator());
>
> // Save the stack pointer.
> Idxs[1] = ConstantInt::get(Int32Ty, 2);
> Value *StackPtr =
> GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_sp_gep",
> EntryBB->getTerminator());
>
> Val = CallInst::Create(StackAddrFn, "sp", EntryBB->getTerminator());
> new StoreInst(Val, StackPtr, true, EntryBB->getTerminator());
>
> // Call the setjmp instrinsic. It fills in the rest of the jmpbuf.
461c509
< CastInst::Create(Instruction::BitCast, FieldPtr,
---
> CastInst::Create(Instruction::BitCast, JBufPtr,
467c515
< // check the return value of the setjmp. non-zero goes to dispatcher
---
> // check the return value of the setjmp. non-zero goes to dispatcher.
511a560,569
> // Following any allocas not in the entry block, update the saved SP
> // in the jmpbuf to the new value.
> for (unsigned i = 0, e = JmpbufUpdatePoints.size(); i != e; ++i) {
> Instruction *AI = JmpbufUpdatePoints[i];
> Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp");
> StackAddr->insertAfter(AI);
> Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true);
> StoreStackAddr->insertAfter(StackAddr);
> }
>