[llvm] [SCEV] Refactor forgetLoop and forgetValue to improve compile time (PR #198759)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 03:23:55 PDT 2026
================
@@ -8835,13 +8792,37 @@ void ScalarEvolution::forgetValue(Value *V) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I) return;
- // Drop information about expressions based on loop-header PHIs.
- SmallVector<Instruction *, 16> Worklist;
+ SmallVector<std::pair<Instruction *, const SCEV *>, 16> Worklist;
SmallPtrSet<Instruction *, 8> Visited;
SmallVector<SCEVUse, 8> ToForget;
- Worklist.push_back(I);
- Visited.insert(I);
- visitAndClearUsers(Worklist, Visited, ToForget);
+
+ auto PushIntoWorklist = [&](Instruction *UI, bool AllowMissingSCEV = false) {
+ bool IsSCEVable = isSCEVable(UI->getType());
+ bool IsWO = isa<WithOverflowInst>(UI);
+ if ((!IsSCEVable && !IsWO) || !Visited.insert(UI).second)
+ return;
+ if (IsSCEVable) {
+ if (const SCEV *S = getExistingSCEV(UI))
----------------
nikic wrote:
Specifically, I don't think that this logic is correct. SCEV will generally not create intermediate SCEVs for all expressions. Consider if you have something like this:
```
%add1 = add i32 %x, 1
%add2 = add i32 %add1, 1
%add3 = add i32 %add2, 1
```
And then query SCEV for `%add3`. This will create SCEV for `%x` and `%add3`, but not the intermediate adds. So if you now invalidate `%add1` (e.g. because you changed the constant), then there will be no existing SCEV, and it will fail to invalidate `%add3`.
https://github.com/llvm/llvm-project/pull/198759
More information about the llvm-commits
mailing list