summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorIgor Laevsky <igmyrj@gmail.com>2016-10-11 13:37:22 +0000
committerIgor Laevsky <igmyrj@gmail.com>2016-10-11 13:37:22 +0000
commit04423cf785f917220a19e803c58f4f5023108137 (patch)
treeefa1d0b427ae7e133c3c83b6e98a1f6dd7240611 /llvm/lib/Analysis
parent6d71f7b348f10edfe134fb361b026eb49e777700 (diff)
downloadbcm5719-llvm-04423cf785f917220a19e803c58f4f5023108137.tar.gz
bcm5719-llvm-04423cf785f917220a19e803c58f4f5023108137.zip
[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 llvm-svn: 283877
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp66
1 files changed, 36 insertions, 30 deletions
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index a5f816dd5ad..d37443cbdbe 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -143,42 +143,48 @@ PHINode *Loop::getCanonicalInductionVariable() const {
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;
+// 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 (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;
- }
+ 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;
-
- return all_of(*this,
- [&](const Loop *L) { return L->isRecursivelyLCSSAForm(DT); });
+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);
+ });
+}
+
+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 {
OpenPOWER on IntegriCloud