diff options
| author | Bill Wendling <isanbard@gmail.com> | 2011-12-14 22:45:33 +0000 |
|---|---|---|
| committer | Bill Wendling <isanbard@gmail.com> | 2011-12-14 22:45:33 +0000 |
| commit | b108aaebbe373abfb7b86edc06834376ac0981e7 (patch) | |
| tree | 3e92f34beb9b9f02b5b7cdfbd1528d04185a783a /llvm/lib/CodeGen | |
| parent | ad41ab5015aed4ca896371e5f107045b28ed73cb (diff) | |
| download | bcm5719-llvm-b108aaebbe373abfb7b86edc06834376ac0981e7.tar.gz bcm5719-llvm-b108aaebbe373abfb7b86edc06834376ac0981e7.zip | |
Reapply r146481 with a fix to create the Builder value in the correct place and
with the correct iterator.
<rdar://problem/10530851>
llvm-svn: 146600
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SjLjEHPrepare.cpp | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/SjLjEHPrepare.cpp b/llvm/lib/CodeGen/SjLjEHPrepare.cpp index c8651926c2f..8e2f74f0392 100644 --- a/llvm/lib/CodeGen/SjLjEHPrepare.cpp +++ b/llvm/lib/CodeGen/SjLjEHPrepare.cpp @@ -69,6 +69,8 @@ namespace { private: bool setupEntryBlockAndCallSites(Function &F); + void substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, + Value *SelVal); Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads); void lowerIncomingArguments(Function &F); void lowerAcrossUnwindEdges(Function &F, ArrayRef<InvokeInst*> Invokes); @@ -138,6 +140,38 @@ static void MarkBlocksLiveIn(BasicBlock *BB, MarkBlocksLiveIn(*PI, LiveBBs); } +/// substituteLPadValues - Substitute the values returned by the landingpad +/// instruction with those returned by the personality function. +void SjLjEHPass::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, + Value *SelVal) { + SmallVector<Value*, 8> UseWorkList(LPI->use_begin(), LPI->use_end()); + while (!UseWorkList.empty()) { + Value *Val = UseWorkList.pop_back_val(); + ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val); + if (!EVI) continue; + if (EVI->getNumIndices() != 1) continue; + if (*EVI->idx_begin() == 0) + EVI->replaceAllUsesWith(ExnVal); + else if (*EVI->idx_begin() == 1) + EVI->replaceAllUsesWith(SelVal); + if (EVI->getNumUses() == 0) + EVI->eraseFromParent(); + } + + if (LPI->getNumUses() == 0) return; + + // There are still some uses of LPI. Construct an aggregate with the exception + // values and replace the LPI with that aggregate. + Type *LPadType = LPI->getType(); + Value *LPadVal = UndefValue::get(LPadType); + IRBuilder<> + Builder(llvm::next(BasicBlock::iterator(cast<Instruction>(SelVal)))); + LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); + LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); + + LPI->replaceAllUsesWith(LPadVal); +} + /// setupFunctionContext - Allocate the function context on the stack and fill /// it with all of the data that we know at this point. Value *SjLjEHPass:: @@ -189,12 +223,7 @@ setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) { ExnVal = Builder.CreateIntToPtr(ExnVal, Type::getInt8PtrTy(F.getContext())); Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); - Type *LPadType = LPI->getType(); - Value *LPadVal = UndefValue::get(LPadType); - LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); - LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); - - LPI->replaceAllUsesWith(LPadVal); + substituteLPadValues(LPI, ExnVal, SelVal); } // Personality function |

