diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-10-27 07:36:42 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-10-27 07:36:42 +0000 |
commit | dd9a81574678d4ee2df9f30ab89f15a8e8b2d1ca (patch) | |
tree | ee547675f421d84cff75bb54c1a3f87078bc9ad3 /llvm/lib | |
parent | c75f0e8f4abb5681ee66bfdc5a37ee96a1ae0df9 (diff) | |
download | bcm5719-llvm-dd9a81574678d4ee2df9f30ab89f15a8e8b2d1ca.tar.gz bcm5719-llvm-dd9a81574678d4ee2df9f30ab89f15a8e8b2d1ca.zip |
[ScalarEvolutionExpander] Properly insert no-op casts + EH Pads
We want to insert no-op casts as close as possible to the def. This is
tricky when the cast is of a PHI node and the BasicBlocks between the
def and the use cannot hold any instructions. Iteratively walk EH pads
until we hit a non-EH pad.
This fixes PR25326.
llvm-svn: 251393
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp index 86c2f50ac29..428d989285c 100644 --- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp @@ -86,6 +86,41 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty, return Ret; } +static BasicBlock::iterator findInsertPointAfter(Instruction *I, + DominatorTree &DT, + BasicBlock *MustDominate) { + BasicBlock::iterator IP = ++I->getIterator(); + if (auto *II = dyn_cast<InvokeInst>(I)) + IP = II->getNormalDest()->begin(); + if (auto *CPI = dyn_cast<CatchPadInst>(I)) + IP = CPI->getNormalDest()->begin(); + + while (isa<PHINode>(IP)) + ++IP; + + while (IP->isEHPad()) { + if (isa<LandingPadInst>(IP) || isa<CleanupPadInst>(IP)) { + ++IP; + } else if (auto *TPI = dyn_cast<TerminatePadInst>(IP)) { + IP = TPI->getUnwindDest()->getFirstNonPHI(); + } else if (auto *CEPI = dyn_cast<CatchEndPadInst>(IP)) { + IP = CEPI->getUnwindDest()->getFirstNonPHI(); + } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(IP)) { + IP = CEPI->getUnwindDest()->getFirstNonPHI(); + } else if (auto *CPI = dyn_cast<CatchPadInst>(IP)) { + BasicBlock *NormalDest = CPI->getNormalDest(); + if (NormalDest == MustDominate || DT.dominates(NormalDest, MustDominate)) + IP = NormalDest->getFirstNonPHI(); + else + IP = CPI->getUnwindDest()->getFirstNonPHI(); + } else { + llvm_unreachable("unexpected eh pad!"); + } + } + + return IP; +} + /// InsertNoopCastOfTo - Insert a cast of V to the specified type, /// which must be possible with a noop cast, doing what we can to share /// the casts. @@ -135,21 +170,15 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) { while ((isa<BitCastInst>(IP) && isa<Argument>(cast<BitCastInst>(IP)->getOperand(0)) && cast<BitCastInst>(IP)->getOperand(0) != A) || - isa<DbgInfoIntrinsic>(IP) || - isa<LandingPadInst>(IP)) + isa<DbgInfoIntrinsic>(IP)) ++IP; return ReuseOrCreateCast(A, Ty, Op, IP); } // Cast the instruction immediately after the instruction. Instruction *I = cast<Instruction>(V); - BasicBlock::iterator IP = ++I->getIterator(); - if (InvokeInst *II = dyn_cast<InvokeInst>(I)) - IP = II->getNormalDest()->begin(); - if (CatchPadInst *CPI = dyn_cast<CatchPadInst>(I)) - IP = CPI->getNormalDest()->begin(); - while (isa<PHINode>(IP) || isa<LandingPadInst>(IP)) - ++IP; + BasicBlock::iterator IP = + findInsertPointAfter(I, SE.DT, Builder.GetInsertBlock()); return ReuseOrCreateCast(I, Ty, Op, IP); } @@ -1394,12 +1423,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { NewOps[i] = SE.getAnyExtendExpr(S->op_begin()[i], CanonicalIV->getType()); Value *V = expand(SE.getAddRecExpr(NewOps, S->getLoop(), S->getNoWrapFlags(SCEV::FlagNW))); - BasicBlock::iterator NewInsertPt = - std::next(BasicBlock::iterator(cast<Instruction>(V))); - BuilderType::InsertPointGuard Guard(Builder); - while (isa<PHINode>(NewInsertPt) || isa<DbgInfoIntrinsic>(NewInsertPt) || - isa<LandingPadInst>(NewInsertPt)) - ++NewInsertPt; + BasicBlock::iterator NewInsertPt = findInsertPointAfter( + cast<Instruction>(V), SE.DT, Builder.GetInsertBlock()); V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), nullptr, &*NewInsertPt); return V; |