[llvm-branch-commits] [llvm] 9a17bff - [LoopNest] Allow empty basic blocks without loops

2021-01-04 Thread Whitney Tsang via llvm-branch-commits

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"

2021-01-04 Thread Whitney Tsang via llvm-branch-commits

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

2021-01-05 Thread Whitney Tsang via llvm-branch-commits

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

2021-01-05 Thread Whitney Tsang via llvm-branch-commits

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.

2021-01-05 Thread Whitney Tsang via llvm-branch-commits

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

2020-12-15 Thread Whitney Tsang via llvm-branch-commits

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"

2020-12-16 Thread Whitney Tsang via llvm-branch-commits

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

2020-12-16 Thread Whitney Tsang via llvm-branch-commits

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

2020-12-17 Thread Whitney Tsang via llvm-branch-commits

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"

2020-12-17 Thread Whitney Tsang via llvm-branch-commits

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

2020-12-18 Thread Whitney Tsang via llvm-branch-commits

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