-
- Value *Val = CallInst::Create(FrameAddrFn,
- ConstantInt::get(Int32Ty, 0),
- "fp",
- EntryBB->getTerminator());
- new StoreInst(Val, ElemPtr, true, EntryBB->getTerminator());
- // Call the setjmp instrinsic. It fills in the rest of the jmpbuf
- Value *SetjmpArg =
- CastInst::Create(Instruction::BitCast, FieldPtr,
- Type::getInt8Ty(F.getContext())->getPointerTo(), "",
- EntryBB->getTerminator());
- Value *DispatchVal = CallInst::Create(BuiltinSetjmpFn, SetjmpArg,
- "dispatch",
- EntryBB->getTerminator());
- // check the return value of the setjmp. non-zero goes to dispatcher
- Value *IsNormal = new ICmpInst(EntryBB->getTerminator(),
- ICmpInst::ICMP_EQ, DispatchVal, Zero,
- "notunwind");
- // Nuke the uncond branch.
- EntryBB->getTerminator()->eraseFromParent();
-
- // Put in a new condbranch in its place.
- BranchInst::Create(ContBlock, DispatchBlock, IsNormal, EntryBB);
-
- // Register the function context and make sure it's known to not throw
- CallInst *Register =
- CallInst::Create(RegisterFn, FunctionContext, "",
- ContBlock->getTerminator());
- Register->setDoesNotThrow();
-
- // At this point, we are all set up. Update the invoke instructions
- // to mark their call_site values, and fill in the dispatch switch
- // accordingly.
- DenseMap<BasicBlock*,unsigned> PadSites;
- unsigned NextCallSiteValue = 1;
- for (SmallVector<InvokeInst*,16>::iterator I = Invokes.begin(),
- E = Invokes.end(); I < E; ++I) {
- unsigned CallSiteValue;
- BasicBlock *LandingPad = (*I)->getSuccessor(1);
- // landing pads can be shared. If we see a landing pad again, we
- // want to make sure to use the same call site index so the dispatch
- // will go to the right place.
- CallSiteValue = PadSites[LandingPad];
- if (!CallSiteValue) {
- CallSiteValue = NextCallSiteValue++;
- PadSites[LandingPad] = CallSiteValue;
- // Add a switch case to our unwind block. The runtime comes back
- // to the dispatcher with the call_site - 1 in the context. Odd,
- // but there it is.
- ConstantInt *SwitchValC =
- ConstantInt::get(Type::getInt32Ty((*I)->getContext()),
- CallSiteValue - 1);
- DispatchSwitch->addCase(SwitchValC, (*I)->getUnwindDest());
- }
- markInvokeCallSite(*I, CallSiteValue, CallSite);
- }
-
- // The front end has likely added calls to _Unwind_Resume. We need
- // to find those calls and mark the call_site as -1 immediately prior.
- // resume is a noreturn function, so any block that has a call to it
- // should end in an 'unreachable' instruction with the call immediately
- // prior. That's how we'll search.
- // ??? There's got to be a better way. this is fugly.
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
- if ((dyn_cast<UnreachableInst>(BB->getTerminator()))) {
- BasicBlock::iterator I = BB->getTerminator();
- // Check the previous instruction and see if it's a resume call
- if (I == BB->begin()) continue;
- if (CallInst *CI = dyn_cast<CallInst>(--I)) {
- if (CI->getCalledFunction() == ResumeFn) {
- Value *NegativeOne = Constant::getAllOnesValue(Int32Ty);
- new StoreInst(NegativeOne, CallSite, true, I); // volatile
- }
- }
+ 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.
+ Value *SetjmpArg =
+ CastInst::Create(Instruction::BitCast, JBufPtr,
+ Type::getInt8PtrTy(F.getContext()), "",
+ EntryBB->getTerminator());
+ Value *DispatchVal = CallInst::Create(BuiltinSetjmpFn, SetjmpArg,
+ "dispatch",
+ EntryBB->getTerminator());
+
+ // Add a call to dispatch_setup after the setjmp call. This is expanded to any
+ // target-specific setup that needs to be done.
+ CallInst::Create(DispatchSetupFn, DispatchVal, "", EntryBB->getTerminator());
+
+ // check the return value of the setjmp. non-zero goes to dispatcher.
+ Value *IsNormal = new ICmpInst(EntryBB->getTerminator(),
+ ICmpInst::ICMP_EQ, DispatchVal, Zero,
+ "notunwind");
+ // Nuke the uncond branch.
+ EntryBB->getTerminator()->eraseFromParent();
+
+ // Put in a new condbranch in its place.
+ BranchInst::Create(ContBlock, DispatchBlock, IsNormal, EntryBB);
+
+ // Register the function context and make sure it's known to not throw
+ CallInst *Register =
+ CallInst::Create(RegisterFn, FunctionContext, "",
+ ContBlock->getTerminator());
+ Register->setDoesNotThrow();
+
+ // At this point, we are all set up, update the invoke instructions to mark
+ // their call_site values, and fill in the dispatch switch accordingly.
+ for (unsigned i = 0, e = Invokes.size(); i != e; ++i)
+ markInvokeCallSite(Invokes[i], i+1, CallSite, DispatchSwitch);
+
+ // Mark call instructions that aren't nounwind as no-action (call_site ==
+ // -1). Skip the entry block, as prior to then, no function context has been
+ // created for this function and any unexpected exceptions thrown will go
+ // directly to the caller's context, which is what we want anyway, so no need
+ // to do anything here.
+ for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) {
+ for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I)
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ // Ignore calls to the EH builtins (eh.selector, eh.exception)
+ Constant *Callee = CI->getCalledFunction();
+ if (Callee != SelectorFn && Callee != ExceptionFn
+ && !CI->doesNotThrow())
+ insertCallSiteStore(CI, -1, CallSite);