Type *FunctionContextTy;
Constant *RegisterFn;
Constant *UnregisterFn;
- Constant *BuiltinSetjmpFn;
+ Constant *BuiltinSetupDispatchFn;
Constant *FrameAddrFn;
Constant *StackAddrFn;
Constant *StackRestoreFn;
} // end anonymous namespace
char SjLjEHPrepare::ID = 0;
+INITIALIZE_PASS(SjLjEHPrepare, "sjljehprepare", "Prepare SjLj exceptions",
+ false, false)
// Public Interface To the SjLjEHPrepare pass.
FunctionPass *llvm::createSjLjEHPreparePass() { return new SjLjEHPrepare(); }
FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress);
StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave);
StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore);
- BuiltinSetjmpFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setjmp);
+ BuiltinSetupDispatchFn =
+ Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setup_dispatch);
LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda);
CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite);
FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext);
// values and replace the LPI with that aggregate.
Type *LPadType = LPI->getType();
Value *LPadVal = UndefValue::get(LPadType);
- IRBuilder<> Builder(
- std::next(BasicBlock::iterator(cast<Instruction>(SelVal))));
+ auto *SelI = cast<Instruction>(SelVal);
+ IRBuilder<> Builder(SelI->getParent(), std::next(SelI->getIterator()));
LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val");
LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val");
/// it with all of the data that we know at this point.
Value *SjLjEHPrepare::setupFunctionContext(Function &F,
ArrayRef<LandingPadInst *> LPads) {
- BasicBlock *EntryBB = F.begin();
+ BasicBlock *EntryBB = &F.front();
// Create an alloca for the incoming jump buffer ptr and the new jump buffer
// that needs to be restored on all exits from the function. This is an alloca
auto &DL = F.getParent()->getDataLayout();
unsigned Align = DL.getPrefTypeAlignment(FunctionContextTy);
FuncCtx = new AllocaInst(FunctionContextTy, nullptr, Align, "fn_context",
- EntryBB->begin());
+ &EntryBB->front());
// Fill in the function context structure.
for (unsigned I = 0, E = LPads.size(); I != E; ++I) {
LandingPadInst *LPI = LPads[I];
- IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt());
+ IRBuilder<> Builder(LPI->getParent(),
+ LPI->getParent()->getFirstInsertionPt());
// Reference the __data field.
Value *FCData =
while (isa<AllocaInst>(AfterAllocaInsPt) &&
isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize()))
++AfterAllocaInsPt;
+ assert(AfterAllocaInsPt != F.front().end());
- for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE;
- ++AI) {
- Type *Ty = AI->getType();
+ for (auto &AI : F.args()) {
+ Type *Ty = AI.getType();
// Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction.
Value *TrueValue = ConstantInt::getTrue(F.getContext());
Value *UndefValue = UndefValue::get(Ty);
- Instruction *SI = SelectInst::Create(TrueValue, AI, UndefValue,
- AI->getName() + ".tmp",
- AfterAllocaInsPt);
- AI->replaceAllUsesWith(SI);
+ Instruction *SI = SelectInst::Create(
+ TrueValue, &AI, UndefValue, AI.getName() + ".tmp", &*AfterAllocaInsPt);
+ AI.replaceAllUsesWith(SI);
// Reset the operand, because it was clobbered by the RAUW above.
- SI->setOperand(1, AI);
+ SI->setOperand(1, &AI);
}
}
// Ignore obvious cases we don't have to handle. In particular, most
// instructions either have no uses or only have a single use inside the
// current block. Ignore them quickly.
- Instruction *Inst = II;
+ Instruction *Inst = &*II;
if (Inst->use_empty())
continue;
if (Inst->hasOneUse() &&
DemotePHIToStack(PN);
// Move the landingpad instruction back to the top of the landing pad block.
- LPI->moveBefore(UnwindBlock->begin());
+ LPI->moveBefore(&UnwindBlock->front());
}
}
Value *FuncCtx =
setupFunctionContext(F, makeArrayRef(LPads.begin(), LPads.end()));
- BasicBlock *EntryBB = F.begin();
+ BasicBlock *EntryBB = &F.front();
IRBuilder<> Builder(EntryBB->getTerminator());
// Get a reference to the jump buffer.
Val = Builder.CreateCall(StackAddrFn, {}, "sp");
Builder.CreateStore(Val, StackPtr, /*isVolatile=*/true);
- // Call the setjmp instrinsic. It fills in the rest of the jmpbuf.
- Value *SetjmpArg = Builder.CreateBitCast(JBufPtr, Builder.getInt8PtrTy());
- Builder.CreateCall(BuiltinSetjmpFn, SetjmpArg);
+ // Call the setup_dispatch instrinsic. It fills in the rest of the jmpbuf.
+ Builder.CreateCall(BuiltinSetupDispatchFn, {});
// Store a pointer to the function context so that the back-end will know
// where to look for it.
continue;
}
Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp");
- StackAddr->insertAfter(I);
+ StackAddr->insertAfter(&*I);
Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true);
StoreStackAddr->insertAfter(StackAddr);
}