Index: include/llvm/Transforms/Utils/LoopUtils.h =================================================================== --- include/llvm/Transforms/Utils/LoopUtils.h +++ include/llvm/Transforms/Utils/LoopUtils.h @@ -356,6 +356,10 @@ bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE); +/// \brief Check if all loops in the function \param F are in LCSSA form. +/// LoopInfo and DominatorTree are required. +bool isFunctionInLCSSAForm(Function &F, DominatorTree &DT, LoopInfo &LI); + /// \brief Walk the specified region of the CFG (defined by all blocks /// dominated by the specified block, and that are in the current loop) in /// reverse depth first order w.r.t the DominatorTree. This allows us to visit Index: lib/Transforms/Utils/LCSSA.cpp =================================================================== --- lib/Transforms/Utils/LCSSA.cpp +++ lib/Transforms/Utils/LCSSA.cpp @@ -270,6 +270,28 @@ return Changed; } +/// Check if all loops in a loop nest are in LCSSA form. +static bool isLoopNestInLCSSAForm(Loop &L, DominatorTree &DT) { + if (!L.isLCSSAForm(DT)) + return false; + + // Recurse through inner loops. + for (Loop *SubLoop : L) + if (!isLoopNestInLCSSAForm(*SubLoop, DT)) + return false; + + return true; +} + +/// Check if all loops in the function F are in LCSSA form. +bool llvm::isFunctionInLCSSAForm(Function &F, DominatorTree &DT, LoopInfo &LI) { + for (Loop *L : LI) + if (!isLoopNestInLCSSAForm(*L, DT)) + return false; + + return true; +} + namespace { struct LCSSA : public FunctionPass { static char ID; // Pass identification, replacement for typeid