+/// mergeLandingPadClauses - Visit all of the landing pad instructions merge the
+/// clauses from the new destination (the caller's landing pad).
+void InvokeInliningInfo::mergeLandingPadClauses(ResumeInst *RI) {
+ for (SmallVectorImpl<LandingPadInst*>::iterator
+ I = CalleeLPads.begin(), E = CalleeLPads.end(); I != E; ++I)
+ for (unsigned i = 0, e = CallerLPad->getNumClauses(); i != e; ++i)
+ (*I)->addClause(CallerLPad->getClauseType(i),
+ CallerLPad->getClauseValue(i));
+}
+
+/// forwardResume - Forward the 'resume' instruction to the caller's landing pad
+/// block. When the landing pad block has only one predecessor, this is a simple
+/// branch. When there is more than one predecessor, we need to split the
+/// landing pad block after the landingpad instruction and jump to there.
+void InvokeInliningInfo::forwardResume(ResumeInst *RI) {
+ BasicBlock *LPadBB = CallerLPad->getParent();
+ Value *ResumeOp = RI->getOperand(0);
+
+ if (!LPadBB->getSinglePredecessor()) {
+ // There are multiple predecessors to this landing pad block. Split this
+ // landing pad block and jump to the new BB.
+ BasicBlock *SplitLPad = getSplitLandingPad();
+ BranchInst::Create(SplitLPad, RI->getParent());
+
+ if (CallerLPad->hasOneUse() && isa<PHINode>(CallerLPad->use_back())) {
+ PHINode *PN = cast<PHINode>(CallerLPad->use_back());
+ PN->addIncoming(ResumeOp, RI->getParent());
+ } else {
+ PHINode *PN = PHINode::Create(ResumeOp->getType(), 0, "lpad.phi",
+ &SplitLPad->front());
+ CallerLPad->replaceAllUsesWith(PN);
+ PN->addIncoming(ResumeOp, RI->getParent());
+ PN->addIncoming(CallerLPad, LPadBB);
+ }
+
+ RI->eraseFromParent();
+ return;
+ }
+
+ BranchInst::Create(LPadBB, RI->getParent());
+ CallerLPad->replaceAllUsesWith(ResumeOp);
+ CallerLPad->eraseFromParent();
+ RI->eraseFromParent();
+}
+