diff options
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/LICM.cpp | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index e62daa63cd..1ce0cbc1c4 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -286,15 +286,28 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) { for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end(); I != E; ++I) PromoteAliasSet(*I, ExitBlocks, InsertPts); - } - // If we have successfully changed the loop, re-form LCSSA and also re-form - // LCSSA in the parent loop as hoisting or sinking may have broken it. - if (Changed) { + // Once we have promoted values across the loop body we have to recursively + // reform LCSSA as any nested loop may now have values defined within the + // loop used in the outer loop. + // FIXME: This is really heavy handed. It would be a bit better to use an + // SSAUpdater strategy during promotion that was LCSSA aware and reformed + // it as it went. + if (Changed) + formLCSSARecursively(*L, *DT, getAnalysisIfAvailable<ScalarEvolution>()); + + } else if (Changed) { + // If we have successfully changed the loop but not used SSAUpdater to + // re-write instructions throughout the loop body, re-form LCSSA just for + // this loop. formLCSSA(*L, *DT, getAnalysisIfAvailable<ScalarEvolution>()); + } + + // Regardless of how we changed the loop, reform LCSSA on its parent as + // hoisting or sinking could have disrupted it. + if (Changed) if (Loop *ParentL = L->getParentLoop()) formLCSSA(*ParentL, *DT, getAnalysisIfAvailable<ScalarEvolution>()); - } // Clear out loops state information for the next iteration CurLoop = 0; |