summaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/InlineFunction.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-07-28 07:31:46 +0000
committerBill Wendling <isanbard@gmail.com>2011-07-28 07:31:46 +0000
commit9a2dde3fd12d9200716e02094deba883186e5ba9 (patch)
tree5bafeea9aed9356817d489ec097a5e6eacbb9686 /lib/Transforms/Utils/InlineFunction.cpp
parent71961846109c65f77a972a8c586cade62c35f081 (diff)
downloadllvm-9a2dde3fd12d9200716e02094deba883186e5ba9.tar.gz
llvm-9a2dde3fd12d9200716e02094deba883186e5ba9.tar.bz2
llvm-9a2dde3fd12d9200716e02094deba883186e5ba9.tar.xz
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
Diffstat (limited to 'lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp88
1 files changed, 56 insertions, 32 deletions
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<Value*, 8> 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<PHINode>(I); ++I) {
// Save the value to use for this edge.
- PHINode *phi = cast<PHINode>(I);
- UnwindDestPHIValues.push_back(phi->getIncomingValueForBlock(invokeBB));
+ PHINode *PHI = cast<PHINode>(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<PHINode>(I);
- phi->addIncoming(UnwindDestPHIValues[i], src);
+ PHINode *PHI = cast<PHINode>(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<PHINode>(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<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);
- }
+ 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();
}