Skip to content

Commit b0662a7

Browse files
[CodeMoverUtils] Enhance CodeMoverUtils to sink an entire BB (#87857)
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 by `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 751be2a that enhanced hoisting an entire BB, and this patch enhances sinking an entire BB. Please refer to the added functionality in test case `llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp` that was not supported without this patch.
1 parent 817c832 commit b0662a7

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

llvm/lib/Transforms/Utils/CodeMoverUtils.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,22 @@ bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
336336

337337
if (isReachedBefore(&I, &InsertPoint, &DT, PDT))
338338
for (const Use &U : I.uses())
339-
if (auto *UserInst = dyn_cast<Instruction>(U.getUser()))
340-
if (UserInst != &InsertPoint && !DT.dominates(&InsertPoint, U))
339+
if (auto *UserInst = dyn_cast<Instruction>(U.getUser())) {
340+
// If InsertPoint is in a BB that comes after I, then we cannot move if
341+
// I is used in the terminator of the current BB.
342+
if (I.getParent() == InsertPoint.getParent() &&
343+
UserInst == I.getParent()->getTerminator())
341344
return false;
345+
if (UserInst != &InsertPoint && !DT.dominates(&InsertPoint, U)) {
346+
// If UserInst is an instruction that appears later in the same BB as
347+
// I, then it is okay to move since I will still be available when
348+
// UserInst is executed.
349+
if (CheckForEntireBlock && I.getParent() == UserInst->getParent() &&
350+
DT.dominates(&I, UserInst))
351+
continue;
352+
return false;
353+
}
354+
}
342355
if (isReachedBefore(&InsertPoint, &I, &DT, PDT))
343356
for (const Value *Op : I.operands())
344357
if (auto *OpInst = dyn_cast<Instruction>(Op)) {

llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,11 @@ TEST(CodeMoverUtils, IsSafeToMoveTest4) {
673673
// Can move as %add2 and %sub2 are control flow equivalent,
674674
// although %add2 does not strictly dominate %sub2.
675675
EXPECT_TRUE(isSafeToMoveBefore(*SubInst2, *AddInst2, DT, &PDT, &DI));
676+
677+
BasicBlock *BB0 = getBasicBlockByName(F, "if.then.first");
678+
BasicBlock *BB1 = getBasicBlockByName(F, "if.then.second");
679+
EXPECT_TRUE(
680+
isSafeToMoveBefore(*BB0, *BB1->getTerminator(), DT, &PDT, &DI));
676681
});
677682
}
678683

0 commit comments

Comments
 (0)