diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index 4d70b91..1af8804 100644 --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -89,7 +89,8 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty, } BasicBlock::iterator -SCEVExpander::findInsertPointAfter(Instruction *I, Instruction *MustDominate) { +SCEVExpander::findInsertPointAfter(Instruction *I, + Instruction *MustDominate) const { BasicBlock::iterator IP = ++I->getIterator(); if (auto *II = dyn_cast<InvokeInst>(I)) IP = II->getNormalDest()->begin(); @@ -114,6 +115,25 @@ SCEVExpander::findInsertPointAfter(Instruction *I, Instruction *MustDominate) { return IP; } +BasicBlock::iterator +SCEVExpander::GetOptimalInsertionPointForCastOf(Value *V) const { + // Cast the argument at the beginning of the entry block, after + // any bitcasts of other arguments. + if (Argument *A = dyn_cast<Argument>(V)) { + BasicBlock::iterator IP = A->getParent()->getEntryBlock().begin(); + while ((isa<BitCastInst>(IP) && + isa<Argument>(cast<BitCastInst>(IP)->getOperand(0)) && + cast<BitCastInst>(IP)->getOperand(0) != A) || + isa<DbgInfoIntrinsic>(IP)) + ++IP; + return IP; + } + + // Cast the instruction immediately after the instruction. + Instruction *I = cast<Instruction>(V); + return findInsertPointAfter(I, &*Builder.GetInsertPoint()); +} + /// 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. @@ -172,22 +192,8 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) { if (Constant *C = dyn_cast<Constant>(V)) return ConstantExpr::getCast(Op, C, Ty); - // Cast the argument at the beginning of the entry block, after - // any bitcasts of other arguments. - if (Argument *A = dyn_cast<Argument>(V)) { - BasicBlock::iterator IP = A->getParent()->getEntryBlock().begin(); - while ((isa<BitCastInst>(IP) && - isa<Argument>(cast<BitCastInst>(IP)->getOperand(0)) && - cast<BitCastInst>(IP)->getOperand(0) != A) || - 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 = findInsertPointAfter(I, &*Builder.GetInsertPoint()); - return ReuseOrCreateCast(I, Ty, Op, IP); + // Try to reuse existing cast, or insert one. + return ReuseOrCreateCast(V, Ty, Op, GetOptimalInsertionPointForCastOf(V)); } /// InsertBinop - Insert the specified binary operator, doing a small amount |