-/// NormalizeLandingPads - Normalize and discover landing pads, noting them
-/// in the LandingPads set. A landing pad is normal if the only CFG edges
-/// that end at it are unwind edges from invoke instructions. If we inlined
-/// through an invoke we could have a normal branch from the previous
-/// unwind block through to the landing pad for the original invoke.
-/// Abnormal landing pads are fixed up by redirecting all unwind edges to
-/// a new basic block which falls through to the original.
-bool DwarfEHPrepare::NormalizeLandingPads() {
- bool Changed = false;
-
- for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
- TerminatorInst *TI = I->getTerminator();
- if (!isa<InvokeInst>(TI))
- continue;
- BasicBlock *LPad = TI->getSuccessor(1);
- // Skip landing pads that have already been normalized.
- if (LandingPads.count(LPad))
- continue;
-
- // Check that only invoke unwind edges end at the landing pad.
- bool OnlyUnwoundTo = true;
- for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad);
- PI != PE; ++PI) {
- TerminatorInst *PT = (*PI)->getTerminator();
- if (!isa<InvokeInst>(PT) || LPad == PT->getSuccessor(0)) {
- OnlyUnwoundTo = false;
- break;
- }
- }
-
- if (OnlyUnwoundTo) {
- // Only unwind edges lead to the landing pad. Remember the landing pad.
- LandingPads.insert(LPad);
- continue;
- }
-
- // At least one normal edge ends at the landing pad. Redirect the unwind
- // edges to a new basic block which falls through into this one.
-
- // Create the new basic block.
- BasicBlock *NewBB = BasicBlock::Create(F->getContext(),
- LPad->getName() + "_unwind_edge");
-
- // Insert it into the function right before the original landing pad.
- LPad->getParent()->getBasicBlockList().insert(LPad, NewBB);
-
- // Redirect unwind edges from the original landing pad to NewBB.
- for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad); PI != PE; ) {
- TerminatorInst *PT = (*PI++)->getTerminator();
- if (isa<InvokeInst>(PT) && PT->getSuccessor(1) == LPad)
- // Unwind to the new block.
- PT->setSuccessor(1, NewBB);
- }
-
- // If there are any PHI nodes in LPad, we need to update them so that they
- // merge incoming values from NewBB instead.
- for (BasicBlock::iterator II = LPad->begin(); isa<PHINode>(II); ++II) {
- PHINode *PN = cast<PHINode>(II);
- pred_iterator PB = pred_begin(NewBB), PE = pred_end(NewBB);
-
- // Check to see if all of the values coming in via unwind edges are the
- // same. If so, we don't need to create a new PHI node.
- Value *InVal = PN->getIncomingValueForBlock(*PB);
- for (pred_iterator PI = PB; PI != PE; ++PI) {
- if (PI != PB && InVal != PN->getIncomingValueForBlock(*PI)) {
- InVal = 0;
- break;
- }
+/// GetExceptionObject - Return the exception object from the value passed into
+/// the 'resume' instruction (typically an aggregate). Clean up any dead
+/// instructions, including the 'resume' instruction.
+Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) {
+ Value *V = RI->getOperand(0);
+ Value *ExnObj = 0;
+ InsertValueInst *SelIVI = dyn_cast<InsertValueInst>(V);
+ LoadInst *SelLoad = 0;
+ InsertValueInst *ExcIVI = 0;
+ bool EraseIVIs = false;
+
+ if (SelIVI) {
+ if (SelIVI->getNumIndices() == 1 && *SelIVI->idx_begin() == 1) {
+ ExcIVI = dyn_cast<InsertValueInst>(SelIVI->getOperand(0));
+ if (ExcIVI && isa<UndefValue>(ExcIVI->getOperand(0)) &&
+ ExcIVI->getNumIndices() == 1 && *ExcIVI->idx_begin() == 0) {
+ ExnObj = ExcIVI->getOperand(1);
+ SelLoad = dyn_cast<LoadInst>(SelIVI->getOperand(1));
+ EraseIVIs = true;