forked from OSchip/llvm-project
[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
This commit is contained in:
parent
7e46a721fc
commit
751be2a064
|
@ -40,7 +40,8 @@ bool isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1,
|
||||||
bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
|
bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
|
||||||
DominatorTree &DT,
|
DominatorTree &DT,
|
||||||
const PostDominatorTree *PDT = nullptr,
|
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
|
/// Return true if all instructions (except the terminator) in \p BB can be
|
||||||
/// safely moved before \p InsertPoint.
|
/// safely moved before \p InsertPoint.
|
||||||
|
|
|
@ -309,7 +309,7 @@ collectInstructionsInBetween(Instruction &StartInst, const Instruction &EndInst,
|
||||||
|
|
||||||
bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
|
bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
|
||||||
DominatorTree &DT, const PostDominatorTree *PDT,
|
DominatorTree &DT, const PostDominatorTree *PDT,
|
||||||
DependenceInfo *DI) {
|
DependenceInfo *DI, bool CheckForEntireBlock) {
|
||||||
// Skip tests when we don't have PDT or DI
|
// Skip tests when we don't have PDT or DI
|
||||||
if (!PDT || !DI)
|
if (!PDT || !DI)
|
||||||
return false;
|
return false;
|
||||||
|
@ -339,9 +339,17 @@ bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
|
||||||
return false;
|
return false;
|
||||||
if (!DT.dominates(&I, &InsertPoint))
|
if (!DT.dominates(&I, &InsertPoint))
|
||||||
for (const Value *Op : I.operands())
|
for (const Value *Op : I.operands())
|
||||||
if (auto *OpInst = dyn_cast<Instruction>(Op))
|
if (auto *OpInst = dyn_cast<Instruction>(Op)) {
|
||||||
if (&InsertPoint == OpInst || !DT.dominates(OpInst, &InsertPoint))
|
if (&InsertPoint == OpInst)
|
||||||
return false;
|
return false;
|
||||||
|
// 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.
|
||||||
|
if (CheckForEntireBlock && I.getParent() == OpInst->getParent() &&
|
||||||
|
DT.dominates(OpInst, &I))
|
||||||
|
continue;
|
||||||
|
if (!DT.dominates(OpInst, &InsertPoint))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DT.updateDFSNumbers();
|
DT.updateDFSNumbers();
|
||||||
const bool MoveForward = domTreeLevelBefore(&DT, &I, &InsertPoint);
|
const bool MoveForward = domTreeLevelBefore(&DT, &I, &InsertPoint);
|
||||||
|
@ -393,7 +401,8 @@ bool llvm::isSafeToMoveBefore(BasicBlock &BB, Instruction &InsertPoint,
|
||||||
if (BB.getTerminator() == &I)
|
if (BB.getTerminator() == &I)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return isSafeToMoveBefore(I, InsertPoint, DT, PDT, DI);
|
return isSafeToMoveBefore(I, InsertPoint, DT, PDT, DI,
|
||||||
|
/*CheckForEntireBlock=*/true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -601,6 +601,8 @@ TEST(CodeMoverUtils, IsSafeToMoveTest3) {
|
||||||
br label %for.latch
|
br label %for.latch
|
||||||
for.latch:
|
for.latch:
|
||||||
%cmp = icmp slt i64 %inc, %N
|
%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
|
br i1 %cmp, label %for.body, label %for.end
|
||||||
for.end:
|
for.end:
|
||||||
ret void
|
ret void
|
||||||
|
@ -611,10 +613,18 @@ TEST(CodeMoverUtils, IsSafeToMoveTest3) {
|
||||||
DependenceInfo &DI) {
|
DependenceInfo &DI) {
|
||||||
Instruction *IncInst = getInstructionByName(F, "inc");
|
Instruction *IncInst = getInstructionByName(F, "inc");
|
||||||
Instruction *CmpInst = getInstructionByName(F, "cmp");
|
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
|
// Can move as the incoming block of %inc for %i (%for.latch) dominated
|
||||||
// by %cmp.
|
// by %cmp.
|
||||||
EXPECT_TRUE(isSafeToMoveBefore(*IncInst, *CmpInst, DT, &PDT, &DI));
|
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));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue