[llvm] [CodeMoverUtils] Enhance CodeMoverUtils to sink an entire BB (PR #87857)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 5 19:52:44 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Congzhe (CongzheUalberta)

<details>
<summary>Changes</summary>

When moving an entire basic block after `InsertPoint`, currently we check each instruction whether their users are dominated by `InsertPoint`, however, this can be improved such that even a user is not dominated `InsertPoint`, as long as it appears as a subsequent instruction in the same BB, it is safe to move.

This patch is similar to commit 751be2a064f119af74c7b9b1e52bc904d8aa114d that enhanced hoisting an entire BB, and this patch enhances sinking an entire BB.

---
Full diff: https://github.com/llvm/llvm-project/pull/87857.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Utils/CodeMoverUtils.cpp (+10-2) 
- (modified) llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp (+8) 


``````````diff
diff --git a/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp b/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp
index 6a2dae5bab68ee..8b9526ceda9a3a 100644
--- a/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp
+++ b/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp
@@ -337,8 +337,16 @@ bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
   if (isReachedBefore(&I, &InsertPoint, &DT, PDT))
     for (const Use &U : I.uses())
       if (auto *UserInst = dyn_cast<Instruction>(U.getUser()))
-        if (UserInst != &InsertPoint && !DT.dominates(&InsertPoint, U))
-          return false;
+        if (UserInst != &InsertPoint && !DT.dominates(&InsertPoint, U)) {
+          // If UserInst is an instruction that appears later in the same BB as
+          // I, then it is okay to move since I will still be available when
+          // UserInst is executed.
+          if (CheckForEntireBlock && I.getParent() == UserInst->getParent() &&
+              DT.dominates(&I, UserInst))
+            continue;
+          if (UserInst != &InsertPoint && !DT.dominates(&InsertPoint, U))
+            return false;
+        }
   if (isReachedBefore(&InsertPoint, &I, &DT, PDT))
     for (const Value *Op : I.operands())
       if (auto *OpInst = dyn_cast<Instruction>(Op)) {
diff --git a/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp b/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
index 8554d1a33cadee..e599450f25e0ee 100644
--- a/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
+++ b/llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp
@@ -615,6 +615,7 @@ TEST(CodeMoverUtils, IsSafeToMoveTest3) {
         Instruction *CmpInst = getInstructionByName(F, "cmp");
         BasicBlock *BB0 = getBasicBlockByName(F, "for.body");
         BasicBlock *BB1 = getBasicBlockByName(F, "for.latch");
+        BasicBlock *BB2 = getBasicBlockByName(F, "for.end");
 
         // Can move as the incoming block of %inc for %i (%for.latch) dominated
         // by %cmp.
@@ -625,6 +626,13 @@ TEST(CodeMoverUtils, IsSafeToMoveTest3) {
         // before %add2 although %add does not dominate InsertPoint.
         EXPECT_TRUE(
             isSafeToMoveBefore(*BB1, *BB0->getTerminator(), 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, *BB2->getTerminator(), DT, &PDT, &DI));
+
       });
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/87857


More information about the llvm-commits mailing list