[llvm] 59b0292 - [reland][NFC] Vastly simplifies TypeSize

Guillaume Chatelet via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 9 00:43:54 PST 2023


Author: Guillaume Chatelet
Date: 2023-01-09T08:43:37Z
New Revision: 59b029238af27e6d77017d225cfe0ed1c2dd22f3

URL: https://github.com/llvm/llvm-project/commit/59b029238af27e6d77017d225cfe0ed1c2dd22f3
DIFF: https://github.com/llvm/llvm-project/commit/59b029238af27e6d77017d225cfe0ed1c2dd22f3.diff

LOG: [reland][NFC] Vastly simplifies TypeSize

Simplifies the implementation of `TypeSize` while retaining its interface.
There is no need for abstract concepts like `LinearPolyBase`, `UnivariateLinearPolyBase` or `LinearPolySize`.

Differential Revision: https://reviews.llvm.org/D140263

Added: 
    

Modified: 
    llvm/include/llvm/Support/TypeSize.h
    llvm/lib/IR/StructuralHash.cpp
    llvm/unittests/Support/CMakeLists.txt
    llvm/unittests/Support/TypeSizeTest.cpp
    llvm/utils/TableGen/CodeGenDAGPatterns.cpp

Removed: 
    llvm/unittests/Support/LinearPolyBaseTest.cpp


################################################################################
diff  --git a/llvm/include/llvm/Support/TypeSize.h b/llvm/include/llvm/Support/TypeSize.h
index ae871cf478733..53c888e0a2e9b 100644
--- a/llvm/include/llvm/Support/TypeSize.h
+++ b/llvm/include/llvm/Support/TypeSize.h
@@ -31,176 +31,97 @@ namespace llvm {
 /// done on a scalable vector. This function may not return.
 void reportInvalidSizeRequest(const char *Msg);
 
-template <typename LeafTy> struct LinearPolyBaseTypeTraits {};
+/// StackOffset holds a fixed and a scalable offset in bytes.
+class StackOffset {
+  int64_t Fixed = 0;
+  int64_t Scalable = 0;
 
-//===----------------------------------------------------------------------===//
-// LinearPolyBase - a base class for linear polynomials with multiple
-// dimensions. This can e.g. be used to describe offsets that are have both a
-// fixed and scalable component.
-//===----------------------------------------------------------------------===//
-
-/// LinearPolyBase describes a linear polynomial:
-///  c0 * scale0 + c1 * scale1 + ... + cK * scaleK
-/// where the scale is implicit, so only the coefficients are encoded.
-template <typename LeafTy>
-class LinearPolyBase {
-public:
-  using ScalarTy = typename LinearPolyBaseTypeTraits<LeafTy>::ScalarTy;
-  static constexpr auto Dimensions = LinearPolyBaseTypeTraits<LeafTy>::Dimensions;
-  static_assert(Dimensions != std::numeric_limits<unsigned>::max(),
-                "Dimensions out of range");
-
-private:
-  std::array<ScalarTy, Dimensions> Coefficients;
-
-protected:
-  constexpr LinearPolyBase(ArrayRef<ScalarTy> Values) {
-    std::copy(Values.begin(), Values.end(), Coefficients.begin());
-  }
+  StackOffset(int64_t Fixed, int64_t Scalable)
+      : Fixed(Fixed), Scalable(Scalable) {}
 
 public:
-  friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
-    for (unsigned I=0; I<Dimensions; ++I)
-      LHS.Coefficients[I] += RHS.Coefficients[I];
-    return LHS;
-  }
-
-  friend LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
-    for (unsigned I=0; I<Dimensions; ++I)
-      LHS.Coefficients[I] -= RHS.Coefficients[I];
-    return LHS;
+  StackOffset() = default;
+  static StackOffset getFixed(int64_t Fixed) { return {Fixed, 0}; }
+  static StackOffset getScalable(int64_t Scalable) { return {0, Scalable}; }
+  static StackOffset get(int64_t Fixed, int64_t Scalable) {
+    return {Fixed, Scalable};
   }
 
-  friend LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) {
-    for (auto &C : LHS.Coefficients)
-      C *= RHS;
-    return LHS;
-  }
+  /// Returns the fixed component of the stack.
+  int64_t getFixed() const { return Fixed; }
 
-  friend LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
-    LeafTy Copy = LHS;
-    return Copy += RHS;
-  }
+  /// Returns the scalable component of the stack.
+  int64_t getScalable() const { return Scalable; }
 
-  friend LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
-    LeafTy Copy = LHS;
-    return Copy -= RHS;
+  // Arithmetic operations.
+  StackOffset operator+(const StackOffset &RHS) const {
+    return {Fixed + RHS.Fixed, Scalable + RHS.Scalable};
   }
