@@ -250,24 +250,29 @@ namespace {
250250 PHINode *InnerSelectorPHI;
251251 SmallVector<Value*, 8 > UnwindDestPHIValues;
252252
253- PHINode *InnerEHValuesPHI;
253+ // New EH:
254+ BasicBlock *OuterResumeDest;
255+ BasicBlock *InnerResumeDest;
254256 LandingPadInst *CallerLPad;
257+ PHINode *InnerEHValuesPHI;
255258 BasicBlock *SplitLPad;
256259
257260 public:
258261 InvokeInliningInfo (InvokeInst *II)
259262 : OuterUnwindDest(II->getUnwindDest ()), OuterSelector(0 ),
260263 InnerUnwindDest(0 ), InnerExceptionPHI(0 ), InnerSelectorPHI(0 ),
261- InnerEHValuesPHI(0 ), CallerLPad(0 ), SplitLPad(0 ) {
264+
265+ OuterResumeDest(II->getUnwindDest ()), InnerResumeDest(0 ),
266+ CallerLPad(0 ), InnerEHValuesPHI(0 ), SplitLPad(0 ) {
262267 // If there are PHI nodes in the unwind destination block, we
263268 // need to keep track of which values came into them from the
264269 // invoke before removing the edge from this block.
265- llvm::BasicBlock *invokeBB = II->getParent ();
270+ llvm::BasicBlock *InvokeBB = II->getParent ();
266271 BasicBlock::iterator I = OuterUnwindDest->begin ();
267272 for (; isa<PHINode>(I); ++I) {
268273 // Save the value to use for this edge.
269- PHINode *phi = cast<PHINode>(I);
270- UnwindDestPHIValues.push_back (phi ->getIncomingValueForBlock (invokeBB ));
274+ PHINode *PHI = cast<PHINode>(I);
275+ UnwindDestPHIValues.push_back (PHI ->getIncomingValueForBlock (InvokeBB ));
271276 }
272277
273278 // FIXME: With the new EH, this if/dyn_cast should be a 'cast'.
@@ -288,6 +293,7 @@ namespace {
288293 }
289294
290295 BasicBlock *getInnerUnwindDest ();
296+ BasicBlock *getInnerUnwindDest_new ();
291297
292298 LandingPadInst *getLandingPadInst () const { return CallerLPad; }
293299 BasicBlock *getSplitLandingPad () {
@@ -316,8 +322,8 @@ namespace {
316322 void addIncomingPHIValuesForInto (BasicBlock *src, BasicBlock *dest) const {
317323 BasicBlock::iterator I = dest->begin ();
318324 for (unsigned i = 0 , e = UnwindDestPHIValues.size (); i != e; ++i, ++I) {
319- PHINode *phi = cast<PHINode>(I);
320- phi ->addIncoming (UnwindDestPHIValues[i], src);
325+ PHINode *PHI = cast<PHINode>(I);
326+ PHI ->addIncoming (UnwindDestPHIValues[i], src);
321327 }
322328 }
323329 };
@@ -427,38 +433,56 @@ bool InvokeInliningInfo::forwardEHResume(CallInst *call, BasicBlock *src) {
427433 return true ;
428434}
429435
436+ // / Get or create a target for the branch from ResumeInsts.
437+ BasicBlock *InvokeInliningInfo::getInnerUnwindDest_new () {
438+ if (InnerResumeDest) return InnerResumeDest;
439+
440+ // Split the landing pad.
441+ BasicBlock::iterator SplitPoint = CallerLPad; ++SplitPoint;
442+ InnerResumeDest =
443+ OuterResumeDest->splitBasicBlock (SplitPoint,
444+ OuterResumeDest->getName () + " .body" );
445+
446+ // The number of incoming edges we expect to the inner landing pad.
447+ const unsigned PHICapacity = 2 ;
448+
449+ // Create corresponding new PHIs for all the PHIs in the outer landing pad.
450+ BasicBlock::iterator InsertPoint = InnerResumeDest->begin ();
451+ BasicBlock::iterator I = OuterResumeDest->begin ();
452+ for (unsigned i = 0 , e = UnwindDestPHIValues.size (); i != e; ++i, ++I) {
453+ PHINode *OuterPHI = cast<PHINode>(I);
454+ PHINode *InnerPHI = PHINode::Create (OuterPHI->getType (), PHICapacity,
455+ OuterPHI->getName () + " .lpad-body" ,
456+ InsertPoint);
457+ OuterPHI->replaceAllUsesWith (InnerPHI);
458+ InnerPHI->addIncoming (OuterPHI, OuterResumeDest);
459+ }
460+
461+ // Create a PHI for the exception values.
462+ InnerEHValuesPHI = PHINode::Create (CallerLPad->getType (), PHICapacity,
463+ " eh.lpad-body" , InsertPoint);
464+ CallerLPad->replaceAllUsesWith (InnerEHValuesPHI);
465+ InnerEHValuesPHI->addIncoming (CallerLPad, OuterResumeDest);
466+
467+ // All done.
468+ return InnerResumeDest;
469+ }
470+
430471// / forwardResume - Forward the 'resume' instruction to the caller's landing pad
431472// / block. When the landing pad block has only one predecessor, this is a simple
432473// / branch. When there is more than one predecessor, we need to split the
433474// / landing pad block after the landingpad instruction and jump to there.
434475void InvokeInliningInfo::forwardResume (ResumeInst *RI) {
435- BasicBlock *LPadBB = CallerLPad->getParent ();
436- Value *ResumeOp = RI->getOperand (0 );
437-
438- if (!LPadBB->getSinglePredecessor ()) {
439- // There are multiple predecessors to this landing pad block. Split this
440- // landing pad block and jump to the new BB.
441- BasicBlock *SplitLPad = getSplitLandingPad ();
442- BranchInst::Create (SplitLPad, RI->getParent ());
443-
444- if (CallerLPad->hasOneUse () && isa<PHINode>(CallerLPad->use_back ())) {
445- PHINode *PN = cast<PHINode>(CallerLPad->use_back ());
446- PN->addIncoming (ResumeOp, RI->getParent ());
447- } else {
448- PHINode *PN = PHINode::Create (ResumeOp->getType (), 0 , " lpad.phi" ,
449- &SplitLPad->front ());
450- CallerLPad->replaceAllUsesWith (PN);
451- PN->addIncoming (ResumeOp, RI->getParent ());
452- PN->addIncoming (CallerLPad, LPadBB);
453- }
476+ BasicBlock *Dest = getInnerUnwindDest_new ();
477+ BasicBlock *Src = RI->getParent ();
454478
455- RI->eraseFromParent ();
456- return ;
457- }
479+ BranchInst::Create (Dest, Src);
480+
481+ // Update the PHIs in the destination. They were inserted in an order which
482+ // makes this work.
483+ addIncomingPHIValuesForInto (Src, Dest);
458484
459- BranchInst::Create (LPadBB, RI->getParent ());
460- CallerLPad->replaceAllUsesWith (ResumeOp);
461- CallerLPad->eraseFromParent ();
485+ InnerEHValuesPHI->addIncoming (RI->getOperand (0 ), Src);
462486 RI->eraseFromParent ();
463487}
464488
0 commit comments