Revert "[SCEV] Support clearing Block/LoopDispositions for a single value."
authorFlorian Hahn <flo@fhahn.com>
Fri, 7 Oct 2022 16:58:53 +0000 (17:58 +0100)
committerFlorian Hahn <flo@fhahn.com>
Fri, 7 Oct 2022 16:58:54 +0000 (17:58 +0100)
This reverts commit 9e931439ddb9b6b8f655940b9d8ed6db50c2a7e2.

This commit causes a crash when TSan, e.g. with
https://lab.llvm.org/buildbot/#/builders/70/builds/28309/steps/10/logs/stdio

Reverting while I extract a reproducer and submit a fix.

llvm/include/llvm/Analysis/ScalarEvolution.h
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/lib/Transforms/Scalar/LoopDeletion.cpp
llvm/lib/Transforms/Scalar/LoopSink.cpp
llvm/lib/Transforms/Utils/LoopSimplify.cpp

index 580fef9..83f8a9e 100644 (file)
@@ -944,7 +944,7 @@ public:
   ///
   /// We don't have a way to invalidate per-loop/per-block dispositions. Clear
   /// and recompute is simpler.
-  void forgetBlockAndLoopDispositions(Value *V = nullptr);
+  void forgetBlockAndLoopDispositions();
 
   /// Determine the minimum number of zero bits that S is guaranteed to end in
   /// (at every loop iteration).  It is, at the same time, the minimum number
index 932be39..ac36aba 100644 (file)
@@ -8384,36 +8384,9 @@ void ScalarEvolution::forgetValue(Value *V) {
 
 void ScalarEvolution::forgetLoopDispositions() { LoopDispositions.clear(); }
 
-void ScalarEvolution::forgetBlockAndLoopDispositions(Value *V) {
-  // Unless a specific value is passed to invalidation, completely clear both
-  // caches.
-  if (!V) {
-    BlockDispositions.clear();
-    LoopDispositions.clear();
-    return;
-  }
-
-  const SCEV *S = getExistingSCEV(V);
-  if (!S)
-    return;
-
-  // Invalidate the block and loop dispositions cached for S. Dispositions of
-  // S's users may change if S's disposition changes (i.e. a user may change to
-  // loop-invariant, if S changes to loop invariant), so also invalidate
-  // dispositions of S's users recursively.
-  SmallVector<const SCEV *, 8> Worklist = {S};
-  SmallPtrSet<const SCEV *, 8> Seen = {S};
-  while (!Worklist.empty()) {
-    const SCEV *Curr = Worklist.pop_back_val();
-    if (!LoopDispositions.erase(Curr) && !BlockDispositions.erase(S))
-      continue;
-
-    auto Users = SCEVUsers.find(Curr);
-    if (Users != SCEVUsers.end())
-      for (const auto *User : Users->second)
-        if (Seen.insert(User).second)
-          Worklist.push_back(User);
-  }
+void ScalarEvolution::forgetBlockAndLoopDispositions() {
+  BlockDispositions.clear();
+  LoopDispositions.clear();
 }
 
 /// Get the exact loop backedge taken count considering all loop exits. A
index f19f53e..d969126 100644 (file)
@@ -90,21 +90,22 @@ static bool isLoopDead(Loop *L, ScalarEvolution &SE,
         break;
 
       if (Instruction *I = dyn_cast<Instruction>(incoming)) {
-        bool InstrMoved = false;
-        if (!L->makeLoopInvariant(I, InstrMoved, Preheader->getTerminator())) {
+        if (!L->makeLoopInvariant(I, Changed, Preheader->getTerminator())) {
           AllEntriesInvariant = false;
           break;
         }
-        Changed |= InstrMoved;
-        if (InstrMoved) {
+        if (Changed) {
           // Moving I to a different location may change its block disposition,
           // so invalidate its SCEV.
-          SE.forgetBlockAndLoopDispositions(I);
+          SE.forgetValue(I);
         }
       }
     }
   }
 
+  if (Changed)
+    SE.forgetLoopDispositions();
+
   if (!AllEntriesInvariant || !AllOutgoingValuesSame)
     return false;
 
index ff93727..131af32 100644 (file)
@@ -312,13 +312,12 @@ static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI,
     if (!canSinkOrHoistInst(I, &AA, &DT, &L, MSSAU, false, LICMFlags))
       continue;
     if (sinkInstruction(L, I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI,
-                        &MSSAU)) {
+                        &MSSAU))
       Changed = true;
-      if (SE)
-        SE->forgetBlockAndLoopDispositions(&I);
-    }
   }
 
+  if (Changed && SE)
+    SE->forgetLoopDispositions();
   return Changed;
 }
 
index f247a7e..16085f4 100644 (file)
@@ -647,22 +647,20 @@ ReprocessLoop:
         Instruction *Inst = &*I++;
         if (Inst == CI)
           continue;
-        bool InstInvariant = false;
         if (!L->makeLoopInvariant(
-                Inst, InstInvariant,
+                Inst, AnyInvariant,
                 Preheader ? Preheader->getTerminator() : nullptr, MSSAU)) {
           AllInvariant = false;
           break;
         }
-        if (InstInvariant && SE) {
-          // The loop disposition of all SCEV expressions that depend on any
-          // hoisted values have also changed.
-          SE->forgetBlockAndLoopDispositions(Inst);
-        }
-        AnyInvariant |= InstInvariant;
       }
-      if (AnyInvariant)
+      if (AnyInvariant) {
         Changed = true;
+        // The loop disposition of all SCEV expressions that depend on any
+        // hoisted values have also changed.
+        if (SE)
+          SE->forgetLoopDispositions();
+      }
       if (!AllInvariant) continue;
 
       // The block has now been cleared of all instructions except for