aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp')
-rw-r--r--contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp220
1 files changed, 110 insertions, 110 deletions
diff --git a/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp b/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
index 9746a415bf..7133abcc35 100644
--- a/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
+++ b/contrib/libs/llvm12/lib/Analysis/LoopNestAnalysis.cpp
@@ -42,7 +42,7 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
LoopNest::LoopNest(Loop &Root, ScalarEvolution &SE)
: MaxPerfectDepth(getMaxPerfectDepth(Root, SE)) {
- append_range(Loops, breadth_first(&Root));
+ append_range(Loops, breadth_first(&Root));
}
std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root,
@@ -52,8 +52,8 @@ std::unique_ptr<LoopNest> LoopNest::getLoopNest(Loop &Root,
bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
ScalarEvolution &SE) {
- assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
- assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
+ assert(!OuterLoop.isInnermost() && "Outer loop should have subloops");
+ assert(!InnerLoop.isOutermost() && "Inner loop should have a parent");
LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName()
<< "' and '" << InnerLoop.getName()
<< "' are perfectly nested.\n");
@@ -205,31 +205,31 @@ unsigned LoopNest::getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE) {
return CurrentDepth;
}
-const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From,
- const BasicBlock *End) {
- assert(From && "Expecting valid From");
- assert(End && "Expecting valid End");
-
- if (From == End || !From->getSingleSuccessor())
- return *From;
-
- auto IsEmpty = [](const BasicBlock *BB) {
- return (BB->getInstList().size() == 1);
- };
-
- // Visited is used to avoid running into an infinite loop.
- SmallPtrSet<const BasicBlock *, 4> Visited;
- const BasicBlock *BB = From->getSingleSuccessor();
- const BasicBlock *PredBB = BB;
- while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB)) {
- Visited.insert(BB);
- PredBB = BB;
- BB = BB->getSingleSuccessor();
- }
-
- return (BB == End) ? *End : *PredBB;
-}
-
+const BasicBlock &LoopNest::skipEmptyBlockUntil(const BasicBlock *From,
+ const BasicBlock *End) {
+ assert(From && "Expecting valid From");
+ assert(End && "Expecting valid End");
+
+ if (From == End || !From->getSingleSuccessor())
+ return *From;
+
+ auto IsEmpty = [](const BasicBlock *BB) {
+ return (BB->getInstList().size() == 1);
+ };
+
+ // Visited is used to avoid running into an infinite loop.
+ SmallPtrSet<const BasicBlock *, 4> Visited;
+ const BasicBlock *BB = From->getSingleSuccessor();
+ const BasicBlock *PredBB = BB;
+ while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB)) {
+ Visited.insert(BB);
+ PredBB = BB;
+ BB = BB->getSingleSuccessor();
+ }
+
+ return (BB == End) ? *End : *PredBB;
+}
+
static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
ScalarEvolution &SE) {
// The inner loop must be the only outer loop's child.
@@ -252,92 +252,92 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
InnerLoop.getExitingBlock() != InnerLoopLatch || !InnerLoopExit)
return false;
- // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node.
- auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) {
- return any_of(ExitBlock.phis(), [](const PHINode &PN) {
- return PN.getNumIncomingValues() == 1;
- });
- };
-
- // Returns whether the block `BB` qualifies for being an extra Phi block. The
- // extra Phi block is the additional block inserted after the exit block of an
- // "guarded" inner loop which contains "only" Phi nodes corresponding to the
- // LCSSA Phi nodes in the exit block.
- auto IsExtraPhiBlock = [&](const BasicBlock &BB) {
- return BB.getFirstNonPHI() == BB.getTerminator() &&
- all_of(BB.phis(), [&](const PHINode &PN) {
- return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) {
- return IncomingBlock == InnerLoopExit ||
- IncomingBlock == OuterLoopHeader;
- });
- });
- };
-
- const BasicBlock *ExtraPhiBlock = nullptr;
+ // Returns whether the block `ExitBlock` contains at least one LCSSA Phi node.
+ auto ContainsLCSSAPhi = [](const BasicBlock &ExitBlock) {
+ return any_of(ExitBlock.phis(), [](const PHINode &PN) {
+ return PN.getNumIncomingValues() == 1;
+ });
+ };
+
+ // Returns whether the block `BB` qualifies for being an extra Phi block. The
+ // extra Phi block is the additional block inserted after the exit block of an
+ // "guarded" inner loop which contains "only" Phi nodes corresponding to the
+ // LCSSA Phi nodes in the exit block.
+ auto IsExtraPhiBlock = [&](const BasicBlock &BB) {
+ return BB.getFirstNonPHI() == BB.getTerminator() &&
+ all_of(BB.phis(), [&](const PHINode &PN) {
+ return all_of(PN.blocks(), [&](const BasicBlock *IncomingBlock) {
+ return IncomingBlock == InnerLoopExit ||
+ IncomingBlock == OuterLoopHeader;
+ });
+ });
+ };
+
+ const BasicBlock *ExtraPhiBlock = nullptr;
// Ensure the only branch that may exist between the loops is the inner loop
// guard.
if (OuterLoopHeader != InnerLoopPreHeader) {
- const BasicBlock &SingleSucc =
- LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader);
-
- // no conditional branch present
- if (&SingleSucc != InnerLoopPreHeader) {
- const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator());
-
- if (!BI || BI != InnerLoop.getLoopGuardBranch())
- return false;
-
- bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit);
-
- // The successors of the inner loop guard should be the inner loop
- // preheader or the outer loop latch possibly through empty blocks.
- for (const BasicBlock *Succ : BI->successors()) {
- const BasicBlock *PotentialInnerPreHeader = Succ;
- const BasicBlock *PotentialOuterLatch = Succ;
-
- // Ensure the inner loop guard successor is empty before skipping
- // blocks.
- if (Succ->getInstList().size() == 1) {
- PotentialInnerPreHeader =
- &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader);
- PotentialOuterLatch =
- &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch);
- }
-
- if (PotentialInnerPreHeader == InnerLoopPreHeader)
- continue;
- if (PotentialOuterLatch == OuterLoopLatch)
- continue;
-
- // If `InnerLoopExit` contains LCSSA Phi instructions, additional block
- // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The
- // loops are still considered perfectly nested if the extra block only
- // contains Phi instructions from InnerLoopExit and OuterLoopHeader.
- if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) &&
- Succ->getSingleSuccessor() == OuterLoopLatch) {
- // Points to the extra block so that we can reference it later in the
- // final check. We can also conclude that the inner loop is
- // guarded and there exists LCSSA Phi node in the exit block later if
- // we see a non-null `ExtraPhiBlock`.
- ExtraPhiBlock = Succ;
- continue;
- }
-
- DEBUG_WITH_TYPE(VerboseDebug, {
- dbgs() << "Inner loop guard successor " << Succ->getName()
- << " doesn't lead to inner loop preheader or "
- "outer loop latch.\n";
- });
- return false;
- }
+ const BasicBlock &SingleSucc =
+ LoopNest::skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader);
+
+ // no conditional branch present
+ if (&SingleSucc != InnerLoopPreHeader) {
+ const BranchInst *BI = dyn_cast<BranchInst>(SingleSucc.getTerminator());
+
+ if (!BI || BI != InnerLoop.getLoopGuardBranch())
+ return false;
+
+ bool InnerLoopExitContainsLCSSA = ContainsLCSSAPhi(*InnerLoopExit);
+
+ // The successors of the inner loop guard should be the inner loop
+ // preheader or the outer loop latch possibly through empty blocks.
+ for (const BasicBlock *Succ : BI->successors()) {
+ const BasicBlock *PotentialInnerPreHeader = Succ;
+ const BasicBlock *PotentialOuterLatch = Succ;
+
+ // Ensure the inner loop guard successor is empty before skipping
+ // blocks.
+ if (Succ->getInstList().size() == 1) {
+ PotentialInnerPreHeader =
+ &LoopNest::skipEmptyBlockUntil(Succ, InnerLoopPreHeader);
+ PotentialOuterLatch =
+ &LoopNest::skipEmptyBlockUntil(Succ, OuterLoopLatch);
+ }
+
+ if (PotentialInnerPreHeader == InnerLoopPreHeader)
+ continue;
+ if (PotentialOuterLatch == OuterLoopLatch)
+ continue;
+
+ // If `InnerLoopExit` contains LCSSA Phi instructions, additional block
+ // may be inserted before the `OuterLoopLatch` to which `BI` jumps. The
+ // loops are still considered perfectly nested if the extra block only
+ // contains Phi instructions from InnerLoopExit and OuterLoopHeader.
+ if (InnerLoopExitContainsLCSSA && IsExtraPhiBlock(*Succ) &&
+ Succ->getSingleSuccessor() == OuterLoopLatch) {
+ // Points to the extra block so that we can reference it later in the
+ // final check. We can also conclude that the inner loop is
+ // guarded and there exists LCSSA Phi node in the exit block later if
+ // we see a non-null `ExtraPhiBlock`.
+ ExtraPhiBlock = Succ;
+ continue;
+ }
+
+ DEBUG_WITH_TYPE(VerboseDebug, {
+ dbgs() << "Inner loop guard successor " << Succ->getName()
+ << " doesn't lead to inner loop preheader or "
+ "outer loop latch.\n";
+ });
+ return false;
+ }
}
}
- // Ensure the inner loop exit block lead to the outer loop latch possibly
- // through empty blocks.
- const BasicBlock &SuccInner =
- LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(), OuterLoopLatch);
- if (&SuccInner != OuterLoopLatch && &SuccInner != ExtraPhiBlock) {
+ // Ensure the inner loop exit block lead to the outer loop latch possibly
+ // through empty blocks.
+ const BasicBlock &SuccInner =
+ LoopNest::skipEmptyBlockUntil(InnerLoop.getExitBlock(), OuterLoopLatch);
+ if (&SuccInner != OuterLoopLatch && &SuccInner != ExtraPhiBlock) {
DEBUG_WITH_TYPE(
VerboseDebug,
dbgs() << "Inner loop exit block " << *InnerLoopExit
@@ -348,8 +348,8 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop,
return true;
}
-AnalysisKey LoopNestAnalysis::Key;
-
+AnalysisKey LoopNestAnalysis::Key;
+
raw_ostream &llvm::operator<<(raw_ostream &OS, const LoopNest &LN) {
OS << "IsPerfect=";
if (LN.getMaxPerfectDepth() == LN.getNestDepth())