From 9a2dde3fd12d9200716e02094deba883186e5ba9 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 28 Jul 2011 07:31:46 +0000 Subject: 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136339 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/InlineFunction.cpp | 88 +++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 32 deletions(-) (limited to 'lib/Transforms/Utils/InlineFunction.cpp') diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index 8eda3e0b0d..5cba7ee823 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -250,24 +250,29 @@ namespace { PHINode *InnerSelectorPHI; SmallVector UnwindDestPHIValues; - PHINode *InnerEHValuesPHI; + // New EH: + BasicBlock *OuterResumeDest; + BasicBlock *InnerResumeDest; LandingPadInst *CallerLPad; + PHINode *InnerEHValuesPHI; BasicBlock *SplitLPad; public: InvokeInliningInfo(InvokeInst *II) : OuterUnwindDest(II->getUnwindDest()), OuterSelector(0), InnerUnwindDest(0), InnerExceptionPHI(0), InnerSelectorPHI(0), - InnerEHValuesPHI(0), CallerLPad(0), SplitLPad(0) { + + OuterResumeDest(II->getUnwindDest()), InnerResumeDest(0), + CallerLPad(0), InnerEHValuesPHI(0), SplitLPad(0) { // If there are PHI nodes in the unwind destination block, we // need to keep track of which values came into them from the // invoke before removing the edge from this block. - llvm::BasicBlock *invokeBB = II->getParent(); + llvm::BasicBlock *InvokeBB = II->getParent(); BasicBlock::iterator I = OuterUnwindDest->begin(); for (; isa(I); ++I) { // Save the value to use for this edge. - PHINode *phi = cast(I); - UnwindDestPHIValues.push_back(phi->getIncomingValueForBlock(invokeBB)); + PHINode *PHI = cast(I); + UnwindDestPHIValues.push_back(PHI->getIncomingValueForBlock(InvokeBB)); } // FIXME: With the new EH, this if/dyn_cast should be a 'cast'. @@ -288,6 +293,7 @@ namespace { } BasicBlock *getInnerUnwindDest(); + BasicBlock *getInnerUnwindDest_new(); LandingPadInst *getLandingPadInst() const { return CallerLPad; } BasicBlock *getSplitLandingPad() { @@ -316,8 +322,8 @@ namespace { void addIncomingPHIValuesForInto(BasicBlock *src, BasicBlock *dest) const { BasicBlock::iterator I = dest->begin(); for (unsigned i = 0, e = UnwindDestPHIValues.size(); i != e; ++i, ++I) { - PHINode *phi = cast(I); - phi->addIncoming(UnwindDestPHIValues[i], src); + PHINode *PHI = cast(I); + PHI->addIncoming(UnwindDestPHIValues[i], src); } } }; @@ -427,38 +433,56 @@ bool InvokeInliningInfo::forwardEHResume(CallInst *call, BasicBlock *src) { return true; } +/// Get or create a target for the branch from ResumeInsts. +BasicBlock *InvokeInliningInfo::getInnerUnwindDest_new() { + if (InnerResumeDest) return InnerResumeDest; + + // Split the landing pad. + BasicBlock::iterator SplitPoint = CallerLPad; ++SplitPoint; + InnerResumeDest = + OuterResumeDest->splitBasicBlock(SplitPoint, + OuterResumeDest->getName() + ".body"); + + // The number of incoming edges we expect to the inner landing pad. + const unsigned PHICapacity = 2; + + // Create corresponding new PHIs for all the PHIs in the outer landing pad. + BasicBlock::iterator InsertPoint = InnerResumeDest->begin(); + BasicBlock::iterator I = OuterResumeDest->begin(); + for (unsigned i = 0, e = UnwindDestPHIValues.size(); i != e; ++i, ++I) { + PHINode *OuterPHI = cast(I); + PHINode *InnerPHI = PHINode::Create(OuterPHI->getType(), PHICapacity, + OuterPHI->getName() + ".lpad-body", + InsertPoint); + OuterPHI->replaceAllUsesWith(InnerPHI); + InnerPHI->addIncoming(OuterPHI, OuterResumeDest); + } + + // Create a PHI for the exception values. + InnerEHValuesPHI = PHINode::Create(CallerLPad->getType(), PHICapacity, + "eh.lpad-body", InsertPoint); + CallerLPad->replaceAllUsesWith(InnerEHValuesPHI); + InnerEHValuesPHI->addIncoming(CallerLPad, OuterResumeDest); + + // All done. + return InnerResumeDest; +} + /// 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(CallerLPad->use_back())) { - PHINode *PN = cast(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); - } + BasicBlock *Dest = getInnerUnwindDest_new(); + BasicBlock *Src = RI->getParent(); - RI->eraseFromParent(); - return; - } + BranchInst::Create(Dest, Src); + + // Update the PHIs in the destination. They were inserted in an order which + // makes this work. + addIncomingPHIValuesForInto(Src, Dest); - BranchInst::Create(LPadBB, RI->getParent()); - CallerLPad->replaceAllUsesWith(ResumeOp); - CallerLPad->eraseFromParent(); + InnerEHValuesPHI->addIncoming(RI->getOperand(0), Src); RI->eraseFromParent(); } -- cgit v1.2.3