[llvm] [SCEV] Introduce SCEVUse, use it instead of const SCEV * (NFCI) (WIP). (PR #91961)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 25 11:22:30 PST 2024


================
@@ -65,6 +65,117 @@ enum SCEVTypes : unsigned short;
 
 extern bool VerifySCEV;
 
+class SCEV;
+
+class SCEVUse : public PointerIntPair<const SCEV *, 3> {
+  bool computeIsCanonical() const;
+  const SCEV *computeCanonical(ScalarEvolution &SE) const;
+
+public:
+  SCEVUse() : PointerIntPair(nullptr, 0) {}
+  SCEVUse(const SCEV *S) : PointerIntPair(S, 0) {}
+  SCEVUse(const SCEV *S, int Flags) : PointerIntPair(S, Flags) {
+    if (Flags > 0)
+      setInt(Flags | 1);
+  }
+
+  operator const SCEV *() const { return getPointer(); }
+  const SCEV *operator->() const { return getPointer(); }
+  const SCEV *operator->() { return getPointer(); }
+
+  void *getRawPointer() const { return getOpaqueValue(); }
+
+  bool isCanonical() const {
+    assert(((getFlags() & 1) != 0 || computeIsCanonical()) &&
+           "Canonical bit set incorrectly");
+    return (getFlags() & 1) == 0;
+  }
+
+  const SCEV *getCanonical(ScalarEvolution &SE) {
+    if (isCanonical())
+      return getPointer();
+    return computeCanonical(SE);
+  }
+
+  unsigned getFlags() const { return getInt(); }
+
+  bool operator==(const SCEVUse &RHS) const;
+  bool operator==(const SCEV *RHS) const;
+  /// Print out the internal representation of this scalar to the specified
+  /// stream.  This should really only be used for debugging purposes.
+  void print(raw_ostream &OS) const;
+
+  /// This method is used for debugging.
+  void dump() const;
+};
+
+/// Provide PointerLikeTypeTraits for SCEVUse, so it can be used with
+/// SmallPtrSet, among others.
+template <> struct PointerLikeTypeTraits<SCEVUse> {
+  static inline void *getAsVoidPointer(SCEVUse U) { return U.getOpaqueValue(); }
+  static inline SCEVUse getFromVoidPointer(void *P) {
+    SCEVUse U;
+    U.setFromOpaqueValue(P);
+    return U;
+  }
+
+  /// The Low bits are used by the PointerIntPair.
+  static constexpr int NumLowBitsAvailable = 0;
+};
+
+template <> struct DenseMapInfo<SCEVUse> {
+  // The following should hold, but it would require T to be complete:
+  // static_assert(alignof(T) <= (1 << Log2MaxAlign),
+  //               "DenseMap does not support pointer keys requiring more than "
+  //               "Log2MaxAlign bits of alignment");
+  static constexpr uintptr_t Log2MaxAlign = 12;
+
+  static inline SCEVUse getEmptyKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-1);
+    Val <<= Log2MaxAlign;
+    return PointerLikeTypeTraits<SCEVUse>::getFromVoidPointer((void *)Val);
+  }
+
+  static inline SCEVUse getTombstoneKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-2);
+    Val <<= Log2MaxAlign;
+    return PointerLikeTypeTraits<SCEVUse>::getFromVoidPointer((void *)Val);
+  }
+
+  static unsigned getHashValue(SCEVUse U) {
+    void *PtrVal = PointerLikeTypeTraits<SCEVUse>::getAsVoidPointer(U);
+    return (unsigned((uintptr_t)PtrVal) >> 4) ^
+           (unsigned((uintptr_t)PtrVal) >> 9);
+  }
+
+  static bool isEqual(const SCEVUse LHS, const SCEVUse RHS) {
+    return LHS.getRawPointer() == RHS.getRawPointer();
+  }
+};
+
+template <typename To> [[nodiscard]] inline decltype(auto) dyn_cast(SCEVUse U) {
+  assert(detail::isPresent(U.getPointer()) &&
+         "dyn_cast on a non-existent value");
+  return CastInfo<To, const SCEV *>::doCastIfPossible(U.getPointer());
+}
+
+template <typename To> [[nodiscard]] inline decltype(auto) cast(SCEVUse U) {
+  assert(detail::isPresent(U.getPointer()) &&
+         "dyn_cast on a non-existent value");
+  return CastInfo<To, const SCEV *>::doCast(U.getPointer());
+}
+
+template <typename To> [[nodiscard]] inline bool isa(SCEVUse U) {
+  return CastInfo<To, const SCEV *>::isPossible(U.getPointer());
+}
+
+template <class X> auto dyn_cast_or_null(SCEVUse U) {
+  const SCEV *Val = U.getPointer();
+  if (!detail::isPresent(Val))
+    return CastInfo<X, const SCEV *>::castFailed();
+  return CastInfo<X, const SCEV *>::doCastIfPossible(detail::unwrapValue(Val));
+}
----------------
fhahn wrote:

Yep, will do that once we are happy with the rest of the patch

https://github.com/llvm/llvm-project/pull/91961


More information about the llvm-commits mailing list