[llvm] a024d35 - [APInt.h] Clean up the APInt interface. NFC.

Geoffrey Martin-Noble via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 8 16:32:41 PDT 2021


I'm seeing failures from this because clang uses APInt::needsCleanup in
Expr.cpp which was public before

```
llvm-project/clang/lib/AST/Expr.cpp:260:25: error: 'needsCleanup' is a
private member of 'llvm::APInt'
    if (!Value.getInt().needsCleanup())
                        ^
llvm-project/llvm/include/llvm/ADT/APInt.h:1994:8: note: declared private
here
  bool needsCleanup() const { return !isSingleWord(); }
```

On Wed, Sep 8, 2021 at 4:09 PM Chris Lattner via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

>
> Author: Chris Lattner
> Date: 2021-09-08T16:08:57-07:00
> New Revision: a024d35b3885490221e78b835b087a830cc3c325
>
> URL:
> https://github.com/llvm/llvm-project/commit/a024d35b3885490221e78b835b087a830cc3c325
> DIFF:
> https://github.com/llvm/llvm-project/commit/a024d35b3885490221e78b835b087a830cc3c325.diff
>
> LOG: [APInt.h] Clean up the APInt interface. NFC.
>
> This moves all the private implementation details to the bottom of
> the header, and pushes all the "make an APInt" stuff up to the top.
> This is in prep for making other changes to spiff up APInt a bit.
>
> Added:
>
>
> Modified:
>     llvm/include/llvm/ADT/APInt.h
>
> Removed:
>
>
>
>
> ################################################################################
> diff  --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
> index 68a229478c189..7ab49d23840a1 100644
> --- a/llvm/include/llvm/ADT/APInt.h
> +++ b/llvm/include/llvm/ADT/APInt.h
> @@ -87,176 +87,6 @@ class LLVM_NODISCARD APInt {
>
>    static constexpr WordType WORDTYPE_MAX = ~WordType(0);
>
> -private:
> -  /// This union is used to store the integer value. When the
> -  /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
> -  union {
> -    uint64_t VAL;   ///< Used to store the <= 64 bits integer value.
> -    uint64_t *pVal; ///< Used to store the >64 bits integer value.
> -  } U;
> -
> -  unsigned BitWidth; ///< The number of bits in this APInt.
> -
> -  friend struct DenseMapInfo<APInt>;
> -
> -  friend class APSInt;
> -
> -  /// Fast internal constructor
> -  ///
> -  /// This constructor is used only internally for speed of construction
> of
> -  /// temporaries. It is unsafe for general use so it is not public.
> -  APInt(uint64_t *val, unsigned bits) : BitWidth(bits) {
> -    U.pVal = val;
> -  }
> -
> -  /// Determine which word a bit is in.
> -  ///
> -  /// \returns the word position for the specified bit position.
> -  static unsigned whichWord(unsigned bitPosition) {
> -    return bitPosition / APINT_BITS_PER_WORD;
> -  }
> -
> -  /// Determine which bit in a word a bit is in.
> -  ///
> -  /// \returns the bit position in a word for the specified bit position
> -  /// in the APInt.
> -  static unsigned whichBit(unsigned bitPosition) {
> -    return bitPosition % APINT_BITS_PER_WORD;
> -  }
> -
> -  /// Get a single bit mask.
> -  ///
> -  /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set
> -  /// This method generates and returns a uint64_t (word) mask for a
> single
> -  /// bit at a specific bit position. This is used to mask the bit in the
> -  /// corresponding word.
> -  static uint64_t maskBit(unsigned bitPosition) {
> -    return 1ULL << whichBit(bitPosition);
> -  }
> -
> -  /// Clear unused high order bits
> -  ///
> -  /// This method is used internally to clear the top "N" bits in the
> high order
> -  /// word that are not used by the APInt. This is needed after the most
> -  /// significant word is assigned a value to ensure that those bits are
> -  /// zero'd out.
> -  APInt &clearUnusedBits() {
> -    // Compute how many bits are used in the final word
> -    unsigned WordBits = ((BitWidth-1) % APINT_BITS_PER_WORD) + 1;
> -
> -    // Mask out the high bits.
> -    uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - WordBits);
> -    if (isSingleWord())
> -      U.VAL &= mask;
> -    else
> -      U.pVal[getNumWords() - 1] &= mask;
> -    return *this;
> -  }
> -
> -  /// Get the word corresponding to a bit position
> -  /// \returns the corresponding word for the specified bit position.
> -  uint64_t getWord(unsigned bitPosition) const {
> -    return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
> -  }
> -
> -  /// Utility method to change the bit width of this APInt to new bit
> width,
> -  /// allocating and/or deallocating as necessary. There is no guarantee
> on the
> -  /// value of any bits upon return. Caller should populate the bits
> after.
> -  void reallocate(unsigned NewBitWidth);
> -
> -  /// Convert a char array into an APInt
> -  ///
> -  /// \param radix 2, 8, 10, 16, or 36
> -  /// Converts a string into a number.  The string must be non-empty
> -  /// and well-formed as a number of the given base. The bit-width
> -  /// must be sufficient to hold the result.
> -  ///
> -  /// This is used by the constructors that take string arguments.
> -  ///
> -  /// StringRef::getAsInteger is superficially similar but (1) does
> -  /// not assume that the string is well-formed and (2) grows the
> -  /// result to hold the input.
> -  void fromString(unsigned numBits, StringRef str, uint8_t radix);
> -
> -  /// An internal division function for dividing APInts.
> -  ///
> -  /// This is used by the toString method to divide by the radix. It
> simply
> -  /// provides a more convenient form of divide for internal use since
> KnuthDiv
> -  /// has specific constraints on its inputs. If those constraints are
> not met
> -  /// then it provides a simpler form of divide.
> -  static void divide(const WordType *LHS, unsigned lhsWords,
> -                     const WordType *RHS, unsigned rhsWords, WordType
> *Quotient,
> -                     WordType *Remainder);
> -
> -  /// out-of-line slow case for inline constructor
> -  void initSlowCase(uint64_t val, bool isSigned);
> -
> -  /// shared code between two array constructors
> -  void initFromArray(ArrayRef<uint64_t> array);
> -
> -  /// out-of-line slow case for inline copy constructor
> -  void initSlowCase(const APInt &that);
> -
> -  /// out-of-line slow case for shl
> -  void shlSlowCase(unsigned ShiftAmt);
> -
> -  /// out-of-line slow case for lshr.
> -  void lshrSlowCase(unsigned ShiftAmt);
> -
> -  /// out-of-line slow case for ashr.
> -  void ashrSlowCase(unsigned ShiftAmt);
> -
> -  /// out-of-line slow case for operator=
> -  void AssignSlowCase(const APInt &RHS);
> -
> -  /// out-of-line slow case for operator==
> -  bool EqualSlowCase(const APInt &RHS) const LLVM_READONLY;
> -
> -  /// out-of-line slow case for countLeadingZeros
> -  unsigned countLeadingZerosSlowCase() const LLVM_READONLY;
> -
> -  /// out-of-line slow case for countLeadingOnes.
> -  unsigned countLeadingOnesSlowCase() const LLVM_READONLY;
> -
> -  /// out-of-line slow case for countTrailingZeros.
> -  unsigned countTrailingZerosSlowCase() const LLVM_READONLY;
> -
> -  /// out-of-line slow case for countTrailingOnes
> -  unsigned countTrailingOnesSlowCase() const LLVM_READONLY;
> -
> -  /// out-of-line slow case for countPopulation
> -  unsigned countPopulationSlowCase() const LLVM_READONLY;
> -
> -  /// out-of-line slow case for intersects.
> -  bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;
> -
> -  /// out-of-line slow case for isSubsetOf.
> -  bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY;
> -
> -  /// out-of-line slow case for setBits.
> -  void setBitsSlowCase(unsigned loBit, unsigned hiBit);
> -
> -  /// out-of-line slow case for flipAllBits.
> -  void flipAllBitsSlowCase();
> -
> -  /// out-of-line slow case for operator&=.
> -  void AndAssignSlowCase(const APInt& RHS);
> -
> -  /// out-of-line slow case for operator|=.
> -  void OrAssignSlowCase(const APInt& RHS);
> -
> -  /// out-of-line slow case for operator^=.
> -  void XorAssignSlowCase(const APInt& RHS);
> -
> -  /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less
> than, equal
> -  /// to, or greater than RHS.
> -  int compare(const APInt &RHS) const LLVM_READONLY;
> -
> -  /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than,
> equal
> -  /// to, or greater than RHS.
> -  int compareSigned(const APInt &RHS) const LLVM_READONLY;
> -
> -public:
>    /// \name Constructors
>    /// @{
>
> @@ -312,7 +142,13 @@ class LLVM_NODISCARD APInt {
>    /// \param radix the radix to use for the conversion
>    APInt(unsigned numBits, StringRef str, uint8_t radix);
>
> -  /// Simply makes *this a copy of that.
> +  /// Default constructor that creates an uninteresting APInt
> +  /// representing a 1-bit zero value.
> +  ///
> +  /// This is useful for object deserialization (pair this with the static
> +  ///  method Read).
> +  explicit APInt() : BitWidth(1) { U.VAL = 0; }
> +
>    /// Copy Constructor.
>    APInt(const APInt &that) : BitWidth(that.BitWidth) {
>      if (isSingleWord())
> @@ -333,19 +169,135 @@ class LLVM_NODISCARD APInt {
>        delete[] U.pVal;
>    }
>
> -  /// Default constructor that creates an uninteresting APInt
> -  /// representing a 1-bit zero value.
> +  /// @}
> +  /// \name Value Generators
> +  /// @{
> +
> +  /// Get the '0' value.
>    ///
> -  /// This is useful for object deserialization (pair this with the static
> -  ///  method Read).
> -  explicit APInt() : BitWidth(1) { U.VAL = 0; }
> +  /// \returns the '0' value for an APInt of the specified bit-width.
> +  static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0);
> }
>
> -  /// Returns whether this instance allocated memory.
> -  bool needsCleanup() const { return !isSingleWord(); }
> +  /// Gets maximum unsigned value of APInt for specific bit width.
> +  static APInt getMaxValue(unsigned numBits) {
> +    return getAllOnesValue(numBits);
> +  }
>
> -  /// Used to insert APInt objects, or objects that contain APInt
> objects, into
> -  ///  FoldingSets.
> -  void Profile(FoldingSetNodeID &id) const;
> +  /// Gets maximum signed value of APInt for a specific bit width.
> +  static APInt getSignedMaxValue(unsigned numBits) {
> +    APInt API = getAllOnesValue(numBits);
> +    API.clearBit(numBits - 1);
> +    return API;
> +  }
> +
> +  /// Gets minimum unsigned value of APInt for a specific bit width.
> +  static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }
> +
> +  /// Gets minimum signed value of APInt for a specific bit width.
> +  static APInt getSignedMinValue(unsigned numBits) {
> +    APInt API(numBits, 0);
> +    API.setBit(numBits - 1);
> +    return API;
> +  }
> +
> +  /// Get the SignMask for a specific bit width.
> +  ///
> +  /// This is just a wrapper function of getSignedMinValue(), and it
> helps code
> +  /// readability when we want to get a SignMask.
> +  static APInt getSignMask(unsigned BitWidth) {
> +    return getSignedMinValue(BitWidth);
> +  }
> +
> +  /// Get the all-ones value.
> +  ///
> +  /// \returns the all-ones value for an APInt of the specified bit-width.
> +  static APInt getAllOnesValue(unsigned numBits) {
> +    return APInt(numBits, WORDTYPE_MAX, true);
> +  }
> +
> +  /// Return an APInt with exactly one bit set in the result.
> +  static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
> +    APInt Res(numBits, 0);
> +    Res.setBit(BitNo);
> +    return Res;
> +  }
> +
> +  /// Get a value with a block of bits set.
> +  ///
> +  /// Constructs an APInt value that has a contiguous range of bits set.
> The
> +  /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All
> other
> +  /// bits will be zero. For example, with parameters(32, 0, 16) you
> would get
> +  /// 0x0000FFFF. Please call getBitsSetWithWrap if \p loBit may be
> greater than
> +  /// \p hiBit.
> +  ///
> +  /// \param numBits the intended bit width of the result
> +  /// \param loBit the index of the lowest bit set.
> +  /// \param hiBit the index of the highest bit set.
> +  ///
> +  /// \returns An APInt value with the requested bits set.
> +  static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned
> hiBit) {
> +    assert(loBit <= hiBit && "loBit greater than hiBit");
> +    APInt Res(numBits, 0);
> +    Res.setBits(loBit, hiBit);
> +    return Res;
> +  }
> +
> +  /// Wrap version of getBitsSet.
> +  /// If \p hiBit is bigger than \p loBit, this is same with getBitsSet.
> +  /// If \p hiBit is not bigger than \p loBit, the set bits "wrap". For
> example,
> +  /// with parameters (32, 28, 4), you would get 0xF000000F.
> +  /// If \p hiBit is equal to \p loBit, you would get a result with all
> bits
> +  /// set.
> +  static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit,
> +                                  unsigned hiBit) {
> +    APInt Res(numBits, 0);
> +    Res.setBitsWithWrap(loBit, hiBit);
> +    return Res;
> +  }
> +
> +  /// Get a value with upper bits starting at loBit set.
> +  ///
> +  /// Constructs an APInt value that has a contiguous range of bits set.
> The
> +  /// bits from loBit (inclusive) to numBits (exclusive) will be set. All
> other
> +  /// bits will be zero. For example, with parameters(32, 12) you would
> get
> +  /// 0xFFFFF000.
> +  ///
> +  /// \param numBits the intended bit width of the result
> +  /// \param loBit the index of the lowest bit to set.
> +  ///
> +  /// \returns An APInt value with the requested bits set.
> +  static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {
> +    APInt Res(numBits, 0);
> +    Res.setBitsFrom(loBit);
> +    return Res;
> +  }
> +
> +  /// Get a value with high bits set
> +  ///
> +  /// Constructs an APInt value that has the top hiBitsSet bits set.
> +  ///
> +  /// \param numBits the bitwidth of the result
> +  /// \param hiBitsSet the number of high-order bits set in the result.
> +  static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
> +    APInt Res(numBits, 0);
> +    Res.setHighBits(hiBitsSet);
> +    return Res;
> +  }
> +
> +  /// Get a value with low bits set
> +  ///
> +  /// Constructs an APInt value that has the bottom loBitsSet bits set.
> +  ///
> +  /// \param numBits the bitwidth of the result
> +  /// \param loBitsSet the number of low-order bits set in the result.
> +  static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
> +    APInt Res(numBits, 0);
> +    Res.setLowBits(loBitsSet);
> +    return Res;
> +  }
> +
> +  /// Return a value containing V broadcasted over NewLen bits.
> +  static APInt getSplat(unsigned NewLen, const APInt &V);
>
>    /// @}
>    /// \name Value Tests
> @@ -373,7 +325,7 @@ class LLVM_NODISCARD APInt {
>    /// This tests the high bit of this APInt to determine if it is set.
>    ///
>    /// \returns true if this APInt has its sign bit set, false otherwise.
> -  bool isSignBitSet() const { return (*this)[BitWidth-1]; }
> +  bool isSignBitSet() const { return (*this)[BitWidth - 1]; }
>
>    /// Determine if sign bit of this APInt is clear.
>    ///
> @@ -453,13 +405,13 @@ class LLVM_NODISCARD APInt {
>
>    /// Check if this APInt has an N-bits unsigned integer value.
>    bool isIntN(unsigned N) const {
> -    assert(N && "N == 0 ???");
> +    assert(N && "0 bit APInt not supported");
>      return getActiveBits() <= N;
>    }
>
>    /// Check if this APInt has an N-bits signed integer value.
>    bool isSignedIntN(unsigned N) const {
> -    assert(N && "N == 0 ???");
> +    assert(N && "0 bit APInt not supported");
>      return getMinSignedBits() <= N;
>    }
>
> @@ -498,180 +450,50 @@ class LLVM_NODISCARD APInt {
>    /// \returns true if this APInt value is a sequence of \param numBits
> ones
>    /// starting at the least significant bit with the remainder zero.
>    bool isMask(unsigned numBits) const {
> -    assert(numBits != 0 && "numBits must be non-zero");
> -    assert(numBits <= BitWidth && "numBits out of range");
> -    if (isSingleWord())
> -      return U.VAL == (WORDTYPE_MAX >> (APINT_BITS_PER_WORD - numBits));
> -    unsigned Ones = countTrailingOnesSlowCase();
> -    return (numBits == Ones) &&
> -           ((Ones + countLeadingZerosSlowCase()) == BitWidth);
> -  }
> -
> -  /// \returns true if this APInt is a non-empty sequence of ones
> starting at
> -  /// the least significant bit with the remainder zero.
> -  /// Ex. isMask(0x0000FFFFU) == true.
> -  bool isMask() const {
> -    if (isSingleWord())
> -      return isMask_64(U.VAL);
> -    unsigned Ones = countTrailingOnesSlowCase();
> -    return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) ==
> BitWidth);
> -  }
> -
> -  /// Return true if this APInt value contains a sequence of ones with
> -  /// the remainder zero.
> -  bool isShiftedMask() const {
> -    if (isSingleWord())
> -      return isShiftedMask_64(U.VAL);
> -    unsigned Ones = countPopulationSlowCase();
> -    unsigned LeadZ = countLeadingZerosSlowCase();
> -    return (Ones + LeadZ + countTrailingZeros()) == BitWidth;
> -  }
> -
> -  /// @}
> -  /// \name Value Generators
> -  /// @{
> -
> -  /// Gets maximum unsigned value of APInt for specific bit width.
> -  static APInt getMaxValue(unsigned numBits) {
> -    return getAllOnesValue(numBits);
> -  }
> -
> -  /// Gets maximum signed value of APInt for a specific bit width.
> -  static APInt getSignedMaxValue(unsigned numBits) {
> -    APInt API = getAllOnesValue(numBits);
> -    API.clearBit(numBits - 1);
> -    return API;
> -  }
> -
> -  /// Gets minimum unsigned value of APInt for a specific bit width.
> -  static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }
> -
> -  /// Gets minimum signed value of APInt for a specific bit width.
> -  static APInt getSignedMinValue(unsigned numBits) {
> -    APInt API(numBits, 0);
> -    API.setBit(numBits - 1);
> -    return API;
> -  }
> -
> -  /// Get the SignMask for a specific bit width.
> -  ///
> -  /// This is just a wrapper function of getSignedMinValue(), and it
> helps code
> -  /// readability when we want to get a SignMask.
> -  static APInt getSignMask(unsigned BitWidth) {
> -    return getSignedMinValue(BitWidth);
> -  }
> -
> -  /// Get the all-ones value.
> -  ///
> -  /// \returns the all-ones value for an APInt of the specified bit-width.
> -  static APInt getAllOnesValue(unsigned numBits) {
> -    return APInt(numBits, WORDTYPE_MAX, true);
> -  }
> -
> -  /// Get the '0' value.
> -  ///
> -  /// \returns the '0' value for an APInt of the specified bit-width.
> -  static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0);
> }
> -
> -  /// Compute an APInt containing numBits highbits from this APInt.
> -  ///
> -  /// Get an APInt with the same BitWidth as this APInt, just zero mask
> -  /// the low bits and right shift to the least significant bit.
> -  ///
> -  /// \returns the high "numBits" bits of this APInt.
> -  APInt getHiBits(unsigned numBits) const;
> -
> -  /// Compute an APInt containing numBits lowbits from this APInt.
> -  ///
> -  /// Get an APInt with the same BitWidth as this APInt, just zero mask
> -  /// the high bits.
> -  ///
> -  /// \returns the low "numBits" bits of this APInt.
> -  APInt getLoBits(unsigned numBits) const;
> -
> -  /// Return an APInt with exactly one bit set in the result.
> -  static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
> -    APInt Res(numBits, 0);
> -    Res.setBit(BitNo);
> -    return Res;
> -  }
> -
> -  /// Get a value with a block of bits set.
> -  ///
> -  /// Constructs an APInt value that has a contiguous range of bits set.
> The
> -  /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All
> other
> -  /// bits will be zero. For example, with parameters(32, 0, 16) you
> would get
> -  /// 0x0000FFFF. Please call getBitsSetWithWrap if \p loBit may be
> greater than
> -  /// \p hiBit.
> -  ///
> -  /// \param numBits the intended bit width of the result
> -  /// \param loBit the index of the lowest bit set.
> -  /// \param hiBit the index of the highest bit set.
> -  ///
> -  /// \returns An APInt value with the requested bits set.
> -  static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned
> hiBit) {
> -    assert(loBit <= hiBit && "loBit greater than hiBit");
> -    APInt Res(numBits, 0);
> -    Res.setBits(loBit, hiBit);
> -    return Res;
> +    assert(numBits != 0 && "numBits must be non-zero");
> +    assert(numBits <= BitWidth && "numBits out of range");
> +    if (isSingleWord())
> +      return U.VAL == (WORDTYPE_MAX >> (APINT_BITS_PER_WORD - numBits));
> +    unsigned Ones = countTrailingOnesSlowCase();
> +    return (numBits == Ones) &&
> +           ((Ones + countLeadingZerosSlowCase()) == BitWidth);
>    }
>
> -  /// Wrap version of getBitsSet.
> -  /// If \p hiBit is bigger than \p loBit, this is same with getBitsSet.
> -  /// If \p hiBit is not bigger than \p loBit, the set bits "wrap". For
> example,
> -  /// with parameters (32, 28, 4), you would get 0xF000000F.
> -  /// If \p hiBit is equal to \p loBit, you would get a result with all
> bits
> -  /// set.
> -  static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit,
> -                                  unsigned hiBit) {
> -    APInt Res(numBits, 0);
> -    Res.setBitsWithWrap(loBit, hiBit);
> -    return Res;
> +  /// \returns true if this APInt is a non-empty sequence of ones
> starting at
> +  /// the least significant bit with the remainder zero.
> +  /// Ex. isMask(0x0000FFFFU) == true.
> +  bool isMask() const {
> +    if (isSingleWord())
> +      return isMask_64(U.VAL);
> +    unsigned Ones = countTrailingOnesSlowCase();
> +    return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) ==
> BitWidth);
>    }
>
> -  /// Get a value with upper bits starting at loBit set.
> -  ///
> -  /// Constructs an APInt value that has a contiguous range of bits set.
> The
> -  /// bits from loBit (inclusive) to numBits (exclusive) will be set. All
> other
> -  /// bits will be zero. For example, with parameters(32, 12) you would
> get
> -  /// 0xFFFFF000.
> -  ///
> -  /// \param numBits the intended bit width of the result
> -  /// \param loBit the index of the lowest bit to set.
> -  ///
> -  /// \returns An APInt value with the requested bits set.
> -  static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {
> -    APInt Res(numBits, 0);
> -    Res.setBitsFrom(loBit);
> -    return Res;
> +  /// Return true if this APInt value contains a sequence of ones with
> +  /// the remainder zero.
> +  bool isShiftedMask() const {
> +    if (isSingleWord())
> +      return isShiftedMask_64(U.VAL);
> +    unsigned Ones = countPopulationSlowCase();
> +    unsigned LeadZ = countLeadingZerosSlowCase();
> +    return (Ones + LeadZ + countTrailingZeros()) == BitWidth;
>    }
>
> -  /// Get a value with high bits set
> +  /// Compute an APInt containing numBits highbits from this APInt.
>    ///
> -  /// Constructs an APInt value that has the top hiBitsSet bits set.
> +  /// Get an APInt with the same BitWidth as this APInt, just zero mask
> +  /// the low bits and right shift to the least significant bit.
>    ///
> -  /// \param numBits the bitwidth of the result
> -  /// \param hiBitsSet the number of high-order bits set in the result.
> -  static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
> -    APInt Res(numBits, 0);
> -    Res.setHighBits(hiBitsSet);
> -    return Res;
> -  }
> +  /// \returns the high "numBits" bits of this APInt.
> +  APInt getHiBits(unsigned numBits) const;
>
> -  /// Get a value with low bits set
> +  /// Compute an APInt containing numBits lowbits from this APInt.
>    ///
> -  /// Constructs an APInt value that has the bottom loBitsSet bits set.
> +  /// Get an APInt with the same BitWidth as this APInt, just zero mask
> +  /// the high bits.
>    ///
> -  /// \param numBits the bitwidth of the result
> -  /// \param loBitsSet the number of low-order bits set in the result.
> -  static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
> -    APInt Res(numBits, 0);
> -    Res.setLowBits(loBitsSet);
> -    return Res;
> -  }
> -
> -  /// Return a value containing V broadcasted over NewLen bits.
> -  static APInt getSplat(unsigned NewLen, const APInt &V);
> +  /// \returns the low "numBits" bits of this APInt.
> +  APInt getLoBits(unsigned numBits) const;
>
>    /// Determine if two APInts have the same value, after zero-extending
>    /// one of them (if needed!) to ensure that the bit-widths match.
> @@ -827,7 +649,7 @@ class LLVM_NODISCARD APInt {
>        return *this;
>      }
>      U.pVal[0] &= RHS;
> -    memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
> +    memset(U.pVal + 1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
>      return *this;
>    }
>
> @@ -1449,9 +1271,7 @@ class LLVM_NODISCARD APInt {
>    }
>
>    /// Set the sign bit to 1.
> -  void setSignBit() {
> -    setBit(BitWidth - 1);
> -  }
> +  void setSignBit() { setBit(BitWidth - 1); }
>
>    /// Set a given bit to a given value.
>    void setBitVal(unsigned BitPosition, bool BitValue) {
> @@ -1497,14 +1317,10 @@ class LLVM_NODISCARD APInt {
>    }
>
>    /// Set the top bits starting from loBit.
> -  void setBitsFrom(unsigned loBit) {
> -    return setBits(loBit, BitWidth);
> -  }
> +  void setBitsFrom(unsigned loBit) { return setBits(loBit, BitWidth); }
>
>    /// Set the bottom loBits bits.
> -  void setLowBits(unsigned loBits) {
> -    return setBits(0, loBits);
> -  }
> +  void setLowBits(unsigned loBits) { return setBits(0, loBits); }
>
>    /// Set the top hiBits bits.
>    void setHighBits(unsigned hiBits) {
> @@ -1539,9 +1355,7 @@ class LLVM_NODISCARD APInt {
>    }
>
>    /// Set the sign bit to 0.
> -  void clearSignBit() {
> -    clearBit(BitWidth - 1);
> -  }
> +  void clearSignBit() { clearBit(BitWidth - 1); }
>
>    /// Toggle every bit to its opposite value.
>    void flipAllBits() {
> @@ -1774,9 +1588,7 @@ class LLVM_NODISCARD APInt {
>    /// The conversion does not do a translation from integer to double, it
> just
>    /// re-interprets the bits as a double. Note that it is valid to do
> this on
>    /// any bit width. Exactly 64 bits will be translated.
> -  double bitsToDouble() const {
> -    return BitsToDouble(getWord(0));
> -  }
> +  double bitsToDouble() const { return BitsToDouble(getWord(0)); }
>
>    /// Converts APInt bits to a float
>    ///
> @@ -1808,7 +1620,7 @@ class LLVM_NODISCARD APInt {
>    /// @{
>
>    /// \returns the floor log base 2 of this APInt.
> -  unsigned logBase2() const { return getActiveBits() -  1; }
> +  unsigned logBase2() const { return getActiveBits() - 1; }
>
>    /// \returns the ceil log base 2 of this APInt.
>    unsigned ceilLogBase2() const {
> @@ -1908,9 +1720,8 @@ class LLVM_NODISCARD APInt {
>    /// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least
>    /// significant bit of DST.  All high bits above srcBITS in DST are
>    /// zero-filled.
> -  static void tcExtract(WordType *, unsigned dstCount,
> -                        const WordType *, unsigned srcBits,
> -                        unsigned srcLSB);
> +  static void tcExtract(WordType *, unsigned dstCount, const WordType *,
> +                        unsigned srcBits, unsigned srcLSB);
>
>    /// Set the given bit of a bignum.  Zero-based.
>    static void tcSetBit(WordType *, unsigned bit);
> @@ -1927,14 +1738,13 @@ class LLVM_NODISCARD APInt {
>    static void tcNegate(WordType *, unsigned);
>
>    /// DST += RHS + CARRY where CARRY is zero or one.  Returns the carry
> flag.
> -  static WordType tcAdd(WordType *, const WordType *,
> -                        WordType carry, unsigned);
> +  static WordType tcAdd(WordType *, const WordType *, WordType carry,
> unsigned);
>    /// DST += RHS.  Returns the carry flag.
>    static WordType tcAddPart(WordType *, WordType, unsigned);
>
>    /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry
> flag.
> -  static WordType tcSubtract(WordType *, const WordType *,
> -                             WordType carry, unsigned);
> +  static WordType tcSubtract(WordType *, const WordType *, WordType carry,
> +                             unsigned);
>    /// DST -= RHS.  Returns the carry flag.
>    static WordType tcSubtractPart(WordType *, WordType, unsigned);
>
> @@ -1950,8 +1760,7 @@ class LLVM_NODISCARD APInt {
>    /// otherwise overflow occurred and return one.
>    static int tcMultiplyPart(WordType *dst, const WordType *src,
>                              WordType multiplier, WordType carry,
> -                            unsigned srcParts, unsigned dstParts,
> -                            bool add);
> +                            unsigned srcParts, unsigned dstParts, bool
> add);
>
>    /// DST = LHS * RHS, where DST has the same width as the operands and is
>    /// filled with the least significant parts of the result.  Returns one
> if
> @@ -1962,8 +1771,8 @@ class LLVM_NODISCARD APInt {
>
>    /// DST = LHS * RHS, where DST has width the sum of the widths of the
>    /// operands. No overflow occurs. DST must be disjoint from both
> operands.
> -  static void tcFullMultiply(WordType *, const WordType *,
> -                             const WordType *, unsigned, unsigned);
> +  static void tcFullMultiply(WordType *, const WordType *, const WordType
> *,
> +                             unsigned, unsigned);
>
>    /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
>    /// Otherwise set LHS to LHS / RHS with the fractional part discarded,
> set
> @@ -1974,9 +1783,8 @@ class LLVM_NODISCARD APInt {
>    /// SCRATCH is a bignum of the same size as the operands and result for
> use by
>    /// the routine; its contents need not be initialized and are
> destroyed.  LHS,
>    /// REMAINDER and SCRATCH must be distinct.
> -  static int tcDivide(WordType *lhs, const WordType *rhs,
> -                      WordType *remainder, WordType *scratch,
> -                      unsigned parts);
> +  static int tcDivide(WordType *lhs, const WordType *rhs, WordType
> *remainder,
> +                      WordType *scratch, unsigned parts);
>
>    /// Shift a bignum left Count bits. Shifted in bits are zero. There are
> no
>    /// restrictions on Count.
> @@ -2008,9 +1816,183 @@ class LLVM_NODISCARD APInt {
>    /// Set the least significant BITS and clear the rest.
>    static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned
> bits);
>
> +  /// Used to insert APInt objects, or objects that contain APInt
> objects, into
> +  ///  FoldingSets.
> +  void Profile(FoldingSetNodeID &id) const;
> +
>    /// debug method
>    void dump() const;
>
> +private:
> +  /// This union is used to store the integer value. When the
> +  /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
> +  union {
> +    uint64_t VAL;   ///< Used to store the <= 64 bits integer value.
> +    uint64_t *pVal; ///< Used to store the >64 bits integer value.
> +  } U;
> +
> +  unsigned BitWidth; ///< The number of bits in this APInt.
> +
> +  friend struct DenseMapInfo<APInt>;
> +
> +  friend class APSInt;
> +
> +  /// Fast internal constructor
> +  ///
> +  /// This constructor is used only internally for speed of construction
> of
> +  /// temporaries. It is unsafe for general use so it is not public.
> +  APInt(uint64_t *val, unsigned bits) : BitWidth(bits) { U.pVal = val; }
> +
> +  /// Determine which word a bit is in.
> +  ///
> +  /// \returns the word position for the specified bit position.
> +  static unsigned whichWord(unsigned bitPosition) {
> +    return bitPosition / APINT_BITS_PER_WORD;
> +  }
> +
> +  /// Determine which bit in a word a bit is in.
> +  ///
> +  /// \returns the bit position in a word for the specified bit position
> +  /// in the APInt.
> +  static unsigned whichBit(unsigned bitPosition) {
> +    return bitPosition % APINT_BITS_PER_WORD;
> +  }
> +
> +  /// Get a single bit mask.
> +  ///
> +  /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set
> +  /// This method generates and returns a uint64_t (word) mask for a
> single
> +  /// bit at a specific bit position. This is used to mask the bit in the
> +  /// corresponding word.
> +  static uint64_t maskBit(unsigned bitPosition) {
> +    return 1ULL << whichBit(bitPosition);
> +  }
> +
> +  /// Clear unused high order bits
> +  ///
> +  /// This method is used internally to clear the top "N" bits in the
> high order
> +  /// word that are not used by the APInt. This is needed after the most
> +  /// significant word is assigned a value to ensure that those bits are
> +  /// zero'd out.
> +  APInt &clearUnusedBits() {
> +    // Compute how many bits are used in the final word
> +    unsigned WordBits = ((BitWidth - 1) % APINT_BITS_PER_WORD) + 1;
> +
> +    // Mask out the high bits.
> +    uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - WordBits);
> +    if (isSingleWord())
> +      U.VAL &= mask;
> +    else
> +      U.pVal[getNumWords() - 1] &= mask;
> +    return *this;
> +  }
> +
> +  /// Get the word corresponding to a bit position
> +  /// \returns the corresponding word for the specified bit position.
> +  uint64_t getWord(unsigned bitPosition) const {
> +    return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
> +  }
> +
> +  /// Utility method to change the bit width of this APInt to new bit
> width,
> +  /// allocating and/or deallocating as necessary. There is no guarantee
> on the
> +  /// value of any bits upon return. Caller should populate the bits
> after.
> +  void reallocate(unsigned NewBitWidth);
> +
> +  /// Convert a char array into an APInt
> +  ///
> +  /// \param radix 2, 8, 10, 16, or 36
> +  /// Converts a string into a number.  The string must be non-empty
> +  /// and well-formed as a number of the given base. The bit-width
> +  /// must be sufficient to hold the result.
> +  ///
> +  /// This is used by the constructors that take string arguments.
> +  ///
> +  /// StringRef::getAsInteger is superficially similar but (1) does
> +  /// not assume that the string is well-formed and (2) grows the
> +  /// result to hold the input.
> +  void fromString(unsigned numBits, StringRef str, uint8_t radix);
> +
> +  /// An internal division function for dividing APInts.
> +  ///
> +  /// This is used by the toString method to divide by the radix. It
> simply
> +  /// provides a more convenient form of divide for internal use since
> KnuthDiv
> +  /// has specific constraints on its inputs. If those constraints are
> not met
> +  /// then it provides a simpler form of divide.
> +  static void divide(const WordType *LHS, unsigned lhsWords,
> +                     const WordType *RHS, unsigned rhsWords, WordType
> *Quotient,
> +                     WordType *Remainder);
> +
> +  /// out-of-line slow case for inline constructor
> +  void initSlowCase(uint64_t val, bool isSigned);
> +
> +  /// shared code between two array constructors
> +  void initFromArray(ArrayRef<uint64_t> array);
> +
> +  /// out-of-line slow case for inline copy constructor
> +  void initSlowCase(const APInt &that);
> +
> +  /// out-of-line slow case for shl
> +  void shlSlowCase(unsigned ShiftAmt);
> +
> +  /// out-of-line slow case for lshr.
> +  void lshrSlowCase(unsigned ShiftAmt);
> +
> +  /// out-of-line slow case for ashr.
> +  void ashrSlowCase(unsigned ShiftAmt);
> +
> +  /// out-of-line slow case for operator=
> +  void AssignSlowCase(const APInt &RHS);
> +
> +  /// out-of-line slow case for operator==
> +  bool EqualSlowCase(const APInt &RHS) const LLVM_READONLY;
> +
> +  /// out-of-line slow case for countLeadingZeros
> +  unsigned countLeadingZerosSlowCase() const LLVM_READONLY;
> +
> +  /// out-of-line slow case for countLeadingOnes.
> +  unsigned countLeadingOnesSlowCase() const LLVM_READONLY;
> +
> +  /// out-of-line slow case for countTrailingZeros.
> +  unsigned countTrailingZerosSlowCase() const LLVM_READONLY;
> +
> +  /// out-of-line slow case for countTrailingOnes
> +  unsigned countTrailingOnesSlowCase() const LLVM_READONLY;
> +
> +  /// out-of-line slow case for countPopulation
> +  unsigned countPopulationSlowCase() const LLVM_READONLY;
> +
> +  /// out-of-line slow case for intersects.
> +  bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;
> +
> +  /// out-of-line slow case for isSubsetOf.
> +  bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY;
> +
> +  /// out-of-line slow case for setBits.
> +  void setBitsSlowCase(unsigned loBit, unsigned hiBit);
> +
> +  /// out-of-line slow case for flipAllBits.
> +  void flipAllBitsSlowCase();
> +
> +  /// out-of-line slow case for operator&=.
> +  void AndAssignSlowCase(const APInt &RHS);
> +
> +  /// out-of-line slow case for operator|=.
> +  void OrAssignSlowCase(const APInt &RHS);
> +
> +  /// out-of-line slow case for operator^=.
> +  void XorAssignSlowCase(const APInt &RHS);
> +
> +  /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less
> than, equal
> +  /// to, or greater than RHS.
> +  int compare(const APInt &RHS) const LLVM_READONLY;
> +
> +  /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than,
> equal
> +  /// to, or greater than RHS.
> +  int compareSigned(const APInt &RHS) const LLVM_READONLY;
> +
> +  /// Returns whether this instance allocated memory.
> +  bool needsCleanup() const { return !isSingleWord(); }
> +
>    /// @}
>  };
>
> @@ -2161,7 +2143,6 @@ inline APInt operator*(uint64_t LHS, APInt b) {
>    return b;
>  }
>
> -
>  namespace APIntOps {
>
>  /// Determine the smaller of two APInts considered to be signed.
> @@ -2277,7 +2258,7 @@ Optional<APInt> SolveQuadraticEquationWrap(APInt A,
> APInt B, APInt C,
>  Optional<unsigned> GetMostSignificantDifferentBit(const APInt &A,
>                                                    const APInt &B);
>
> -} // End of APIntOps namespace
> +} // namespace APIntOps
>
>  // See friend declaration above. This additional declaration is required
> in
>  // order to compile LLVM with IBM xlC compiler.
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210908/35852606/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3992 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210908/35852606/attachment.bin>


More information about the llvm-commits mailing list