diff --git a/llvm/include/llvm/Transforms/Scalar/LoopOptTutorial.h b/llvm/include/llvm/Transforms/Scalar/LoopOptTutorial.h index cad77541dfd6f..4ed633dd336ec 100644 --- a/llvm/include/llvm/Transforms/Scalar/LoopOptTutorial.h +++ b/llvm/include/llvm/Transforms/Scalar/LoopOptTutorial.h @@ -33,6 +33,10 @@ class LoopSplit { private: LoopInfo &LI; + + /// Determines if \p L is a candidate for splitting + bool isCandidate(const Loop &L) const; + }; class LoopOptTutorialPass : public PassInfoMixin { diff --git a/llvm/lib/Transforms/Scalar/LoopOptTutorial.cpp b/llvm/lib/Transforms/Scalar/LoopOptTutorial.cpp index c441a7123ec08..8e07f355384d1 100644 --- a/llvm/lib/Transforms/Scalar/LoopOptTutorial.cpp +++ b/llvm/lib/Transforms/Scalar/LoopOptTutorial.cpp @@ -27,22 +27,50 @@ bool LoopSplit::run(Loop &L) const { LLVM_DEBUG(dbgs() << "Entering " << __func__ << "\n"); - LLVM_DEBUG(dbgs() << "TODO: Need to check if Loop is a valid candidate\n"); + if (!isCandidate(L)) { + LLVM_DEBUG(dbgs() << "Loop " << L.getName() + << " is not a candidate for splitting.\n"); + return false; + } + + LLVM_DEBUG(dbgs() << "Loop " << L.getName() + << " is a candidate for splitting!\n"); return false; } +bool LoopSplit::isCandidate(const Loop &L) const { + // Require loops with preheaders and dedicated exits. + if (!L.isLoopSimplifyForm()) + return false; + + // Since we use cloning to split the loop, it has to be safe to clone. + if (!L.isSafeToClone()) + return false; + + // If the loop has multiple exiting blocks, do not split. + if (!L.getExitingBlock()) + return false; + + // If loop has multiple exit blocks, do not split. + if (!L.getExitBlock()) + return false; + + // Only split innermost loops. Thus, if the loop has any children, it cannot + // be split. + if (!L.getSubLoops().empty()) + return false; + + return true; +} + PreservedAnalyses LoopOptTutorialPass::run(Loop &L, LoopAnalysisManager &LAM, LoopStandardAnalysisResults &AR, LPMUpdater &U) { - bool Changed = false; - LLVM_DEBUG(dbgs() << "Entering LoopOptTutorialPass::run\n"); LLVM_DEBUG(dbgs() << "Loop: "; L.dump(); dbgs() << "\n"); - LoopSplit LS(AR.LI); - - Changed = LS.run(L); + bool Changed = LoopSplit(AR.LI).run(L); if (!Changed) return PreservedAnalyses::all();