[PATCH] D43997: [SCEV][NFC] Smarter implementation of isAvailableAtLoopEntry

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 12 21:32:42 PDT 2018


mkazantsev added inline comments.


================
Comment at: lib/Analysis/ScalarEvolution.cpp:2237
 bool ScalarEvolution::isAvailableAtLoopEntry(const SCEV *S, const Loop *L) {
-  if (!isLoopInvariant(S, L))
-    return false;
-  // If a value depends on a SCEVUnknown which is defined after the loop, we
-  // conservatively assume that we cannot calculate it at the loop's entry.
-  struct FindDominatedSCEVUnknown {
-    bool Found = false;
-    const Loop *L;
-    DominatorTree &DT;
-    LoopInfo &LI;
-
-    FindDominatedSCEVUnknown(const Loop *L, DominatorTree &DT, LoopInfo &LI)
-        : L(L), DT(DT), LI(LI) {}
-
-    bool checkSCEVUnknown(const SCEVUnknown *SU) {
-      if (auto *I = dyn_cast<Instruction>(SU->getValue())) {
-        if (DT.dominates(L->getHeader(), I->getParent()))
-          Found = true;
-        else
-          assert(DT.dominates(I->getParent(), L->getHeader()) &&
-                 "No dominance relationship between SCEV and loop?");
-      }
-      return false;
-    }
-
-    bool follow(const SCEV *S) {
-      switch (static_cast<SCEVTypes>(S->getSCEVType())) {
-      case scConstant:
-        return false;
-      case scAddRecExpr:
-      case scTruncate:
-      case scZeroExtend:
-      case scSignExtend:
-      case scAddExpr:
-      case scMulExpr:
-      case scUMaxExpr:
-      case scSMaxExpr:
-      case scUDivExpr:
-        return true;
-      case scUnknown:
-        return checkSCEVUnknown(cast<SCEVUnknown>(S));
-      case scCouldNotCompute:
-        llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
-      }
-      return false;
-    }
-
-    bool isDone() { return Found; }
-  };
-
-  FindDominatedSCEVUnknown FSU(L, DT, LI);
-  SCEVTraversal<FindDominatedSCEVUnknown> ST(FSU);
-  ST.visitAll(S);
-  return !FSU.Found;
+  return isLoopInvariant(S, L) && properlyDominates(S, L->getHeader());
 }
----------------
sanjoy wrote:
> Looks like `properlyDominates` is not transitive when this used to be transitive?
> 
> (It could be that `properlyDominates` is incorrect itself and needs to be transitive too - if yes, let's make that change first.)
I didn't get what do you mean under "transitive" in this context. The only significant difference I see is that `getBlockDisposition` is implemented via recursion with global caching and this is via SCEV traversal with local caching. Global caching is more profitable in this case since we can end up checking the same SCEVs again and again. I don't think there are any functional differences.


https://reviews.llvm.org/D43997





More information about the llvm-commits mailing list