[llvm-branch-commits] [llvm] 9a17bff - [LoopNest] Allow empty basic blocks without loops
Author: Whitney Tsang Date: 2021-01-04T19:59:50Z New Revision: 9a17bff4f715a9f3ec89f4eacae8fdea1b74fe79 URL: https://github.com/llvm/llvm-project/commit/9a17bff4f715a9f3ec89f4eacae8fdea1b74fe79 DIFF: https://github.com/llvm/llvm-project/commit/9a17bff4f715a9f3ec89f4eacae8fdea1b74fe79.diff LOG: [LoopNest] Allow empty basic blocks without loops Allow loop nests with empty basic blocks without loops in different levels as perfect. Reviewers: Meinersbur Differential Revision: https://reviews.llvm.org/D93665 Added: Modified: llvm/include/llvm/Analysis/LoopNestAnalysis.h llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/lib/Analysis/LoopNestAnalysis.cpp llvm/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/test/Analysis/LoopNestAnalysis/perfectnest.ll Removed: diff --git a/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/llvm/include/llvm/Analysis/LoopNestAnalysis.h index 4d77d735819f..692909db8341 100644 --- a/llvm/include/llvm/Analysis/LoopNestAnalysis.h +++ b/llvm/include/llvm/Analysis/LoopNestAnalysis.h @@ -128,6 +128,12 @@ class LoopNest { [](const Loop *L) { return L->isLoopSimplifyForm(); }); } + /// Return true if all loops in the loop nest are in rotated form. + bool areAllLoopsRotatedForm() const { +return std::all_of(Loops.begin(), Loops.end(), + [](const Loop *L) { return L->isRotatedForm(); }); + } + StringRef getName() const { return Loops.front()->getName(); } protected: diff --git a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h index 64c569de1f58..fd5a7daf3add 100644 --- a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -244,6 +244,12 @@ unsigned SplitAllCriticalEdges(Function &F, const CriticalEdgeSplittingOptions &Options = CriticalEdgeSplittingOptions()); +/// Recursivelly traverse all empty 'single successor' basic blocks of \p From +/// (if there are any). Return the last basic block found or \p End if it was +/// reached during the search. +const BasicBlock &skipEmptyBlockUntil(const BasicBlock *From, + const BasicBlock *End); + /// Split the edge connecting the specified blocks, and return the newly created /// basic block between \p From and \p To. BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, diff --git a/llvm/lib/Analysis/LoopNestAnalysis.cpp b/llvm/lib/Analysis/LoopNestAnalysis.cpp index ef10b7e97461..abc219a8bd32 100644 --- a/llvm/lib/Analysis/LoopNestAnalysis.cpp +++ b/llvm/lib/Analysis/LoopNestAnalysis.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; @@ -253,49 +254,66 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop, // Ensure the only branch that may exist between the loops is the inner loop // guard. if (OuterLoopHeader != InnerLoopPreHeader) { -const BranchInst *BI = -dyn_cast(OuterLoopHeader->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 and the outer loop latch. -for (const BasicBlock *Succ : BI->successors()) { - if (Succ == InnerLoopPreHeader) -continue; - if (Succ == 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; - } +const BasicBlock &SingleSucc = +skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader); - 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; +// no conditional branch present +if (&SingleSucc != InnerLoopPreH
[llvm-branch-commits] [llvm] de6d43f - Revert "[LoopNest] Allow empty basic blocks without loops"
Author: Whitney Tsang Date: 2021-01-04T20:42:21Z New Revision: de6d43f16cbaf2eae6fa161ea6e811b8f5f45174 URL: https://github.com/llvm/llvm-project/commit/de6d43f16cbaf2eae6fa161ea6e811b8f5f45174 DIFF: https://github.com/llvm/llvm-project/commit/de6d43f16cbaf2eae6fa161ea6e811b8f5f45174.diff LOG: Revert "[LoopNest] Allow empty basic blocks without loops" This reverts commit 9a17bff4f715a9f3ec89f4eacae8fdea1b74fe79. Added: Modified: llvm/include/llvm/Analysis/LoopNestAnalysis.h llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/lib/Analysis/LoopNestAnalysis.cpp llvm/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/test/Analysis/LoopNestAnalysis/perfectnest.ll Removed: diff --git a/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/llvm/include/llvm/Analysis/LoopNestAnalysis.h index 692909db8341..4d77d735819f 100644 --- a/llvm/include/llvm/Analysis/LoopNestAnalysis.h +++ b/llvm/include/llvm/Analysis/LoopNestAnalysis.h @@ -128,12 +128,6 @@ class LoopNest { [](const Loop *L) { return L->isLoopSimplifyForm(); }); } - /// Return true if all loops in the loop nest are in rotated form. - bool areAllLoopsRotatedForm() const { -return std::all_of(Loops.begin(), Loops.end(), - [](const Loop *L) { return L->isRotatedForm(); }); - } - StringRef getName() const { return Loops.front()->getName(); } protected: diff --git a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h index fd5a7daf3add..64c569de1f58 100644 --- a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -244,12 +244,6 @@ unsigned SplitAllCriticalEdges(Function &F, const CriticalEdgeSplittingOptions &Options = CriticalEdgeSplittingOptions()); -/// Recursivelly traverse all empty 'single successor' basic blocks of \p From -/// (if there are any). Return the last basic block found or \p End if it was -/// reached during the search. -const BasicBlock &skipEmptyBlockUntil(const BasicBlock *From, - const BasicBlock *End); - /// Split the edge connecting the specified blocks, and return the newly created /// basic block between \p From and \p To. BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, diff --git a/llvm/lib/Analysis/LoopNestAnalysis.cpp b/llvm/lib/Analysis/LoopNestAnalysis.cpp index abc219a8bd32..ef10b7e97461 100644 --- a/llvm/lib/Analysis/LoopNestAnalysis.cpp +++ b/llvm/lib/Analysis/LoopNestAnalysis.cpp @@ -16,7 +16,6 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ValueTracking.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; @@ -254,66 +253,49 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop, // Ensure the only branch that may exist between the loops is the inner loop // guard. if (OuterLoopHeader != InnerLoopPreHeader) { -const BasicBlock &SingleSucc = -skipEmptyBlockUntil(OuterLoopHeader, InnerLoopPreHeader); - -// no conditional branch present -if (&SingleSucc != InnerLoopPreHeader) { - const BranchInst *BI = dyn_cast(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 = - &skipEmptyBlockUntil(Succ, InnerLoopPreHeader); - PotentialOuterLatch = &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
[llvm-branch-commits] [llvm] c005518 - [LoopNest] Allow empty basic blocks without loops
Author: Whitney Tsang Date: 2021-01-05T15:09:38Z New Revision: c00551893674d6d61e9e5d68412e2b8621f617b8 URL: https://github.com/llvm/llvm-project/commit/c00551893674d6d61e9e5d68412e2b8621f617b8 DIFF: https://github.com/llvm/llvm-project/commit/c00551893674d6d61e9e5d68412e2b8621f617b8.diff LOG: [LoopNest] Allow empty basic blocks without loops Allow loop nests with empty basic blocks without loops in different levels as perfect. Reviewers: Meinersbur Differential Revision: https://reviews.llvm.org/D93665 Added: Modified: llvm/include/llvm/Analysis/LoopNestAnalysis.h llvm/lib/Analysis/LoopNestAnalysis.cpp llvm/test/Analysis/LoopNestAnalysis/perfectnest.ll Removed: diff --git a/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/llvm/include/llvm/Analysis/LoopNestAnalysis.h index 4d77d735819f..f65ff493574c 100644 --- a/llvm/include/llvm/Analysis/LoopNestAnalysis.h +++ b/llvm/include/llvm/Analysis/LoopNestAnalysis.h @@ -59,6 +59,12 @@ class LoopNest { /// getMaxPerfectDepth(Loop_i) would return 2. static unsigned getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE); + /// Recursivelly traverse all empty 'single successor' basic blocks of \p From + /// (if there are any). Return the last basic block found or \p End if it was + /// reached during the search. + static const BasicBlock &skipEmptyBlockUntil(const BasicBlock *From, + const BasicBlock *End); + /// Return the outermost loop in the loop nest. Loop &getOutermostLoop() const { return *Loops.front(); } @@ -128,6 +134,12 @@ class LoopNest { [](const Loop *L) { return L->isLoopSimplifyForm(); }); } + /// Return true if all loops in the loop nest are in rotated form. + bool areAllLoopsRotatedForm() const { +return std::all_of(Loops.begin(), Loops.end(), + [](const Loop *L) { return L->isRotatedForm(); }); + } + StringRef getName() const { return Loops.front()->getName(); } protected: diff --git a/llvm/lib/Analysis/LoopNestAnalysis.cpp b/llvm/lib/Analysis/LoopNestAnalysis.cpp index ef10b7e97461..70b9ccaa87c1 100644 --- a/llvm/lib/Analysis/LoopNestAnalysis.cpp +++ b/llvm/lib/Analysis/LoopNestAnalysis.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; @@ -206,6 +207,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 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. @@ -253,49 +279,67 @@ static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop, // Ensure the only branch that may exist between the loops is the inner loop // guard. if (OuterLoopHeader != InnerLoopPreHeader) { -const BranchInst *BI = -dyn_cast(OuterLoopHeader->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 and the outer loop latch. -for (const BasicBlock *Succ : BI->successors()) { - if (Succ == InnerLoopPreHeader) -continue; - if (Succ == 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 loo
[llvm-branch-commits] [llvm] 601636d - [LoopNest] Allow empty basic blocks without loops
Author: Whitney Tsang Date: 2021-01-05T18:44:43Z New Revision: 601636de98061b53242b598fc2354905c8efbfb8 URL: https://github.com/llvm/llvm-project/commit/601636de98061b53242b598fc2354905c8efbfb8 DIFF: https://github.com/llvm/llvm-project/commit/601636de98061b53242b598fc2354905c8efbfb8.diff LOG: [LoopNest] Allow empty basic blocks without loops Addressed Florian's post commit review comments: 1. included STLExtras.h 2. changed std::all_of to llvm::all_of Differential Revision: https://reviews.llvm.org/D93665 Added: Modified: llvm/include/llvm/Analysis/LoopNestAnalysis.h Removed: diff --git a/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/llvm/include/llvm/Analysis/LoopNestAnalysis.h index f65ff493574c4..9c4fb4dbc29b4 100644 --- a/llvm/include/llvm/Analysis/LoopNestAnalysis.h +++ b/llvm/include/llvm/Analysis/LoopNestAnalysis.h @@ -14,6 +14,7 @@ #ifndef LLVM_ANALYSIS_LOOPNESTANALYSIS_H #define LLVM_ANALYSIS_LOOPNESTANALYSIS_H +#include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/LoopAnalysisManager.h" #include "llvm/Analysis/LoopInfo.h" @@ -130,14 +131,12 @@ class LoopNest { /// Return true if all loops in the loop nest are in simplify form. bool areAllLoopsSimplifyForm() const { -return llvm::all_of(Loops, -[](const Loop *L) { return L->isLoopSimplifyForm(); }); +return all_of(Loops, [](const Loop *L) { return L->isLoopSimplifyForm(); }); } /// Return true if all loops in the loop nest are in rotated form. bool areAllLoopsRotatedForm() const { -return std::all_of(Loops.begin(), Loops.end(), - [](const Loop *L) { return L->isRotatedForm(); }); +return all_of(Loops, [](const Loop *L) { return L->isRotatedForm(); }); } StringRef getName() const { return Loops.front()->getName(); } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 314ccc0 - [LoopNest] Remove unused include.
Author: Whitney Tsang Date: 2021-01-05T20:05:31Z New Revision: 314ccc00139a7f382db7b598dcd94883b366b7de URL: https://github.com/llvm/llvm-project/commit/314ccc00139a7f382db7b598dcd94883b366b7de DIFF: https://github.com/llvm/llvm-project/commit/314ccc00139a7f382db7b598dcd94883b366b7de.diff LOG: [LoopNest] Remove unused include. Differential Revision: https://reviews.llvm.org/D93665 Added: Modified: llvm/lib/Analysis/LoopNestAnalysis.cpp Removed: diff --git a/llvm/lib/Analysis/LoopNestAnalysis.cpp b/llvm/lib/Analysis/LoopNestAnalysis.cpp index 70b9ccaa87c1..f3aa0d76742f 100644 --- a/llvm/lib/Analysis/LoopNestAnalysis.cpp +++ b/llvm/lib/Analysis/LoopNestAnalysis.cpp @@ -16,7 +16,6 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ValueTracking.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] cf638d7 - Ensure SplitEdge to return the new block between the two given blocks
Author: Bangtian Liu Date: 2020-12-15T23:32:29Z New Revision: cf638d793c489632bbcf0ee0fbf9d0f8c76e1f48 URL: https://github.com/llvm/llvm-project/commit/cf638d793c489632bbcf0ee0fbf9d0f8c76e1f48 DIFF: https://github.com/llvm/llvm-project/commit/cf638d793c489632bbcf0ee0fbf9d0f8c76e1f48.diff LOG: Ensure SplitEdge to return the new block between the two given blocks This PR implements the function splitBasicBlockBefore to address an issue that occurred during SplitEdge(BB, Succ, ...), inside splitBlockBefore. The issue occurs in SplitEdge when the Succ has a single predecessor and the edge between the BB and Succ is not critical. This produces the result ‘BB->Succ->New’. The new function splitBasicBlockBefore was added to splitBlockBefore to handle the issue and now produces the correct result ‘BB->New->Succ’. Below is an example of splitting the block bb1 at its first instruction. /// Original IR bb0: br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlock bb0: br bb1 bb1: br bb1.split bb1.split: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlockBefore bb0: br bb1.split bb1.split br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: Differential Revision: https://reviews.llvm.org/D92200 Added: Modified: llvm/include/llvm/IR/BasicBlock.h llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/lib/IR/BasicBlock.cpp llvm/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/test/CodeGen/AMDGPU/call-constexpr.ll llvm/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp Removed: diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 26cfdd9e51d6..34b40365bc5a 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -396,22 +396,49 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// Split the basic block into two basic blocks at the specified instruction. /// - /// Note that all instructions BEFORE the specified iterator stay as part of - /// the original basic block, an unconditional branch is added to the original - /// BB, and the rest of the instructions in the BB are moved to the new BB, - /// including the old terminator. The newly formed BasicBlock is returned. - /// This function invalidates the specified iterator. + /// If \p Before is true, splitBasicBlockBefore handles the + /// block splitting. Otherwise, execution proceeds as described below. + /// + /// Note that all instructions BEFORE the specified iterator + /// stay as part of the original basic block, an unconditional branch is added + /// to the original BB, and the rest of the instructions in the BB are moved + /// to the new BB, including the old terminator. The newly formed basic block + /// is returned. This function invalidates the specified iterator. /// /// Note that this only works on well formed basic blocks (must have a - /// terminator), and 'I' must not be the end of instruction list (which would - /// cause a degenerate basic block to be formed, having a terminator inside of - /// the basic block). + /// terminator), and \p 'I' must not be the end of instruction list (which + /// would cause a degenerate basic block to be formed, having a terminator + /// inside of the basic block). /// /// Also note that this doesn't preserve any passes. To split blocks while /// keeping loop information consistent, use the SplitBlock utility function. - BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); - BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "") { -return splitBasicBlock(I->getIterator(), BBName); + BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "", + bool Before = false); + BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "", + bool Before = false) { +return splitBasicBlock(I->getIterator(), BBName, Before); + } + + /// Split the basic block into two basic blocks at the specified instruction + /// and insert the new basic blocks as the predecessor of the current block. + /// + /// This function ensures all instructions AFTER and including the specified + /// iterator \p I are part of the original basic block. All Instructions + /// BEFORE the iterator \p I are moved to the new BB and an unconditional + /// branch is added to the new BB. The new basic block is returned. + /// + /// Note that this only works on well formed basic blocks (must have a + /// terminator), and \p 'I' must not be the end of instruction list (which + /// would cause a degenerate basic block to be formed, having a terminator + /// inside
[llvm-branch-commits] [llvm] c107572 - Revert "Ensure SplitEdge to return the new block between the two given blocks"
Author: Bangtian Liu Date: 2020-12-16T11:52:30Z New Revision: c10757200d89e59a52ab8cbbc68178eeafaa3600 URL: https://github.com/llvm/llvm-project/commit/c10757200d89e59a52ab8cbbc68178eeafaa3600 DIFF: https://github.com/llvm/llvm-project/commit/c10757200d89e59a52ab8cbbc68178eeafaa3600.diff LOG: Revert "Ensure SplitEdge to return the new block between the two given blocks" This reverts commit cf638d793c489632bbcf0ee0fbf9d0f8c76e1f48. Added: Modified: llvm/include/llvm/IR/BasicBlock.h llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/lib/IR/BasicBlock.cpp llvm/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/test/CodeGen/AMDGPU/call-constexpr.ll llvm/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp Removed: diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 34b40365bc5a..26cfdd9e51d6 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -396,49 +396,22 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// Split the basic block into two basic blocks at the specified instruction. /// - /// If \p Before is true, splitBasicBlockBefore handles the - /// block splitting. Otherwise, execution proceeds as described below. - /// - /// Note that all instructions BEFORE the specified iterator - /// stay as part of the original basic block, an unconditional branch is added - /// to the original BB, and the rest of the instructions in the BB are moved - /// to the new BB, including the old terminator. The newly formed basic block - /// is returned. This function invalidates the specified iterator. + /// Note that all instructions BEFORE the specified iterator stay as part of + /// the original basic block, an unconditional branch is added to the original + /// BB, and the rest of the instructions in the BB are moved to the new BB, + /// including the old terminator. The newly formed BasicBlock is returned. + /// This function invalidates the specified iterator. /// /// Note that this only works on well formed basic blocks (must have a - /// terminator), and \p 'I' must not be the end of instruction list (which - /// would cause a degenerate basic block to be formed, having a terminator - /// inside of the basic block). + /// terminator), and 'I' must not be the end of instruction list (which would + /// cause a degenerate basic block to be formed, having a terminator inside of + /// the basic block). /// /// Also note that this doesn't preserve any passes. To split blocks while /// keeping loop information consistent, use the SplitBlock utility function. - BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "", - bool Before = false); - BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "", - bool Before = false) { -return splitBasicBlock(I->getIterator(), BBName, Before); - } - - /// Split the basic block into two basic blocks at the specified instruction - /// and insert the new basic blocks as the predecessor of the current block. - /// - /// This function ensures all instructions AFTER and including the specified - /// iterator \p I are part of the original basic block. All Instructions - /// BEFORE the iterator \p I are moved to the new BB and an unconditional - /// branch is added to the new BB. The new basic block is returned. - /// - /// Note that this only works on well formed basic blocks (must have a - /// terminator), and \p 'I' must not be the end of instruction list (which - /// would cause a degenerate basic block to be formed, having a terminator - /// inside of the basic block). \p 'I' cannot be a iterator for a PHINode - /// with multiple incoming blocks. - /// - /// Also note that this doesn't preserve any passes. To split blocks while - /// keeping loop information consistent, use the SplitBlockBefore utility - /// function. - BasicBlock *splitBasicBlockBefore(iterator I, const Twine &BBName = ""); - BasicBlock *splitBasicBlockBefore(Instruction *I, const Twine &BBName = "") { -return splitBasicBlockBefore(I->getIterator(), BBName); + BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); + BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "") { +return splitBasicBlock(I->getIterator(), BBName); } /// Returns true if there are any uses of this basic block other than diff --git a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h index 7b8e2be17fa2..0a63654feb98 100644 --- a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -244,33 +244,19 @@ unsigned SplitAllCriticalEdges(Funct
[llvm-branch-commits] [llvm] fa3693a - [LoopNest] Handle loop-nest passes in LoopPassManager
Author: Whitney Tsang Date: 2020-12-16T17:07:14Z New Revision: fa3693ad0b34ef1d64f49e3d3dd10865b9fb7a8b URL: https://github.com/llvm/llvm-project/commit/fa3693ad0b34ef1d64f49e3d3dd10865b9fb7a8b DIFF: https://github.com/llvm/llvm-project/commit/fa3693ad0b34ef1d64f49e3d3dd10865b9fb7a8b.diff LOG: [LoopNest] Handle loop-nest passes in LoopPassManager Per http://llvm.org/OpenProjects.html#llvm_loopnest, the goal of this patch (and other following patches) is to create facilities that allow implementing loop nest passes that run on top-level loop nests for the New Pass Manager. This patch extends the functionality of LoopPassManager to handle loop-nest passes by specializing the definition of LoopPassManager that accepts both kinds of passes in addPass. Only loop passes are executed if L is not a top-level one, and both kinds of passes are executed if L is top-level. Currently, loop nest passes should have the following run method: PreservedAnalyses run(LoopNest &, LoopAnalysisManager &, LoopStandardAnalysisResults &, LPMUpdater &); Reviewed By: Whitney, ychen Differential Revision: https://reviews.llvm.org/D87045 Added: Modified: llvm/include/llvm/Analysis/LoopNestAnalysis.h llvm/include/llvm/Transforms/Scalar/LoopPassManager.h llvm/lib/Analysis/LoopNestAnalysis.cpp llvm/lib/Transforms/Scalar/LoopPassManager.cpp llvm/unittests/IR/PassBuilderCallbacksTest.cpp llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp Removed: diff --git a/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/llvm/include/llvm/Analysis/LoopNestAnalysis.h index 792958a312ce..4d77d735819f 100644 --- a/llvm/include/llvm/Analysis/LoopNestAnalysis.h +++ b/llvm/include/llvm/Analysis/LoopNestAnalysis.h @@ -128,6 +128,8 @@ class LoopNest { [](const Loop *L) { return L->isLoopSimplifyForm(); }); } + StringRef getName() const { return Loops.front()->getName(); } + protected: const unsigned MaxPerfectDepth; // maximum perfect nesting depth level. LoopVectorTy Loops; // the loops in the nest (in breadth first order). diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h index 4ac12061e79e..a1f43aa6d404 100644 --- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h +++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -45,6 +45,7 @@ #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopAnalysisManager.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopNestAnalysis.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" @@ -67,13 +68,136 @@ class LPMUpdater; // See the comments on the definition of the specialization for details on how // it diff ers from the primary template. template <> -PreservedAnalyses -PassManager::run(Loop &InitialL, LoopAnalysisManager &AM, - LoopStandardAnalysisResults &AnalysisResults, - LPMUpdater &U); -extern template class PassManager; +class PassManager +: public PassInfoMixin< + PassManager> { +private: + template + using HasRunOnLoopT = decltype(std::declval().run( + std::declval(), std::declval(), + std::declval(), + std::declval())); + +public: + /// Construct a pass manager. + /// + /// If \p DebugLogging is true, we'll log our progress to llvm::dbgs(). + explicit PassManager(bool DebugLogging = false) + : DebugLogging(DebugLogging) {} + + // FIXME: These are equivalent to the default move constructor/move + // assignment. However, using = default triggers linker errors due to the + // explicit instantiations below. Find a way to use the default and remove the + // duplicated code here. + PassManager(PassManager &&Arg) + : IsLoopNestPass(std::move(Arg.IsLoopNestPass)), +LoopPasses(std::move(Arg.LoopPasses)), +LoopNestPasses(std::move(Arg.LoopNestPasses)), +DebugLogging(std::move(Arg.DebugLogging)) {} + + PassManager &operator=(PassManager &&RHS) { +IsLoopNestPass = std::move(RHS.IsLoopNestPass); +LoopPasses = std::move(RHS.LoopPasses); +LoopNestPasses = std::move(RHS.LoopNestPasses); +DebugLogging = std::move(RHS.DebugLogging); +return *this; + } + + PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, +LoopStandardAnalysisResults &AR, LPMUpdater &U); + + /// Add either a loop pass or a loop-nest pass to the pass manager. Append \p + /// Pass to the list of loop passes if it has a dedicated \fn run() method for + /// loops and to the list of loop-nest passes if the \fn run() method is for + /// loop-nests instead. Also append whether \p Pass is loop-nest pass or not + /// to the end of \var IsLoopNestPass so we can easily identify the types of + /// pa
[llvm-branch-commits] [llvm] d20e0c3 - Ensure SplitEdge to return the new block between the two given blocks
Author: Bangtian Liu Date: 2020-12-17T16:00:15Z New Revision: d20e0c3444ad9ada550d9d6d1d56fd72948ae444 URL: https://github.com/llvm/llvm-project/commit/d20e0c3444ad9ada550d9d6d1d56fd72948ae444 DIFF: https://github.com/llvm/llvm-project/commit/d20e0c3444ad9ada550d9d6d1d56fd72948ae444.diff LOG: Ensure SplitEdge to return the new block between the two given blocks This PR implements the function splitBasicBlockBefore to address an issue that occurred during SplitEdge(BB, Succ, ...), inside splitBlockBefore. The issue occurs in SplitEdge when the Succ has a single predecessor and the edge between the BB and Succ is not critical. This produces the result ‘BB->Succ->New’. The new function splitBasicBlockBefore was added to splitBlockBefore to handle the issue and now produces the correct result ‘BB->New->Succ’. Below is an example of splitting the block bb1 at its first instruction. /// Original IR bb0: br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlock bb0: br bb1 bb1: br bb1.split bb1.split: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlockBefore bb0: br bb1.split bb1.split br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: Differential Revision: https://reviews.llvm.org/D92200 Added: Modified: llvm/include/llvm/IR/BasicBlock.h llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/lib/IR/BasicBlock.cpp llvm/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/test/CodeGen/AMDGPU/call-constexpr.ll llvm/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp Removed: diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 0cce2a599d9c..b86bb16e1239 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -398,22 +398,49 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// Split the basic block into two basic blocks at the specified instruction. /// - /// Note that all instructions BEFORE the specified iterator stay as part of - /// the original basic block, an unconditional branch is added to the original - /// BB, and the rest of the instructions in the BB are moved to the new BB, - /// including the old terminator. The newly formed BasicBlock is returned. - /// This function invalidates the specified iterator. + /// If \p Before is true, splitBasicBlockBefore handles the + /// block splitting. Otherwise, execution proceeds as described below. + /// + /// Note that all instructions BEFORE the specified iterator + /// stay as part of the original basic block, an unconditional branch is added + /// to the original BB, and the rest of the instructions in the BB are moved + /// to the new BB, including the old terminator. The newly formed basic block + /// is returned. This function invalidates the specified iterator. /// /// Note that this only works on well formed basic blocks (must have a - /// terminator), and 'I' must not be the end of instruction list (which would - /// cause a degenerate basic block to be formed, having a terminator inside of - /// the basic block). + /// terminator), and \p 'I' must not be the end of instruction list (which + /// would cause a degenerate basic block to be formed, having a terminator + /// inside of the basic block). /// /// Also note that this doesn't preserve any passes. To split blocks while /// keeping loop information consistent, use the SplitBlock utility function. - BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); - BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "") { -return splitBasicBlock(I->getIterator(), BBName); + BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "", + bool Before = false); + BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "", + bool Before = false) { +return splitBasicBlock(I->getIterator(), BBName, Before); + } + + /// Split the basic block into two basic blocks at the specified instruction + /// and insert the new basic blocks as the predecessor of the current block. + /// + /// This function ensures all instructions AFTER and including the specified + /// iterator \p I are part of the original basic block. All Instructions + /// BEFORE the iterator \p I are moved to the new BB and an unconditional + /// branch is added to the new BB. The new basic block is returned. + /// + /// Note that this only works on well formed basic blocks (must have a + /// terminator), and \p 'I' must not be the end of instruction list (which + /// would cause a degenerate basic block to be formed, having a terminator + /// inside
[llvm-branch-commits] [llvm] 511cfe9 - Revert "Ensure SplitEdge to return the new block between the two given blocks"
Author: Bangtian Liu Date: 2020-12-17T21:00:37Z New Revision: 511cfe9441955f20a8b93573fb9b62433b053550 URL: https://github.com/llvm/llvm-project/commit/511cfe9441955f20a8b93573fb9b62433b053550 DIFF: https://github.com/llvm/llvm-project/commit/511cfe9441955f20a8b93573fb9b62433b053550.diff LOG: Revert "Ensure SplitEdge to return the new block between the two given blocks" This reverts commit d20e0c3444ad9ada550d9d6d1d56fd72948ae444. Added: Modified: llvm/include/llvm/IR/BasicBlock.h llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/lib/IR/BasicBlock.cpp llvm/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/test/CodeGen/AMDGPU/call-constexpr.ll llvm/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp Removed: diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index b86bb16e1239..0cce2a599d9c 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -398,49 +398,22 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// Split the basic block into two basic blocks at the specified instruction. /// - /// If \p Before is true, splitBasicBlockBefore handles the - /// block splitting. Otherwise, execution proceeds as described below. - /// - /// Note that all instructions BEFORE the specified iterator - /// stay as part of the original basic block, an unconditional branch is added - /// to the original BB, and the rest of the instructions in the BB are moved - /// to the new BB, including the old terminator. The newly formed basic block - /// is returned. This function invalidates the specified iterator. + /// Note that all instructions BEFORE the specified iterator stay as part of + /// the original basic block, an unconditional branch is added to the original + /// BB, and the rest of the instructions in the BB are moved to the new BB, + /// including the old terminator. The newly formed BasicBlock is returned. + /// This function invalidates the specified iterator. /// /// Note that this only works on well formed basic blocks (must have a - /// terminator), and \p 'I' must not be the end of instruction list (which - /// would cause a degenerate basic block to be formed, having a terminator - /// inside of the basic block). + /// terminator), and 'I' must not be the end of instruction list (which would + /// cause a degenerate basic block to be formed, having a terminator inside of + /// the basic block). /// /// Also note that this doesn't preserve any passes. To split blocks while /// keeping loop information consistent, use the SplitBlock utility function. - BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "", - bool Before = false); - BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "", - bool Before = false) { -return splitBasicBlock(I->getIterator(), BBName, Before); - } - - /// Split the basic block into two basic blocks at the specified instruction - /// and insert the new basic blocks as the predecessor of the current block. - /// - /// This function ensures all instructions AFTER and including the specified - /// iterator \p I are part of the original basic block. All Instructions - /// BEFORE the iterator \p I are moved to the new BB and an unconditional - /// branch is added to the new BB. The new basic block is returned. - /// - /// Note that this only works on well formed basic blocks (must have a - /// terminator), and \p 'I' must not be the end of instruction list (which - /// would cause a degenerate basic block to be formed, having a terminator - /// inside of the basic block). \p 'I' cannot be a iterator for a PHINode - /// with multiple incoming blocks. - /// - /// Also note that this doesn't preserve any passes. To split blocks while - /// keeping loop information consistent, use the SplitBlockBefore utility - /// function. - BasicBlock *splitBasicBlockBefore(iterator I, const Twine &BBName = ""); - BasicBlock *splitBasicBlockBefore(Instruction *I, const Twine &BBName = "") { -return splitBasicBlockBefore(I->getIterator(), BBName); + BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); + BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "") { +return splitBasicBlock(I->getIterator(), BBName); } /// Returns true if there are any uses of this basic block other than diff --git a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h index 7b8e2be17fa2..0a63654feb98 100644 --- a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -244,33 +244,19 @@ unsigned SplitAllCriticalEdges(Funct
[llvm-branch-commits] [llvm] 2a814cd - Ensure SplitEdge to return the new block between the two given blocks
Author: Whitney Tsang Date: 2020-12-18T17:37:17Z New Revision: 2a814cd9e1e8493c6606712d55f9ffdb58396481 URL: https://github.com/llvm/llvm-project/commit/2a814cd9e1e8493c6606712d55f9ffdb58396481 DIFF: https://github.com/llvm/llvm-project/commit/2a814cd9e1e8493c6606712d55f9ffdb58396481.diff LOG: Ensure SplitEdge to return the new block between the two given blocks This PR implements the function splitBasicBlockBefore to address an issue that occurred during SplitEdge(BB, Succ, ...), inside splitBlockBefore. The issue occurs in SplitEdge when the Succ has a single predecessor and the edge between the BB and Succ is not critical. This produces the result ‘BB->Succ->New’. The new function splitBasicBlockBefore was added to splitBlockBefore to handle the issue and now produces the correct result ‘BB->New->Succ’. Below is an example of splitting the block bb1 at its first instruction. /// Original IR bb0: br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlock bb0: br bb1 bb1: br bb1.split bb1.split: %0 = mul i32 1, 2 br bb2 bb2: /// IR after splitEdge(bb0, bb1) using splitBasicBlockBefore bb0: br bb1.split bb1.split br bb1 bb1: %0 = mul i32 1, 2 br bb2 bb2: Differential Revision: https://reviews.llvm.org/D92200 Added: Modified: llvm/include/llvm/IR/BasicBlock.h llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/lib/IR/BasicBlock.cpp llvm/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/test/CodeGen/AMDGPU/call-constexpr.ll llvm/test/Transforms/LoopUnswitch/2011-11-18-SimpleSwitch.ll llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp Removed: diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 0cce2a599d9c..b86bb16e1239 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -398,22 +398,49 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// Split the basic block into two basic blocks at the specified instruction. /// - /// Note that all instructions BEFORE the specified iterator stay as part of - /// the original basic block, an unconditional branch is added to the original - /// BB, and the rest of the instructions in the BB are moved to the new BB, - /// including the old terminator. The newly formed BasicBlock is returned. - /// This function invalidates the specified iterator. + /// If \p Before is true, splitBasicBlockBefore handles the + /// block splitting. Otherwise, execution proceeds as described below. + /// + /// Note that all instructions BEFORE the specified iterator + /// stay as part of the original basic block, an unconditional branch is added + /// to the original BB, and the rest of the instructions in the BB are moved + /// to the new BB, including the old terminator. The newly formed basic block + /// is returned. This function invalidates the specified iterator. /// /// Note that this only works on well formed basic blocks (must have a - /// terminator), and 'I' must not be the end of instruction list (which would - /// cause a degenerate basic block to be formed, having a terminator inside of - /// the basic block). + /// terminator), and \p 'I' must not be the end of instruction list (which + /// would cause a degenerate basic block to be formed, having a terminator + /// inside of the basic block). /// /// Also note that this doesn't preserve any passes. To split blocks while /// keeping loop information consistent, use the SplitBlock utility function. - BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); - BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "") { -return splitBasicBlock(I->getIterator(), BBName); + BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "", + bool Before = false); + BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = "", + bool Before = false) { +return splitBasicBlock(I->getIterator(), BBName, Before); + } + + /// Split the basic block into two basic blocks at the specified instruction + /// and insert the new basic blocks as the predecessor of the current block. + /// + /// This function ensures all instructions AFTER and including the specified + /// iterator \p I are part of the original basic block. All Instructions + /// BEFORE the iterator \p I are moved to the new BB and an unconditional + /// branch is added to the new BB. The new basic block is returned. + /// + /// Note that this only works on well formed basic blocks (must have a + /// terminator), and \p 'I' must not be the end of instruction list (which + /// would cause a degenerate basic block to be formed, having a terminator + /// insid