[PATCH] D80583: Create utility function to Merge Adjacent Basic Blocks

Sidharth Baveja via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 26 13:05:49 PDT 2020


sidbav created this revision.
sidbav added reviewers: Whitney, Meinersbur, asbirlea, dmgreen.
Herald added subscribers: llvm-commits, zzheng, hiraditya.
Herald added a project: LLVM.
sidbav added a reviewer: etiotto.

The following code from `/llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp` can be used by other transformations:

  while (!MergeBlocks.empty()) {	
      BasicBlock *BB = *MergeBlocks.begin();
      BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator());	
      if (Term && Term->isUnconditional() && L->contains(Term->getSuccessor(0))) {	
        BasicBlock *Dest = Term->getSuccessor(0);	
        BasicBlock *Fold = Dest->getUniquePredecessor();	
        if (MergeBlockIntoPredecessor(Dest, &DTU, LI)) {	
          // Don't remove BB and add Fold as they are the same BB	
          assert(Fold == BB);	
          (void)Fold;	
          MergeBlocks.erase(Dest);	
        } else	
          MergeBlocks.erase(BB);	
      } else	
        MergeBlocks.erase(BB);	
    }

Hence it should be separated into its own utility function.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D80583

Files:
  llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
  llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
  llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp


Index: llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
===================================================================
--- llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
+++ llvm/lib/Transforms/Utils/LoopUnrollAndJam.cpp
@@ -593,22 +593,9 @@
   MergeBlocks.insert(ForeBlocksLast.begin(), ForeBlocksLast.end());
   MergeBlocks.insert(SubLoopBlocksLast.begin(), SubLoopBlocksLast.end());
   MergeBlocks.insert(AftBlocksLast.begin(), AftBlocksLast.end());
-  while (!MergeBlocks.empty()) {
-    BasicBlock *BB = *MergeBlocks.begin();
-    BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator());
-    if (Term && Term->isUnconditional() && L->contains(Term->getSuccessor(0))) {
-      BasicBlock *Dest = Term->getSuccessor(0);
-      BasicBlock *Fold = Dest->getUniquePredecessor();
-      if (MergeBlockIntoPredecessor(Dest, &DTU, LI)) {
-        // Don't remove BB and add Fold as they are the same BB
-        assert(Fold == BB);
-        (void)Fold;
-        MergeBlocks.erase(Dest);
-      } else
-        MergeBlocks.erase(BB);
-    } else
-      MergeBlocks.erase(BB);
-  }
+
+  MergeAdjacentBlocks(MergeBlocks, true, L, &DTU, LI);
+
   // Apply updates to the DomTree.
   DT = &DTU.getDomTree();
 
Index: llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
===================================================================
--- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -315,6 +315,31 @@
   return true;
 }
 
+bool llvm::MergeAdjacentBlocks(SmallPtrSetImpl<BasicBlock *> &MergeBlocks,
+                               bool UniquePredecessor, Loop *L,
+                               DomTreeUpdater *DTU, LoopInfo *LI) {
+  assert(!MergeBlocks.empty() && "MergeBlocks should not be empty");
+
+  bool MergedAdjacentBlocks = false;
+  while (!MergeBlocks.empty()) {
+    BasicBlock *BB = *MergeBlocks.begin();
+    BasicBlock *Dest = BB->getSingleSuccessor();
+    if (Dest && (!L || L->contains(Dest))) {
+      BasicBlock *Fold = Dest->getUniquePredecessor();
+      if (MergeBlockIntoPredecessor(Dest, DTU, LI)) {
+        assert(!UniquePredecessor ||
+               (Fold == BB &&
+                "Expecting BB to be unique predecessor of the Dest block"));
+        MergeBlocks.erase(Dest);
+        MergedAdjacentBlocks = true;
+      } else
+        MergeBlocks.erase(BB);
+    } else
+      MergeBlocks.erase(BB);
+  }
+  return MergedAdjacentBlocks;
+}
+
 /// Remove redundant instructions within sequences of consecutive dbg.value
 /// instructions. This is done using a backward scan to keep the last dbg.value
 /// describing a specific variable/fragment.
Index: llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
===================================================================
--- llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/LoopInfo.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/InstrTypes.h"
@@ -96,6 +97,16 @@
                                MemoryDependenceResults *MemDep = nullptr,
                                bool PredecessorWithTwoSuccessors = false);
 
+/// Merge Adjacent blocks, if possible. Return true if at least two
+/// of the blocks were merged together.
+/// In order to merge, each block must be terminated by an unconditional
+/// branch. In addition, a call to MergeBlockIntoPredecessor where
+/// the block following the terminal branch is passed must
+/// return true.
+bool MergeAdjacentBlocks(SmallPtrSetImpl<BasicBlock *> &MergeBlocks,
+                         bool UniquePredecessor = true, Loop *L = nullptr,
+                         DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr);
+
 /// Try to remove redundant dbg.value instructions from given basic block.
 /// Returns true if at least one instruction was removed.
 bool RemoveRedundantDbgInstrs(BasicBlock *BB);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80583.266299.patch
Type: text/x-patch
Size: 4044 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200526/6c95cff8/attachment.bin>


More information about the llvm-commits mailing list