diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h index 197fc13f04247..5d9340803ebb7 100644 --- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h +++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h @@ -382,7 +382,7 @@ class SCEVExpander : public SCEVVisitor { /// Returns a suitable insert point after \p I, that dominates \p /// MustDominate. Skips instructions inserted by the expander. BasicBlock::iterator findInsertPointAfter(Instruction *I, - Instruction *MustDominate); + Instruction *MustDominate) const; private: LLVMContext &getContext() const { return SE.getContext(); } @@ -415,6 +415,9 @@ class SCEVExpander : public SCEVVisitor { Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, SCEV::NoWrapFlags Flags, bool IsSafeToHoist); + /// We want to cast \p V. What would be the best place for such a cast? + BasicBlock::iterator GetOptimalInsertionPointForCastOf(Value *V) const; + /// Arrange for there to be a cast of V to Ty at IP, reusing an existing /// cast if a suitable one exists, moving an existing cast if a suitable one /// exists but isn't in the right place, or creating a new one. diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index 4d70b913e4d88..1af8804da46de 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(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(V)) { + BasicBlock::iterator IP = A->getParent()->getEntryBlock().begin(); + while ((isa(IP) && + isa(cast(IP)->getOperand(0)) && + cast(IP)->getOperand(0) != A) || + isa(IP)) + ++IP; + return IP; + } + + // Cast the instruction immediately after the instruction. + Instruction *I = cast(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(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(V)) { - BasicBlock::iterator IP = A->getParent()->getEntryBlock().begin(); - while ((isa(IP) && - isa(cast(IP)->getOperand(0)) && - cast(IP)->getOperand(0) != A) || - isa(IP)) - ++IP; - return ReuseOrCreateCast(A, Ty, Op, IP); - } - - // Cast the instruction immediately after the instruction. - Instruction *I = cast(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