diff options
author | Andrew Trick <atrick@apple.com> | 2011-09-28 01:35:36 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2011-09-28 01:35:36 +0000 |
commit | 909ef7db3dad5247648e1e89a34f1382815442b8 (patch) | |
tree | f87de65665e23cee49a9b0b0a268b29758a38084 /lib | |
parent | e6fadced87cef8faa69f00e3e13fc3a7369210b1 (diff) | |
download | llvm-909ef7db3dad5247648e1e89a34f1382815442b8.tar.gz llvm-909ef7db3dad5247648e1e89a34f1382815442b8.tar.bz2 llvm-909ef7db3dad5247648e1e89a34f1382815442b8.tar.xz |
indvars should hoist [sz]ext because licm is not rerun.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140670 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index e240c42e36..489289d8a0 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -834,6 +834,9 @@ public: PHINode *CreateWideIV(SCEVExpander &Rewriter); protected: + Value *getExtend(Value *NarrowOper, Type *WideType, bool IsSigned, + Instruction *Use); + Instruction *CloneIVUser(NarrowIVDefUse DU); const SCEVAddRecExpr *GetWideRecurrence(Instruction *NarrowUse); @@ -846,8 +849,27 @@ protected: }; } // anonymous namespace -static Value *getExtend( Value *NarrowOper, Type *WideType, - bool IsSigned, IRBuilder<> &Builder) { +/// isLoopInvariant - Perform a quick domtree based check for loop invariance +/// assuming that V is used within the loop. LoopInfo::isLoopInvariant() seems +/// gratuitous for this purpose. +static bool isLoopInvariant(Value *V, const Loop *L, const DominatorTree *DT) { + Instruction *Inst = dyn_cast<Instruction>(V); + if (!Inst) + return true; + + return DT->properlyDominates(Inst->getParent(), L->getHeader()); +} + +Value *WidenIV::getExtend(Value *NarrowOper, Type *WideType, bool IsSigned, + Instruction *Use) { + // Set the debug location and conservative insertion point. + IRBuilder<> Builder(Use); + // Hoist the insertion point into loop preheaders as far as possible. + for (const Loop *L = LI->getLoopFor(Use->getParent()); + L && L->getLoopPreheader() && isLoopInvariant(NarrowOper, L, DT); + L = L->getParentLoop()) + Builder.SetInsertPoint(L->getLoopPreheader()->getTerminator()); + return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) : Builder.CreateZExt(NarrowOper, WideType); } @@ -872,22 +894,21 @@ Instruction *WidenIV::CloneIVUser(NarrowIVDefUse DU) { case Instruction::AShr: DEBUG(dbgs() << "Cloning IVUser: " << *DU.NarrowUse << "\n"); - IRBuilder<> Builder(DU.NarrowUse); - // Replace NarrowDef operands with WideDef. Otherwise, we don't know // anything about the narrow operand yet so must insert a [sz]ext. It is // probably loop invariant and will be folded or hoisted. If it actually // comes from a widened IV, it should be removed during a future call to // WidenIVUse. Value *LHS = (DU.NarrowUse->getOperand(0) == DU.NarrowDef) ? DU.WideDef : - getExtend(DU.NarrowUse->getOperand(0), WideType, IsSigned, Builder); + getExtend(DU.NarrowUse->getOperand(0), WideType, IsSigned, DU.NarrowUse); Value *RHS = (DU.NarrowUse->getOperand(1) == DU.NarrowDef) ? DU.WideDef : - getExtend(DU.NarrowUse->getOperand(1), WideType, IsSigned, Builder); + getExtend(DU.NarrowUse->getOperand(1), WideType, IsSigned, DU.NarrowUse); BinaryOperator *NarrowBO = cast<BinaryOperator>(DU.NarrowUse); BinaryOperator *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS, RHS, NarrowBO->getName()); + IRBuilder<> Builder(DU.NarrowUse); Builder.Insert(WideBO); if (const OverflowingBinaryOperator *OBO = dyn_cast<OverflowingBinaryOperator>(NarrowBO)) { @@ -1391,17 +1412,6 @@ static Type *getBackedgeIVType(Loop *L) { return Ty; } -/// isLoopInvariant - Perform a quick domtree based check for loop invariance -/// assuming that V is used within the loop. LoopInfo::isLoopInvariant() seems -/// gratuitous for this purpose. -static bool isLoopInvariant(Value *V, Loop *L, DominatorTree *DT) { - Instruction *Inst = dyn_cast<Instruction>(V); - if (!Inst) - return true; - - return DT->properlyDominates(Inst->getParent(), L->getHeader()); -} - /// getLoopPhiForCounter - Return the loop header phi IFF IncV adds a loop /// invariant value to the phi. static PHINode *getLoopPhiForCounter(Value *IncV, Loop *L, DominatorTree *DT) { |