Index: include/llvm/Transforms/Utils/LoopRotationUtils.h =================================================================== --- include/llvm/Transforms/Utils/LoopRotationUtils.h +++ include/llvm/Transforms/Utils/LoopRotationUtils.h @@ -25,10 +25,10 @@ class TargetTransformInfo; /// \brief Convert a loop into a loop with bottom test. -bool LoopRotation(Loop *L, unsigned MaxHeaderSize, LoopInfo *LI, - const TargetTransformInfo *TTI, AssumptionCache *AC, - DominatorTree *DT, ScalarEvolution *SE, - const SimplifyQuery &SQ); +bool LoopRotation(Loop *L, LoopInfo *LI, const TargetTransformInfo *TTI, + AssumptionCache *AC, DominatorTree *DT, ScalarEvolution *SE, + const SimplifyQuery &SQ, bool RotationOnly, + unsigned Threshold); } // namespace llvm Index: lib/Transforms/Scalar/LoopRotation.cpp =================================================================== --- lib/Transforms/Scalar/LoopRotation.cpp +++ lib/Transforms/Scalar/LoopRotation.cpp @@ -40,8 +40,8 @@ const DataLayout &DL = L.getHeader()->getModule()->getDataLayout(); const SimplifyQuery SQ = getBestSimplifyQuery(AR, DL); - bool Changed = - LoopRotation(&L, Threshold, &AR.LI, &AR.TTI, &AR.AC, &AR.DT, &AR.SE, SQ); + bool Changed = LoopRotation(&L, &AR.LI, &AR.TTI, &AR.AC, &AR.DT, &AR.SE, SQ, + false, Threshold); if (!Changed) return PreservedAnalyses::all(); @@ -84,7 +84,7 @@ auto *SEWP = getAnalysisIfAvailable(); auto *SE = SEWP ? &SEWP->getSE() : nullptr; const SimplifyQuery SQ = getBestSimplifyQuery(*this, F); - return LoopRotation(L, MaxHeaderSize, LI, TTI, AC, DT, SE, SQ); + return LoopRotation(L, LI, TTI, AC, DT, SE, SQ, false, MaxHeaderSize); } }; } Index: lib/Transforms/Utils/LoopRotationUtils.cpp =================================================================== --- lib/Transforms/Utils/LoopRotationUtils.cpp +++ lib/Transforms/Utils/LoopRotationUtils.cpp @@ -54,13 +54,15 @@ DominatorTree *DT; ScalarEvolution *SE; const SimplifyQuery &SQ; + bool RotationOnly; public: LoopRotate(unsigned MaxHeaderSize, LoopInfo *LI, const TargetTransformInfo *TTI, AssumptionCache *AC, - DominatorTree *DT, ScalarEvolution *SE, const SimplifyQuery &SQ) + DominatorTree *DT, ScalarEvolution *SE, const SimplifyQuery &SQ, + bool RotationOnly) : MaxHeaderSize(MaxHeaderSize), LI(LI), TTI(TTI), AC(AC), DT(DT), SE(SE), - SQ(SQ) {} + SQ(SQ), RotationOnly(RotationOnly) {} bool processLoop(Loop *L); private: @@ -604,10 +606,13 @@ // Save the loop metadata. MDNode *LoopMD = L->getLoopID(); + bool SimplifiedLatch = false; + // Simplify the loop latch before attempting to rotate the header // upward. Rotation may not be needed if the loop tail can be folded into the // loop exit. - bool SimplifiedLatch = simplifyLoopLatch(L); + if (!RotationOnly) + SimplifiedLatch = simplifyLoopLatch(L); bool MadeChange = rotateLoop(L, SimplifiedLatch); assert((!MadeChange || L->isLoopExiting(L->getLoopLatch())) && @@ -623,11 +628,12 @@ /// The utility to convert a loop into a loop with bottom test. -bool llvm::LoopRotation(Loop *L, unsigned MaxHeaderSize, LoopInfo *LI, - const TargetTransformInfo *TTI, AssumptionCache *AC, - DominatorTree *DT, ScalarEvolution *SE, - const SimplifyQuery &SQ) { - LoopRotate LR(MaxHeaderSize, LI, TTI, AC, DT, SE, SQ); +bool llvm::LoopRotation(Loop *L, LoopInfo *LI, const TargetTransformInfo *TTI, + AssumptionCache *AC, DominatorTree *DT, + ScalarEvolution *SE, const SimplifyQuery &SQ, + bool RotationOnly = true, + unsigned Threshold = unsigned(-1)) { + LoopRotate LR(Threshold, LI, TTI, AC, DT, SE, SQ, RotationOnly); return LR.processLoop(L); }