Skip to content

Commit 751be2a

Browse files
[CodeMoverUtils] Enhance isSafeToMoveBefore() when moving BBs
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. Reviewed By: Whitney Differential Revision: https://reviews.llvm.org/D110378
1 parent 7e46a72 commit 751be2a

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ bool isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1,
4040
bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
4141
DominatorTree &DT,
4242
const PostDominatorTree *PDT = nullptr,
43-
DependenceInfo *DI = nullptr);
43+
DependenceInfo *DI = nullptr,
44+
bool CheckForEntireBlock = false);
4445

4546
/// Return true if all instructions (except the terminator) in \p BB can be
4647
/// safely moved before \p InsertPoint.

llvm/lib/Transforms/Utils/CodeMoverUtils.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ collectInstructionsInBetween(Instruction &StartInst, const Instruction &EndInst,
309309

310310
bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
311311
DominatorTree &DT, const PostDominatorTree *PDT,
312-
DependenceInfo *DI) {
312+
DependenceInfo *DI, bool CheckForEntireBlock) {
313313
// Skip tests when we don't have PDT or DI
314314
if (!PDT || !DI)
315315
return false;
@@ -339,9 +339,17 @@ bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
339339
return false;
340340
if (!DT.dominates(&I, &InsertPoint))
341341
for (const Value *Op : I.operands())
342-
if (auto *OpInst = dyn_cast<Instruction>(Op))
343-
if (&InsertPoint == OpInst || !DT.dominates(OpInst, &InsertPoint))
342+
if (auto *OpInst = dyn_cast<Instruction>(Op)) {
343+
if (&InsertPoint == OpInst)
344+
return false;
345+
// If OpInst is an instruction that appears earlier in the same BB as
346+
// I, then it is okay to move since OpInst will still be available.
347+
if (CheckForEntireBlock && I.getParent() == OpInst->getParent() &&
348+
DT.dominates(OpInst, &I))
349+
continue;
350+
if (!DT.dominates(OpInst, &InsertPoint))
344351
return false;
352+
}
345353

346354
DT.updateDFSNumbers();
347355
const bool MoveForward = domTreeLevelBefore(&DT, &I, &InsertPoint);
@@ -393,7 +401,8 @@ bool llvm::isSafeToMoveBefore(BasicBlock &BB, Instruction &InsertPoint,
393401
if (BB.getTerminator() == &I)
394402
return true;
395403

396-
return isSafeToMoveBefore(I, InsertPoint, DT, PDT, DI);
404+
return isSafeToMoveBefore(I, InsertPoint, DT, PDT, DI,
405+
/*CheckForEntireBlock=*/true);
397406
});
398407
}
399408

llvm/unittests/Transforms/Utils/CodeMoverUtilsTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,8 @@ TEST(CodeMoverUtils, IsSafeToMoveTest3) {
601601
br label %for.latch
602602
for.latch:
603603
%cmp = icmp slt i64 %inc, %N
604+
%add = add i64 100, %N
605+
%add2 = add i64 %add, %N
604606
br i1 %cmp, label %for.body, label %for.end
605607
for.end:
606608
ret void
@@ -611,10 +613,18 @@ TEST(CodeMoverUtils, IsSafeToMoveTest3) {
611613
DependenceInfo &DI) {
612614
Instruction *IncInst = getInstructionByName(F, "inc");
613615
Instruction *CmpInst = getInstructionByName(F, "cmp");
616+
BasicBlock *BB0 = getBasicBlockByName(F, "for.body");
617+
BasicBlock *BB1 = getBasicBlockByName(F, "for.latch");
614618

615619
// Can move as the incoming block of %inc for %i (%for.latch) dominated
616620
// by %cmp.
617621
EXPECT_TRUE(isSafeToMoveBefore(*IncInst, *CmpInst, DT, &PDT, &DI));
622+
623+
// Can move as the operands of instructions in BB1 either dominate
624+
// InsertPoint or appear before that instruction, e.g., %add appears
625+
// before %add2 although %add does not dominate InsertPoint.
626+
EXPECT_TRUE(
627+
isSafeToMoveBefore(*BB1, *BB0->getTerminator(), DT, &PDT, &DI));
618628
});
619629
}
620630

0 commit comments

Comments
 (0)