Skip to content

Commit fa28440

Browse files
committed
Leverage some of the code that John wrote to manage the landing pads.
The new EH is more simple in many respects. Mainly, we don't have to worry about the "llvm.eh.exception" and "llvm.eh.selector" calls being in weird places. llvm-svn: 136339
1 parent d8c1c1f commit fa28440

File tree

1 file changed

+56
-32
lines changed

1 file changed

+56
-32
lines changed

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
434475
void 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

Comments
 (0)