Skip to content

Commit 3e4d39e

Browse files
committed
[SimplifyCFG] Add early bailout if Use is not in same BB.
Without this patch, passingValueIsAlwaysUndefined will iterate over all instructions from I to the end of the basic block, even if the use is outside the block. This patch adds an early bail out, if the use instruction is outside I's BB. This can greatly reduce compile-time in cases where very large basic blocks are involved, with a large number of PHI nodes and incoming values. Note that the refactoring makes the handling of the case where I is a phi and Use is in PHI more explicit as well: for phi nodes, we can also directly bail out. In the existing code, we would iterate until we reach the end and return false. Based on an earlier patch by Matt Wala. Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D113293 (cherry-picked from 2ead347)
1 parent 2d7f32a commit 3e4d39e

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6465,19 +6465,21 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
64656465

64666466
if (C->isNullValue() || isa<UndefValue>(C)) {
64676467
// Only look at the first use, avoid hurting compile time with long uselists
6468-
User *Use = *I->user_begin();
6468+
auto *Use = cast<Instruction>(*I->user_begin());
6469+
// Bail out if Use is not in the same BB as I or Use == I or Use comes
6470+
// before I in the block. The latter two can be the case if Use is a PHI
6471+
// node.
6472+
if (Use->getParent() != I->getParent() || Use == I || Use->comesBefore(I))
6473+
return false;
64696474

64706475
// Now make sure that there are no instructions in between that can alter
64716476
// control flow (eg. calls)
6472-
for (BasicBlock::iterator
6473-
i = ++BasicBlock::iterator(I),
6474-
UI = BasicBlock::iterator(dyn_cast<Instruction>(Use));
6475-
i != UI; ++i) {
6476-
if (i == I->getParent()->end())
6477-
return false;
6478-
if (!isGuaranteedToTransferExecutionToSuccessor(&*i))
6479-
return false;
6480-
}
6477+
auto InstrRange =
6478+
make_range(std::next(I->getIterator()), Use->getIterator());
6479+
if (any_of(InstrRange, [](Instruction &I) {
6480+
return !isGuaranteedToTransferExecutionToSuccessor(&I);
6481+
}))
6482+
return false;
64816483

64826484
// Look through GEPs. A load from a GEP derived from NULL is still undefined
64836485
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Use))

0 commit comments

Comments
 (0)