[PATCH] D110378: [CodeMoverUtils] Enhance isSafeToMoveBefore() when moving BBs

Congzhe Cao via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 23 19:07:49 PDT 2021


congzhe created this revision.
congzhe added a project: LLVM.
Herald added a subscriber: hiraditya.
congzhe requested review of this revision.
Herald added a subscriber: llvm-commits.

When moving an entire basic block BB before InsertPoint, currently we check for all instructions whether the operands dominates InsertPoint, however, this can be improved such that even an operand does not dominate InsertPoint, as long as it appears as a previous instruction in the same BB, it is safe to move.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110378

Files:
  llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h
  llvm/lib/Transforms/Utils/CodeMoverUtils.cpp
  llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp


Index: llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
===================================================================
--- llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
+++ llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
@@ -601,6 +601,8 @@
                    br label %for.latch
                  for.latch:
                    %cmp = icmp slt i64 %inc, %N
+                   %add = add i64 100, %N
+                   %add2 = add i64 %add, %N
                    br i1 %cmp, label %for.body, label %for.end
                  for.end:
                    ret void
@@ -611,10 +613,17 @@
           DependenceInfo &DI) {
         Instruction *IncInst = getInstructionByName(F, "inc");
         Instruction *CmpInst = getInstructionByName(F, "cmp");
+        BasicBlock *BB0 = getBasicBlockByName(F, "for.body");
+        BasicBlock *BB1 = getBasicBlockByName(F, "for.latch");
 
         // Can move as the incoming block of %inc for %i (%for.latch) dominated
         // by %cmp.
         EXPECT_TRUE(isSafeToMoveBefore(*IncInst, *CmpInst, DT, &PDT, &DI));
+
+        // Can move as the operands of instructions in BB1 either dominate
+        // InsertPoint or appear before that instruction, e.g., %add appears
+        // before %add2 although %add does not dominate InsertPoint.
+        EXPECT_TRUE(isSafeToMoveBefore(*BB1, *BB0->getTerminator(), DT, &PDT, &DI));
       });
 }
 
Index: llvm/lib/Transforms/Utils/CodeMoverUtils.cpp
===================================================================
--- llvm/lib/Transforms/Utils/CodeMoverUtils.cpp
+++ llvm/lib/Transforms/Utils/CodeMoverUtils.cpp
@@ -309,7 +309,7 @@
 
 bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
                               DominatorTree &DT, const PostDominatorTree *PDT,
-                              DependenceInfo *DI) {
+                              DependenceInfo *DI, bool CheckForEntireBlock) {
   // Skip tests when we don't have PDT or DI
   if (!PDT || !DI)
     return false;
@@ -339,9 +339,21 @@
           return false;
   if (!DT.dominates(&I, &InsertPoint))
     for (const Value *Op : I.operands())
-      if (auto *OpInst = dyn_cast<Instruction>(Op))
-        if (&InsertPoint == OpInst || !DT.dominates(OpInst, &InsertPoint))
+      if (auto *OpInst = dyn_cast<Instruction>(Op)) {
+        if (&InsertPoint == OpInst)
+          return false;
+        if (CheckForEntireBlock) {
+          // If OpInst is an instruction that appears earlier in the same BB as
+          // I, then it is okay to move since OpInst will still be available.
+          BasicBlock::iterator it(&I);
+          if (std::find_if(
+                  I.getParent()->begin(), it,
+                  [&OpInst](Instruction &I) { return &I == OpInst; }) != it)
+            continue;
+        }
+        if (!DT.dominates(OpInst, &InsertPoint))
           return false;
+      }
 
   DT.updateDFSNumbers();
   const bool MoveForward = domTreeLevelBefore(&DT, &I, &InsertPoint);
@@ -393,7 +405,8 @@
     if (BB.getTerminator() == &I)
       return true;
 
-    return isSafeToMoveBefore(I, InsertPoint, DT, PDT, DI);
+    return isSafeToMoveBefore(I, InsertPoint, DT, PDT, DI,
+                              /*CheckForEntireBlock=*/true);
   });
 }
 
Index: llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h
===================================================================
--- llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h
+++ llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h
@@ -40,7 +40,8 @@
 bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
                         DominatorTree &DT,
                         const PostDominatorTree *PDT = nullptr,
-                        DependenceInfo *DI = nullptr);
+                        DependenceInfo *DI = nullptr,
+                        bool CheckForEntireBlock = false);
 
 /// Return true if all instructions (except the terminator) in \p BB can be
 /// safely moved before \p InsertPoint.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110378.374710.patch
Type: text/x-patch
Size: 4000 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210924/96fe6b37/attachment.bin>


More information about the llvm-commits mailing list