-
-  friend LeafTy operator*(const LeafTy &LHS, ScalarTy RHS) {
-    LeafTy Copy = LHS;
-    return Copy *= RHS;
+  StackOffset operator-(const StackOffset &RHS) const {
+    return {Fixed - RHS.Fixed, Scalable - RHS.Scalable};
   }
-
-  template <typename U = ScalarTy>
-  friend std::enable_if_t<std::is_signed<U>::value, LeafTy>
-  operator-(const LeafTy &LHS) {
-    LeafTy Copy = LHS;
-    return Copy *= -1;
+  StackOffset &operator+=(const StackOffset &RHS) {
+    Fixed += RHS.Fixed;
+    Scalable += RHS.Scalable;
+    return *this;
   }
-
-  constexpr bool operator==(const LinearPolyBase &RHS) const {
-    return std::equal(Coefficients.begin(), Coefficients.end(),
-                      RHS.Coefficients.begin());
+  StackOffset &operator-=(const StackOffset &RHS) {
+    Fixed -= RHS.Fixed;
+    Scalable -= RHS.Scalable;
+    return *this;
   }
+  StackOffset operator-() const { return {-Fixed, -Scalable}; }
 
-  constexpr bool operator!=(const LinearPolyBase &RHS) const {
-    return !(*this == RHS);
+  // Equality comparisons.
+  bool operator==(const StackOffset &RHS) const {
+    return Fixed == RHS.Fixed && Scalable == RHS.Scalable;
   }
-
-  constexpr bool isZero() const {
-    return all_of(Coefficients, [](const ScalarTy &C) { return C == 0; });
+  bool operator!=(const StackOffset &RHS) const {
+    return Fixed != RHS.Fixed || Scalable != RHS.Scalable;
   }
-  constexpr bool isNonZero() const { return !isZero(); }
-  constexpr explicit operator bool() const { return isNonZero(); }
 
-  constexpr ScalarTy getValue(unsigned Dim) const { return Coefficients[Dim]; }
+  // The bool operator returns true iff any of the components is non zero.
+  explicit operator bool() const { return Fixed != 0 || Scalable != 0; }
 };
 
-//===----------------------------------------------------------------------===//
-// StackOffset - Represent an offset with named fixed and scalable components.
-//===----------------------------------------------------------------------===//
-
-class StackOffset;
-template <> struct LinearPolyBaseTypeTraits<StackOffset> {
-  using ScalarTy = int64_t;
-  static constexpr unsigned Dimensions = 2;
-};
-
-/// StackOffset is a class to represent an offset with 2 dimensions,
-/// named fixed and scalable, respectively. This class allows a value for both
-/// dimensions to depict e.g. "8 bytes and 16 scalable bytes", which is needed
-/// to represent stack offsets.
-class StackOffset : public LinearPolyBase<StackOffset> {
-protected:
-  StackOffset(ScalarTy Fixed, ScalarTy Scalable)
-      : LinearPolyBase<StackOffset>({Fixed, Scalable}) {}
+namespace details {
 
+// Base class for ElementCount and TypeSize below.
+template <typename LeafTy, typename ValueTy> class FixedOrScalableQuantity {
 public:
-  StackOffset() : StackOffset({0, 0}) {}
-  StackOffset(const LinearPolyBase<StackOffset> &Other)
-      : LinearPolyBase<StackOffset>(Other) {}
-  static StackOffset getFixed(ScalarTy Fixed) { return {Fixed, 0}; }
-  static StackOffset getScalable(ScalarTy Scalable) { return {0, Scalable}; }
-  static StackOffset get(ScalarTy Fixed, ScalarTy Scalable) {
-    return {Fixed, Scalable};
-  }
-
-  ScalarTy getFixed() const { return this->getValue(0); }
-  ScalarTy getScalable() const { return this->getValue(1); }
-};
-
-//===----------------------------------------------------------------------===//
-// UnivariateLinearPolyBase - a base class for linear polynomials with multiple
-// dimensions, but where only one dimension can be set at any time.
-// This can e.g. be used to describe sizes that are either fixed or scalable.
-//===----------------------------------------------------------------------===//
-
-/// UnivariateLinearPolyBase is a base class for ElementCount and TypeSize.
-/// Like LinearPolyBase it tries to represent a linear polynomial
-/// where only one dimension can be set at any time, e.g.
-///   0 * scale0 + 0 * scale1 + ... + cJ * scaleJ + ... + 0 * scaleK
-/// The dimension that is set is the univariate dimension.
-template <typename LeafTy>
-class UnivariateLinearPolyBase {
-public:
-  using ScalarTy = typename LinearPolyBaseTypeTraits<LeafTy>::ScalarTy;
-  static constexpr auto Dimensions = LinearPolyBaseTypeTraits<LeafTy>::Dimensions;
-  static_assert(Dimensions != std::numeric_limits<unsigned>::max(),
-                "Dimensions out of range");
+  using ScalarTy = ValueTy;
 
 protected:
-  ScalarTy Value;         // The value at the univeriate dimension.
-  unsigned UnivariateDim; // The univeriate dimension.
+  ScalarTy Quantity = 0;
+  bool Scalable = false;
 
-  constexpr UnivariateLinearPolyBase(ScalarTy Val, unsigned UnivariateDim)
-      : Value(Val), UnivariateDim(UnivariateDim) {
-    assert(UnivariateDim < Dimensions && "Dimension out of range");
-  }
+  constexpr FixedOrScalableQuantity() = default;
+  constexpr FixedOrScalableQuantity(ScalarTy Quantity, bool Scalable)
+      : Quantity(Quantity), Scalable(Scalable) {}
 
-  friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
-    assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions");
-    LHS.Value += RHS.Value;
+  friend constexpr LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
+    assert(LHS.Scalable == RHS.Scalable && "Incompatible types");
+    LHS.Quantity += RHS.Quantity;
     return LHS;
   }
 
-  friend LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
-    assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions");
-    LHS.Value -= RHS.Value;
+  friend constexpr LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
+    assert(LHS.Scalable == RHS.Scalable && "Incompatible types");
+    LHS.Quantity -= RHS.Quantity;
     return LHS;
   }
 
   friend constexpr LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) {
-    LHS.Value *= RHS;
+    LHS.Quantity *= RHS;
     return LHS;
   }
 
-  friend LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
+  friend constexpr LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
     LeafTy Copy = LHS;
     return Copy += RHS;
   }
 
-  friend LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
+  friend constexpr LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
     LeafTy Copy = LHS;
     return Copy -= RHS;
   }
@@ -211,96 +132,43 @@ class UnivariateLinearPolyBase {
   }
 
   template <typename U = ScalarTy>
-  friend std::enable_if_t<std::is_signed<U>::value, LeafTy>
+  friend constexpr std::enable_if_t<std::is_signed<U>::value, LeafTy>
   operator-(const LeafTy &LHS) {
     LeafTy Copy = LHS;
     return Copy *= -1;
   }
 
 public:
-  constexpr bool operator==(const UnivariateLinearPolyBase &RHS) const {
-    return Value == RHS.Value && UnivariateDim == RHS.UnivariateDim;
-  }
-
-  constexpr bool operator!=(const UnivariateLinearPolyBase &RHS) const {
-    return !(*this == RHS);
-  }
-
-  constexpr bool isZero() const { return !Value; }
-  constexpr bool isNonZero() const { return !isZero(); }
-  explicit constexpr operator bool() const { return isNonZero(); }
-  constexpr ScalarTy getValue(unsigned Dim) const {
-    return Dim == UnivariateDim ? Value : 0;
+  constexpr bool operator==(const FixedOrScalableQuantity &RHS) const {
+    return Quantity == RHS.Quantity && Scalable == RHS.Scalable;
   }
 
-  /// Add \p RHS to the value at the univariate dimension.
-  constexpr LeafTy getWithIncrement(ScalarTy RHS) const {
-    return static_cast<LeafTy>(
-        UnivariateLinearPolyBase(Value + RHS, UnivariateDim));
-  }
-
-  /// Subtract \p RHS from the value at the univariate dimension.
-  constexpr LeafTy getWithDecrement(ScalarTy RHS) const {
-    return static_cast<LeafTy>(
-        UnivariateLinearPolyBase(Value - RHS, UnivariateDim));
+  constexpr bool operator!=(const FixedOrScalableQuantity &RHS) const {
+    return Quantity != RHS.Quantity || Scalable != RHS.Scalable;
   }
-};
-
 
-//===----------------------------------------------------------------------===//
-// LinearPolySize - base class for fixed- or scalable sizes.
-//  ^  ^
-//  |  |
-//  |  +----- ElementCount - Leaf class to represent an element count
-//  |                        (vscale x unsigned)
-//  |
-//  +-------- TypeSize - Leaf class to represent a type size
-//                       (vscale x uint64_t)
-//===----------------------------------------------------------------------===//
+  constexpr bool isZero() const { return Quantity == 0; }
 
-/// LinearPolySize is a base class to represent sizes. It is either
-/// fixed-sized or it is scalable-sized, but it cannot be both.
-template <typename LeafTy>
-class LinearPolySize : public UnivariateLinearPolyBase<LeafTy> {
-  // Make the parent class a friend, so that it can access the protected
-  // conversion/copy-constructor for UnivariatePolyBase<LeafTy> ->
-  // LinearPolySize<LeafTy>.
-  friend class UnivariateLinearPolyBase<LeafTy>;
+  constexpr bool isNonZero() const { return Quantity != 0; }
 
-public:
-  using ScalarTy = typename UnivariateLinearPolyBase<LeafTy>::ScalarTy;
-  enum Dims : unsigned { FixedDim = 0, ScalableDim = 1 };
+  explicit operator bool() const { return isNonZero(); }
 
-protected:
-  constexpr LinearPolySize(ScalarTy MinVal, Dims D)
-      : UnivariateLinearPolyBase<LeafTy>(MinVal, D) {}
+  /// Add \p RHS to the underlying quantity.
+  constexpr LeafTy getWithIncrement(ScalarTy RHS) const {
+    return LeafTy::get(Quantity + RHS, Scalable);
+  }
 
-  constexpr LinearPolySize(const UnivariateLinearPolyBase<LeafTy> &V)
-      : UnivariateLinearPolyBase<LeafTy>(V) {}
+  /// Returns the minimum value this quantity can represent.
+  constexpr ScalarTy getKnownMinValue() const { return Quantity; }
 
-public:
-  static constexpr LeafTy getFixed(ScalarTy MinVal) {
-    return static_cast<LeafTy>(LinearPolySize(MinVal, FixedDim));
-  }
-  static constexpr LeafTy getScalable(ScalarTy MinVal) {
-    return static_cast<LeafTy>(LinearPolySize(MinVal, ScalableDim));
-  }
-  static constexpr LeafTy get(ScalarTy MinVal, bool Scalable) {
-    return static_cast<LeafTy>(
-        LinearPolySize(MinVal, Scalable ? ScalableDim : FixedDim));
-  }
-  static constexpr LeafTy getNull() { return get(0, false); }
+  /// Returns whether the quantity is scaled by a runtime quantity (vscale).
+  constexpr bool isScalable() const { return Scalable; }
 
-  /// Returns the minimum value this size can represent.
-  constexpr ScalarTy getKnownMinValue() const { return this->Value; }
-  /// Returns whether the size is scaled by a runtime quantity (vscale).
-  constexpr bool isScalable() const {
-    return this->UnivariateDim == ScalableDim;
-  }
   /// A return value of true indicates we know at compile time that the number
   /// of elements (vscale * Min) is definitely even. However, returning false
   /// does not guarantee that the total number of elements is odd.
   constexpr bool isKnownEven() const { return (getKnownMinValue() & 0x1) == 0; }
+
   /// This function tells the caller whether the element count is known at
   /// compile time to be a multiple of the scalar value RHS.
   constexpr bool isKnownMultipleOf(ScalarTy RHS) const {
@@ -316,8 +184,8 @@ class LinearPolySize : public UnivariateLinearPolyBase<LeafTy> {
     return getKnownMinValue();
   }
 
-  // For some cases, size ordering between scalable and fixed size types cannot
-  // be determined at compile time, so such comparisons aren't allowed.
+  // For some cases, quantity ordering between scalable and fixed quantity types
+  // cannot be determined at compile time, so such comparisons aren't allowed.
   //
   // e.g. <vscale x 2 x i16> could be bigger than <4 x i32> with a runtime
   // vscale >= 5, equal sized with a vscale of 4, and smaller with
@@ -326,29 +194,29 @@ class LinearPolySize : public UnivariateLinearPolyBase<LeafTy> {
   // All the functions below make use of the fact vscale is always >= 1, which
   // means that <vscale x 4 x i32> is guaranteed to be >= <4 x i32>, etc.
 
-  static constexpr bool isKnownLT(const LinearPolySize &LHS,
-                                  const LinearPolySize &RHS) {
+  static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS,
+                                  const FixedOrScalableQuantity &RHS) {
     if (!LHS.isScalable() || RHS.isScalable())
       return LHS.getKnownMinValue() < RHS.getKnownMinValue();
     return false;
   }
 
-  static constexpr bool isKnownGT(const LinearPolySize &LHS,
-                                  const LinearPolySize &RHS) {
+  static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS,
+                                  const FixedOrScalableQuantity &RHS) {
     if (LHS.isScalable() || !RHS.isScalable())
       return LHS.getKnownMinValue() > RHS.getKnownMinValue();
     return false;
   }
 
-  static constexpr bool isKnownLE(const LinearPolySize &LHS,
-                                  const LinearPolySize &RHS) {
+  static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS,
+                                  const FixedOrScalableQuantity &RHS) {
     if (!LHS.isScalable() || RHS.isScalable())
       return LHS.getKnownMinValue() <= RHS.getKnownMinValue();
     return false;
   }
 
-  static constexpr bool isKnownGE(const LinearPolySize &LHS,
-                                  const LinearPolySize &RHS) {
+  static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS,
+                                  const FixedOrScalableQuantity &RHS) {
     if (LHS.isScalable() || !RHS.isScalable())
       return LHS.getKnownMinValue() >= RHS.getKnownMinValue();
     return false;
@@ -363,31 +231,31 @@ class LinearPolySize : public UnivariateLinearPolyBase<LeafTy> {
   /// isKnownMultipleOf(RHS), which lets the caller know if it's possible to
   /// perform a lossless divide by RHS.
   constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const {
-    return static_cast<LeafTy>(
-        LinearPolySize::get(getKnownMinValue() / RHS, isScalable()));
+    return LeafTy::get(getKnownMinValue() / RHS, isScalable());
   }
 
   constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const {
-    return static_cast<LeafTy>(
-        LinearPolySize::get(getKnownMinValue() * RHS, isScalable()));
+    return LeafTy::get(getKnownMinValue() * RHS, isScalable());
   }
 
   constexpr LeafTy coefficientNextPowerOf2() const {
-    return static_cast<LeafTy>(LinearPolySize::get(
+    return LeafTy::get(
         static_cast<ScalarTy>(llvm::NextPowerOf2(getKnownMinValue())),
-        isScalable()));
+        isScalable());
   }
 
   /// Returns true if there exists a value X where RHS.multiplyCoefficientBy(X)
-  /// will result in a value whose size matches our own.
-  constexpr bool hasKnownScalarFactor(const LinearPolySize &RHS) const {
+  /// will result in a value whose quantity matches our own.
+  constexpr bool
+  hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const {
     return isScalable() == RHS.isScalable() &&
            getKnownMinValue() % RHS.getKnownMinValue() == 0;
   }
 
   /// Returns a value X where RHS.multiplyCoefficientBy(X) will result in a
-  /// value whose size matches our own.
-  constexpr ScalarTy getKnownScalarFactor(const LinearPolySize &RHS) const {
+  /// value whose quantity matches our own.
+  constexpr ScalarTy
+  getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const {
     assert(hasKnownScalarFactor(RHS) && "Expected RHS to be a known factor!");
     return getKnownMinValue() / RHS.getKnownMinValue();
   }
@@ -400,22 +268,35 @@ class LinearPolySize : public UnivariateLinearPolyBase<LeafTy> {
   }
 };
 
-class ElementCount;
-template <> struct LinearPolyBaseTypeTraits<ElementCount> {
-  using ScalarTy = unsigned;
-  static constexpr unsigned Dimensions = 2;
-};
+} // namespace details
+
+// Stores the number of elements for a type and whether this type is fixed
+// (N-Elements) or scalable (e.g., SVE).
+//  - ElementCount::getFixed(1) : A scalar value.
+//  - ElementCount::getFixed(2) : A vector type holding 2 values.
+//  - ElementCount::getScalable(4) : A scalable vector type holding 4 values.
+class ElementCount
+    : public details::FixedOrScalableQuantity<ElementCount, unsigned> {
+  constexpr ElementCount(ScalarTy MinVal, bool Scalable)
+      : FixedOrScalableQuantity(MinVal, Scalable) {}
+
+  constexpr ElementCount(
+      const FixedOrScalableQuantity<ElementCount, unsigned> &V)
+      : FixedOrScalableQuantity(V) {}
 
-class ElementCount : public LinearPolySize<ElementCount> {
 public:
-  constexpr ElementCount() : LinearPolySize(LinearPolySize::getNull()) {}
+  constexpr ElementCount() : FixedOrScalableQuantity() {}
 
-  constexpr ElementCount(const LinearPolySize<ElementCount> &V)
-      : LinearPolySize(V) {}
+  static constexpr ElementCount getFixed(ScalarTy MinVal) {
+    return ElementCount(MinVal, false);
+  }
+  static constexpr ElementCount getScalable(ScalarTy MinVal) {
+    return ElementCount(MinVal, true);
+  }
+  static constexpr ElementCount get(ScalarTy MinVal, bool Scalable) {
+    return ElementCount(MinVal, Scalable);
+  }
 
-  /// Counting predicates.
-  ///
-  ///@{ Number of elements..
   /// Exactly one element.
   constexpr bool isScalar() const {
     return !isScalable() && getKnownMinValue() == 1;
@@ -424,33 +305,33 @@ class ElementCount : public LinearPolySize<ElementCount> {
   constexpr bool isVector() const {
     return (isScalable() && getKnownMinValue() != 0) || getKnownMinValue() > 1;
   }
-  ///@}
 };
 
-// This class is used to represent the size of types. If the type is of fixed
-class TypeSize;
-template <> struct LinearPolyBaseTypeTraits<TypeSize> {
-  using ScalarTy = uint64_t;
-  static constexpr unsigned Dimensions = 2;
-};
+// Stores the size of a type. If the type is of fixed size, it will represent
+// the exact size. If the type is a scalable vector, it will represent the known
+// minimum size.
+class TypeSize : public details::FixedOrScalableQuantity<TypeSize, uint64_t> {
+  TypeSize(const FixedOrScalableQuantity<TypeSize, uint64_t> &V)
+      : FixedOrScalableQuantity(V) {}
 
-// TODO: Most functionality in this class will gradually be phased out
-// so it will resemble LinearPolySize as much as possible.
-//
-// TypeSize is used to represent the size of types. If the type is of fixed
-// size, it will represent the exact size. If the type is a scalable vector,
-// it will represent the known minimum size.
-class TypeSize : public LinearPolySize<TypeSize> {
 public:
-  constexpr TypeSize(const LinearPolySize<TypeSize> &V) : LinearPolySize(V) {}
-  constexpr TypeSize(ScalarTy MinVal, bool IsScalable)
-      : LinearPolySize(LinearPolySize::get(MinVal, IsScalable)) {}
+  constexpr TypeSize(ScalarTy Quantity, bool Scalable)
+      : FixedOrScalableQuantity(Quantity, Scalable) {}
 
-  static constexpr TypeSize Fixed(ScalarTy MinVal) {
-    return TypeSize(MinVal, false);
+  static constexpr TypeSize getFixed(ScalarTy ExactSize) {
+    return TypeSize(ExactSize, false);
   }
-  static constexpr TypeSize Scalable(ScalarTy MinVal) {
-    return TypeSize(MinVal, true);
+  static constexpr TypeSize getScalable(ScalarTy MinimunSize) {
+    return TypeSize(MinimunSize, true);
+  }
+  static constexpr TypeSize get(ScalarTy Quantity, bool Scalable) {
+    return TypeSize(Quantity, Scalable);
+  }
+  static constexpr TypeSize Fixed(ScalarTy ExactSize) {
+    return TypeSize(ExactSize, false);
+  }
+  static constexpr TypeSize Scalable(ScalarTy MinimumSize) {
+    return TypeSize(MinimumSize, true);
   }
 
   constexpr ScalarTy getFixedSize() const { return getFixedValue(); }
@@ -512,7 +393,7 @@ class TypeSize : public LinearPolySize<TypeSize> {
 //===----------------------------------------------------------------------===//
 
 /// Returns a TypeSize with a known minimum size that is the next integer
-/// (mod 2**64) that is greater than or equal to \p Value and is a multiple
+/// (mod 2**64) that is greater than or equal to \p Quantity and is a multiple
 /// of \p Align. \p Align must be non-zero.
 ///
 /// Similar to the alignTo functions in MathExtras.h
@@ -522,10 +403,11 @@ inline constexpr TypeSize alignTo(TypeSize Size, uint64_t Align) {
           Size.isScalable()};
 }
 
-/// Stream operator function for `LinearPolySize`.
-template <typename LeafTy>
-inline raw_ostream &operator<<(raw_ostream &OS,
-                               const LinearPolySize<LeafTy> &PS) {
+/// Stream operator function for `FixedOrScalableQuantity`.
+template <typename LeafTy, typename ScalarTy>
+inline raw_ostream &
+operator<<(raw_ostream &OS,
+           const details::FixedOrScalableQuantity<LeafTy, ScalarTy> &PS) {
   PS.print(OS);
   return OS;
 }
@@ -544,7 +426,6 @@ template <> struct DenseMapInfo<ElementCount, void> {
 
     return HashVal;
   }
-
   static bool isEqual(const ElementCount &LHS, const ElementCount &RHS) {
     return LHS == RHS;
   }

diff  --git a/llvm/lib/IR/StructuralHash.cpp b/llvm/lib/IR/StructuralHash.cpp
index 5a6e074513268..b6b9fe72cc355 100644
--- a/llvm/lib/IR/StructuralHash.cpp
+++ b/llvm/lib/IR/StructuralHash.cpp
@@ -15,7 +15,6 @@
 
 using namespace llvm;
 
-namespace {
 namespace details {
 
 // Basic hashing mechanism to detect structural change to the IR, used to verify
@@ -67,16 +66,14 @@ class StructuralHash {
 
 } // namespace details
 
-} // namespace
-
 uint64_t llvm::StructuralHash(const Function &F) {
-  details::StructuralHash H;
+  ::details::StructuralHash H;
   H.update(F);
   return H.getHash();
 }
 
 uint64_t llvm::StructuralHash(const Module &M) {
-  details::StructuralHash H;
+  ::details::StructuralHash H;
   H.update(M);
   return H.getHash();
 }

diff  --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt
index 91c6c98748706..ccffb42e267eb 100644
--- a/llvm/unittests/Support/CMakeLists.txt
+++ b/llvm/unittests/Support/CMakeLists.txt
@@ -51,7 +51,6 @@ add_llvm_unittest(SupportTests
   JSONTest.cpp
   KnownBitsTest.cpp
   LEB128Test.cpp
-  LinearPolyBaseTest.cpp
   LineIteratorTest.cpp
   LockFileManagerTest.cpp
   MatchersTest.cpp

diff  --git a/llvm/unittests/Support/LinearPolyBaseTest.cpp b/llvm/unittests/Support/LinearPolyBaseTest.cpp
deleted file mode 100644
index 15b366210bca4..0000000000000
--- a/llvm/unittests/Support/LinearPolyBaseTest.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-//===- TestPoly3D.cpp - Poly3D unit tests------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/TypeSize.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-class Poly3D;
-
-namespace llvm {
-template <> struct LinearPolyBaseTypeTraits<Poly3D> {
-  using ScalarTy = int64_t;
-  static const unsigned Dimensions = 3;
-};
-}
-
-using Poly3DBase = LinearPolyBase<Poly3D>;
-class Poly3D : public Poly3DBase {
-public:
-  using ScalarTy = Poly3DBase::ScalarTy;
-  Poly3D(ScalarTy x, ScalarTy y, ScalarTy z) : Poly3DBase({x, y, z}) {}
-  Poly3D(const Poly3DBase &Convert) : Poly3DBase(Convert) {}
-};
-
-TEST(LinearPolyBase, Poly3D_isZero) {
-  EXPECT_TRUE(Poly3D(0, 0, 0).isZero());
-  EXPECT_TRUE(Poly3D(0, 0, 1).isNonZero());
-  EXPECT_TRUE(Poly3D(0, 0, 1));
-}
-
-TEST(LinearPolyBase, Poly3D_Equality) {
-  EXPECT_EQ(Poly3D(1, 2, 3), Poly3D(1, 2, 3));
-  EXPECT_NE(Poly3D(1, 2, 3), Poly3D(1, 2, 4));
-}
-
-TEST(LinearPolyBase, Poly3D_GetValue) {
-  EXPECT_EQ(Poly3D(1, 2, 3).getValue(0), 1);
-  EXPECT_EQ(Poly3D(1, 2, 3).getValue(1), 2);
-  EXPECT_EQ(Poly3D(1, 2, 3).getValue(2), 3);
-}
-
-TEST(LinearPolyBase, Poly3D_Add) {
-  // Test operator+
-  EXPECT_EQ(Poly3D(42, 0, 0) + Poly3D(0, 42, 0) + Poly3D(0, 0, 42),
-            Poly3D(42, 42, 42));
-
-  // Test operator+=
-  Poly3D X(42, 0, 0);
-  X += Poly3D(0, 42, 0);
-  X += Poly3D(0, 0, 42);
-  EXPECT_EQ(X, Poly3D(42, 42, 42));
-}
-
-TEST(LinearPolyBase, Poly3D_Sub) {
-  // Test operator-
-  EXPECT_EQ(Poly3D(42, 42, 42) - Poly3D(42, 0, 0) - Poly3D(0, 42, 0) -
-                Poly3D(0, 0, 42),
-            Poly3D(0, 0, 0));
-
-  // Test operator-=
-  Poly3D X(42, 42, 42);
-  X -= Poly3D(42, 0, 0);
-  X -= Poly3D(0, 42, 0);
-  X -= Poly3D(0, 0, 42);
-  EXPECT_EQ(X, Poly3D(0, 0, 0));
-}
-
-TEST(LinearPolyBase, Poly3D_Scale) {
-  // Test operator*
-  EXPECT_EQ(Poly3D(1, 2, 4) * 2, Poly3D(2, 4, 8));
-  EXPECT_EQ(Poly3D(1, 2, 4) * -2, Poly3D(-2, -4, -8));
-}
-
-TEST(LinearPolyBase, Poly3D_Invert) {
-  // Test operator-
-  EXPECT_EQ(-Poly3D(2, 4, 8), Poly3D(-2, -4, -8));
-}
-
-class Univariate3D;
-namespace llvm {
-template <> struct LinearPolyBaseTypeTraits<Univariate3D> {
-  using ScalarTy = int64_t;
-  static const unsigned Dimensions = 3;
-};
-}
-
-using Univariate3DBase = UnivariateLinearPolyBase<Univariate3D>;
-class Univariate3D : public Univariate3DBase {
-public:
-  using ScalarTy = Univariate3DBase::ScalarTy;
-  constexpr Univariate3D(ScalarTy x, unsigned Dim) : Univariate3DBase(x, Dim) {}
-  Univariate3D(const Univariate3DBase &Convert) : Univariate3DBase(Convert) {}
-};
-
-TEST(UnivariateLinearPolyBase, Univariate3D_isZero) {
-  EXPECT_TRUE(Univariate3D(0, 0).isZero());
-  EXPECT_TRUE(Univariate3D(0, 1).isZero());
-  EXPECT_TRUE(Univariate3D(0, 2).isZero());
-  EXPECT_TRUE(Univariate3D(1, 0).isNonZero());
-  EXPECT_TRUE(Univariate3D(1, 1).isNonZero());
-  EXPECT_TRUE(Univariate3D(1, 2).isNonZero());
-  EXPECT_TRUE(Univariate3D(1, 0));
-}
-
-TEST(UnivariateLinearPolyBase, Univariate3D_Equality) {
-  EXPECT_EQ(Univariate3D(1, 0), Univariate3D(1, 0));
-  EXPECT_NE(Univariate3D(1, 0), Univariate3D(1, 2));
-  EXPECT_NE(Univariate3D(1, 0), Univariate3D(1, 1));
-  EXPECT_NE(Univariate3D(1, 0), Univariate3D(2, 0));
-  EXPECT_NE(Univariate3D(1, 0), Univariate3D(0, 0));
-}
-
-TEST(UnivariateLinearPolyBase, Univariate3D_GetValue) {
-  EXPECT_EQ(Univariate3D(42, 0).getValue(0), 42);
-  EXPECT_EQ(Univariate3D(42, 0).getValue(1), 0);
-  EXPECT_EQ(Univariate3D(42, 0).getValue(2), 0);
-
-  EXPECT_EQ(Univariate3D(42, 1).getValue(0), 0);
-  EXPECT_EQ(Univariate3D(42, 1).getValue(1), 42);
-  EXPECT_EQ(Univariate3D(42, 1).getValue(2), 0);
-}
-
-TEST(UnivariateLinearPolyBase, Univariate3D_Add) {
-  // Test operator+
-  EXPECT_EQ(Univariate3D(42, 0) + Univariate3D(42, 0), Univariate3D(84, 0));
-  EXPECT_EQ(Univariate3D(42, 1) + Univariate3D(42, 1), Univariate3D(84, 1));
-  EXPECT_DEBUG_DEATH(Univariate3D(42, 0) + Univariate3D(42, 1),
-                     "Invalid dimensions");
-
-  // Test operator+=
-  Univariate3D X(42, 0);
-  X += Univariate3D(42, 0);
-  EXPECT_EQ(X, Univariate3D(84, 0));
-
-  // Test 'getWithIncrement' method
-  EXPECT_EQ(Univariate3D(42, 0).getWithIncrement(1), Univariate3D(43, 0));
-  EXPECT_EQ(Univariate3D(42, 1).getWithIncrement(2), Univariate3D(44, 1));
-  EXPECT_EQ(Univariate3D(42, 2).getWithIncrement(3), Univariate3D(45, 2));
-}
-
-TEST(UnivariateLinearPolyBase, Univariate3D_Sub) {
-  // Test operator+
-  EXPECT_EQ(Univariate3D(84, 0) - Univariate3D(42, 0), Univariate3D(42, 0));
-  EXPECT_EQ(Univariate3D(84, 1) - Univariate3D(42, 1), Univariate3D(42, 1));
-  EXPECT_DEBUG_DEATH(Univariate3D(84, 0) - Univariate3D(42, 1),
-                     "Invalid dimensions");
-
-  // Test operator+=
-  Univariate3D X(84, 0);
-  X -= Univariate3D(42, 0);
-  EXPECT_EQ(X, Univariate3D(42, 0));
-
-  // Test 'getWithDecrement' method
-  EXPECT_EQ(Univariate3D(43, 0).getWithDecrement(1), Univariate3D(42, 0));
-  EXPECT_EQ(Univariate3D(44, 1).getWithDecrement(2), Univariate3D(42, 1));
-  EXPECT_EQ(Univariate3D(45, 2).getWithDecrement(3), Univariate3D(42, 2));
-}
-
-TEST(UnivariateLinearPolyBase, Univariate3D_Scale) {
-  // Test operator*
-  EXPECT_EQ(Univariate3D(4, 0) * 2, Univariate3D(8, 0));
-  EXPECT_EQ(Univariate3D(4, 1) * -2, Univariate3D(-8, 1));
-}
-
-TEST(UnivariateLinearPolyBase, Univariate3D_Invert) {
-  // Test operator-
-  EXPECT_EQ(-Univariate3D(4, 0), Univariate3D(-4, 0));
-  EXPECT_EQ(-Univariate3D(4, 1), Univariate3D(-4, 1));
-}
-

diff  --git a/llvm/unittests/Support/TypeSizeTest.cpp b/llvm/unittests/Support/TypeSizeTest.cpp
index 3552c7949a9a0..6e566be375817 100644
--- a/llvm/unittests/Support/TypeSizeTest.cpp
+++ b/llvm/unittests/Support/TypeSizeTest.cpp
@@ -35,7 +35,7 @@ static_assert(!CEElementCountFixed3.isScalable());
 constexpr ElementCount CEElementCountScalable4 = ElementCount::getScalable(4);
 
 static_assert(CEElementCountScalable4.isScalable());
-static_assert(!ElementCount::getNull().isScalable());
+static_assert(!ElementCount().isScalable());
 static_assert(
     CEElementCountScalable4.hasKnownScalarFactor(ElementCount::getScalable(2)));
 static_assert(ElementCount::getScalable(8).getKnownScalarFactor(

diff  --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index 8c1b0997d8698..bbe04fc769f3d 100644
--- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -740,7 +740,7 @@ bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) {
   auto NoLength = [](const SmallDenseSet<ElementCount> &Lengths,
                      MVT T) -> bool {
     return !Lengths.count(T.isVector() ? T.getVectorElementCount()
-                                       : ElementCount::getNull());
+                                       : ElementCount());
   };
 
   SmallVector<unsigned, 4> Modes;
@@ -751,11 +751,9 @@ bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) {
 
     SmallDenseSet<ElementCount> VN, WN;
     for (MVT T : VS)
-      VN.insert(T.isVector() ? T.getVectorElementCount()
-                             : ElementCount::getNull());
+      VN.insert(T.isVector() ? T.getVectorElementCount() : ElementCount());
     for (MVT T : WS)
-      WN.insert(T.isVector() ? T.getVectorElementCount()
-                             : ElementCount::getNull());
+      WN.insert(T.isVector() ? T.getVectorElementCount() : ElementCount());
 
     Changed |= berase_if(VS, std::bind(NoLength, WN, std::placeholders::_1));
     Changed |= berase_if(WS, std::bind(NoLength, VN, std::placeholders::_1));


        


More information about the llvm-commits mailing list