[llvm] r283877 - [LCSSA] Implement linear algorithm for the isRecursivelyLCSSAForm
Igor Laevsky via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 11 06:37:22 PDT 2016
Author: igor.laevsky
Date: Tue Oct 11 08:37:22 2016
New Revision: 283877
URL: http://llvm.org/viewvc/llvm-project?rev=283877&view=rev
Log:
[LCSSA] Implement linear algorithm for the isRecursivelyLCSSAForm
For each block check that it doesn't have any uses outside of it's innermost loop.
Differential Revision: https://reviews.llvm.org/D25364
Modified:
llvm/trunk/include/llvm/Analysis/LoopInfo.h
llvm/trunk/lib/Analysis/LoopInfo.cpp
llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=283877&r1=283876&r2=283877&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Tue Oct 11 08:37:22 2016
@@ -412,7 +412,7 @@ public:
bool isLCSSAForm(DominatorTree &DT) const;
/// Return true if this Loop and all inner subloops are in LCSSA form.
- bool isRecursivelyLCSSAForm(DominatorTree &DT) const;
+ bool isRecursivelyLCSSAForm(DominatorTree &DT, const LoopInfo &LI) const;
/// Return true if the Loop is in the form that the LoopSimplify form
/// transforms loops to, which is sometimes called normal form.
Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=283877&r1=283876&r2=283877&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopInfo.cpp Tue Oct 11 08:37:22 2016
@@ -143,42 +143,48 @@ PHINode *Loop::getCanonicalInductionVari
return nullptr;
}
-bool Loop::isLCSSAForm(DominatorTree &DT) const {
- for (BasicBlock *BB : this->blocks()) {
- for (Instruction &I : *BB) {
- // Tokens can't be used in PHI nodes and live-out tokens prevent loop
- // optimizations, so for the purposes of considered LCSSA form, we
- // can ignore them.
- if (I.getType()->isTokenTy())
- continue;
-
- for (Use &U : I.uses()) {
- Instruction *UI = cast<Instruction>(U.getUser());
- BasicBlock *UserBB = UI->getParent();
- if (PHINode *P = dyn_cast<PHINode>(UI))
- UserBB = P->getIncomingBlock(U);
-
- // Check the current block, as a fast-path, before checking whether
- // the use is anywhere in the loop. Most values are used in the same
- // block they are defined in. Also, blocks not reachable from the
- // entry are special; uses in them don't need to go through PHIs.
- if (UserBB != BB &&
- !contains(UserBB) &&
- DT.isReachableFromEntry(UserBB))
- return false;
- }
+// Check that 'BB' doesn't have any uses outside of the 'L'
+static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB,
+ DominatorTree &DT) {
+ for (const Instruction &I : BB) {
+ // Tokens can't be used in PHI nodes and live-out tokens prevent loop
+ // optimizations, so for the purposes of considered LCSSA form, we
+ // can ignore them.
+ if (I.getType()->isTokenTy())
+ continue;
+
+ for (const Use &U : I.uses()) {
+ const Instruction *UI = cast<Instruction>(U.getUser());
+ const BasicBlock *UserBB = UI->getParent();
+ if (const PHINode *P = dyn_cast<PHINode>(UI))
+ UserBB = P->getIncomingBlock(U);
+
+ // Check the current block, as a fast-path, before checking whether
+ // the use is anywhere in the loop. Most values are used in the same
+ // block they are defined in. Also, blocks not reachable from the
+ // entry are special; uses in them don't need to go through PHIs.
+ if (UserBB != &BB && !L.contains(UserBB) &&
+ DT.isReachableFromEntry(UserBB))
+ return false;
}
}
-
return true;
}
-bool Loop::isRecursivelyLCSSAForm(DominatorTree &DT) const {
- if (!isLCSSAForm(DT))
- return false;
+bool Loop::isLCSSAForm(DominatorTree &DT) const {
+ // For each block we check that it doesn't have any uses outside of this loop.
+ return all_of(this->blocks(), [&](const BasicBlock *BB) {
+ return isBlockInLCSSAForm(*this, *BB, DT);
+ });
+}
- return all_of(*this,
- [&](const Loop *L) { return L->isRecursivelyLCSSAForm(DT); });
+bool Loop::isRecursivelyLCSSAForm(DominatorTree &DT, const LoopInfo &LI) const {
+ // For each block we check that it doesn't have any uses outside of it's
+ // innermost loop. This process will transitivelly guarntee that current loop
+ // and all of the nested loops are in the LCSSA form.
+ return all_of(this->blocks(), [&](const BasicBlock *BB) {
+ return isBlockInLCSSAForm(*LI.getLoopFor(BB), *BB, DT);
+ });
}
bool Loop::isLoopSimplifyForm() const {
Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=283877&r1=283876&r2=283877&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Oct 11 08:37:22 2016
@@ -505,7 +505,8 @@ Value *IndVarSimplify::expandSCEVIfNeede
/// constant operands at the beginning of the loop.
void IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
// Check a pre-condition.
- assert(L->isRecursivelyLCSSAForm(*DT) && "Indvars did not preserve LCSSA!");
+ assert(L->isRecursivelyLCSSAForm(*DT, *LI) &&
+ "Indvars did not preserve LCSSA!");
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
@@ -2184,7 +2185,8 @@ void IndVarSimplify::sinkUnusedInvariant
bool IndVarSimplify::run(Loop *L) {
// We need (and expect!) the incoming loop to be in LCSSA.
- assert(L->isRecursivelyLCSSAForm(*DT) && "LCSSA required to run indvars!");
+ assert(L->isRecursivelyLCSSAForm(*DT, *LI) &&
+ "LCSSA required to run indvars!");
// If LoopSimplify form is not available, stay out of trouble. Some notes:
// - LSR currently only supports LoopSimplify-form loops. Indvars'
@@ -2277,7 +2279,8 @@ bool IndVarSimplify::run(Loop *L) {
Changed |= DeleteDeadPHIs(L->getHeader(), TLI);
// Check a post-condition.
- assert(L->isRecursivelyLCSSAForm(*DT) && "Indvars did not preserve LCSSA!");
+ assert(L->isRecursivelyLCSSAForm(*DT, *LI) &&
+ "Indvars did not preserve LCSSA!");
// Verify that LFTR, and any other change have not interfered with SCEV's
// ability to compute trip count.
Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=283877&r1=283876&r2=283877&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Tue Oct 11 08:37:22 2016
@@ -323,7 +323,8 @@ struct LCSSAWrapperPass : public Functio
bool runOnFunction(Function &F) override;
void verifyAnalysis() const override {
assert(
- all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); }) &&
+ all_of(*LI,
+ [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT, *LI); }) &&
"LCSSA form is broken!");
};
Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=283877&r1=283876&r2=283877&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Tue Oct 11 08:37:22 2016
@@ -366,7 +366,7 @@ static Loop *separateNestedLoop(Loop *L,
// already be a use of an LCSSA phi node.
formLCSSA(*L, *DT, LI, SE);
- assert(NewOuter->isRecursivelyLCSSAForm(*DT) &&
+ assert(NewOuter->isRecursivelyLCSSAForm(*DT, *LI) &&
"LCSSA is broken after separating nested loops!");
}
@@ -810,8 +810,8 @@ bool LoopSimplify::runOnFunction(Functio
if (PreserveLCSSA) {
assert(DT && "DT not available.");
assert(LI && "LI not available.");
- bool InLCSSA =
- all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
+ bool InLCSSA = all_of(
+ *LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT, *LI); });
assert(InLCSSA && "Requested to preserve LCSSA, but it's already broken.");
}
#endif
@@ -822,8 +822,8 @@ bool LoopSimplify::runOnFunction(Functio
#ifndef NDEBUG
if (PreserveLCSSA) {
- bool InLCSSA =
- all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
+ bool InLCSSA = all_of(
+ *LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT, *LI); });
assert(InLCSSA && "LCSSA is broken after loop-simplify.");
}
#endif
More information about the llvm-commits
mailing list