[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