Skip to content

Commit 3ddd1ff

Browse files
committed
[SCEV] Don't invalidate past dependency-breaking instructions
When invalidating a value, we walk all users of that value and invalidate them as well. This can be very expensive for large use graphs. However, we only need to invalidate a user U of instruction I if SCEV(U) can depend on SCEV(I). This is not the case if U is an instruction that always produces a SCEVUnknown, such as a load. If the load pointer operand is invalidated, there is no need to invalidate the load result, which is completely unrelated from a SCEV perspective. Differential Revision: https://reviews.llvm.org/D149323
1 parent 0659000 commit 3ddd1ff

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4490,14 +4490,30 @@ void ScalarEvolution::insertValueToMap(Value *V, const SCEV *S) {
44904490
}
44914491
}
44924492

4493+
/// Determine whether this instruction is either not SCEVable or will always
4494+
/// produce a SCEVUnknown. We do not have to walk past such instructions when
4495+
/// invalidating.
4496+
static bool isAlwaysUnknown(const Instruction *I) {
4497+
switch (I->getOpcode()) {
4498+
case Instruction::Load:
4499+
return true;
4500+
default:
4501+
return false;
4502+
}
4503+
}
4504+
44934505
/// Return an existing SCEV if it exists, otherwise analyze the expression and
44944506
/// create a new one.
44954507
const SCEV *ScalarEvolution::getSCEV(Value *V) {
44964508
assert(isSCEVable(V->getType()) && "Value is not SCEVable!");
44974509

44984510
if (const SCEV *S = getExistingSCEV(V))
44994511
return S;
4500-
return createSCEVIter(V);
4512+
const SCEV *S = createSCEVIter(V);
4513+
assert((!isa<Instruction>(V) || !isAlwaysUnknown(cast<Instruction>(V)) ||
4514+
isa<SCEVUnknown>(S)) &&
4515+
"isAlwaysUnknown() instruction is not SCEVUnknown");
4516+
return S;
45014517
}
45024518

45034519
const SCEV *ScalarEvolution::getExistingSCEV(Value *V) {
@@ -4798,6 +4814,8 @@ static void PushDefUseChildren(Instruction *I,
47984814
// Push the def-use children onto the Worklist stack.
47994815
for (User *U : I->users()) {
48004816
auto *UserInsn = cast<Instruction>(U);
4817+
if (isAlwaysUnknown(UserInsn))
4818+
continue;
48014819
if (Visited.insert(UserInsn).second)
48024820
Worklist.push_back(UserInsn);
48034821
}

0 commit comments

Comments
 (0)