[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:43:55 PDT 2021
Thanks for the prompt fix! :-)
On Wed, Sep 8, 2021 at 4:35 PM Chris Lattner <clattner at nondot.org> wrote:
> Fixed in rG717ed1c31052, sorry for the breakage!
>
> -Chris
>
> On Sep 8, 2021, at 4:32 PM, Geoffrey Martin-Noble <gcmn at google.com> wrote:
>
> 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/fd4482e2/attachment-0001.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/fd4482e2/attachment-0001.bin>
More information about the llvm-commits
mailing list