#include <string>
namespace llvm {
-class Deserializer;
class FoldingSetNodeID;
-class Serializer;
class StringRef;
class hash_code;
class raw_ostream;
APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t))
};
+ friend struct DenseMapAPIntKeyInfo;
+
/// \brief Fast internal constructor
///
/// This constructor is used only internally for speed of construction of
/// \brief Clear unused high order bits
///
- /// This method is used internally to clear the to "N" bits in the high order
+ /// 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.
/// Simply makes *this a copy of that.
/// @brief Copy Constructor.
APInt(const APInt &that) : BitWidth(that.BitWidth), VAL(0) {
- assert(BitWidth && "bitwidth too small");
if (isSingleWord())
VAL = that.VAL;
else
initSlowCase(that);
}
-#if LLVM_HAS_RVALUE_REFERENCES
/// \brief Move Constructor.
APInt(APInt &&that) : BitWidth(that.BitWidth), VAL(that.VAL) {
that.BitWidth = 0;
}
-#endif
/// \brief Destructor.
~APInt() {
/// This checks to see if the value of this APInt is the maximum signed
/// value for the APInt's bit width.
bool isMaxSignedValue() const {
- return BitWidth == 1 ? VAL == 0
- : !isNegative() && countPopulation() == BitWidth - 1;
+ return !isNegative() && countPopulation() == BitWidth - 1;
}
/// \brief Determine if this is the smallest unsigned value.
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
bool isMinSignedValue() const {
- return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2();
+ return isNegative() && isPowerOf2();
}
/// \brief Check if this APInt has an N-bits unsigned integer value.
: getZExtValue();
}
+ /// \brief Check if the APInt consists of a repeated bit pattern.
+ ///
+ /// e.g. 0x01010101 satisfies isSplat(8).
+ /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit
+ /// width without remainder.
+ bool isSplat(unsigned SplatSizeInBits) const;
+
/// @}
/// \name Value Generators
/// @{
return AssignSlowCase(RHS);
}
-#if LLVM_HAS_RVALUE_REFERENCES
/// @brief Move assignment operator.
APInt &operator=(APInt &&that) {
- if (!isSingleWord())
+ if (!isSingleWord()) {
+ // The MSVC STL shipped in 2013 requires that self move assignment be a
+ // no-op. Otherwise algorithms like stable_sort will produce answers
+ // where half of the output is left in a moved-from state.
+ if (this == &that)
+ return *this;
delete[] pVal;
+ }
- BitWidth = that.BitWidth;
- VAL = that.VAL;
+ // Use memcpy so that type based alias analysis sees both VAL and pVal
+ // as modified.
+ memcpy(&VAL, &that.VAL, sizeof(uint64_t));
+ // If 'this == &that', avoid zeroing our own bitwidth by storing to 'that'
+ // first.
+ unsigned ThatBitWidth = that.BitWidth;
that.BitWidth = 0;
+ BitWidth = ThatBitWidth;
return *this;
}
-#endif
/// \brief Assignment operator.
///
/// \brief Bitwise OR function.
///
- /// Performs a bitwise or on *this and RHS. This is implemented bny simply
+ /// Performs a bitwise or on *this and RHS. This is implemented by simply
/// calling operator|.
///
/// \returns An APInt value representing the bitwise OR of *this and RHS.
APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
APInt smul_ov(const APInt &RHS, bool &Overflow) const;
APInt umul_ov(const APInt &RHS, bool &Overflow) const;
- APInt sshl_ov(unsigned Amt, bool &Overflow) const;
+ APInt sshl_ov(const APInt &Amt, bool &Overflow) const;
+ APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
/// \brief Array-indexing support.
///
/// the validity of the less-than relationship.
///
/// \returns true if *this < RHS when considered unsigned.
- bool ult(uint64_t RHS) const { return ult(APInt(getBitWidth(), RHS)); }
+ bool ult(uint64_t RHS) const {
+ return getActiveBits() > 64 ? false : getZExtValue() < RHS;
+ }
/// \brief Signed less than comparison
///
/// the validity of the less-than relationship.
///
/// \returns true if *this < RHS when considered signed.
- bool slt(uint64_t RHS) const { return slt(APInt(getBitWidth(), RHS)); }
+ bool slt(int64_t RHS) const {
+ return getMinSignedBits() > 64 ? isNegative() : getSExtValue() < RHS;
+ }
/// \brief Unsigned less or equal comparison
///
/// the validity of the less-or-equal relationship.
///
/// \returns true if *this <= RHS when considered unsigned.
- bool ule(uint64_t RHS) const { return ule(APInt(getBitWidth(), RHS)); }
+ bool ule(uint64_t RHS) const { return !ugt(RHS); }
/// \brief Signed less or equal comparison
///
/// validity of the less-or-equal relationship.
///
/// \returns true if *this <= RHS when considered signed.
- bool sle(uint64_t RHS) const { return sle(APInt(getBitWidth(), RHS)); }
+ bool sle(uint64_t RHS) const { return !sgt(RHS); }
/// \brief Unsigned greather than comparison
///
/// the validity of the greater-than relationship.
///
/// \returns true if *this > RHS when considered unsigned.
- bool ugt(uint64_t RHS) const { return ugt(APInt(getBitWidth(), RHS)); }
+ bool ugt(uint64_t RHS) const {
+ return getActiveBits() > 64 ? true : getZExtValue() > RHS;
+ }
/// \brief Signed greather than comparison
///
/// the validity of the greater-than relationship.
///
/// \returns true if *this > RHS when considered signed.
- bool sgt(uint64_t RHS) const { return sgt(APInt(getBitWidth(), RHS)); }
+ bool sgt(int64_t RHS) const {
+ return getMinSignedBits() > 64 ? !isNegative() : getSExtValue() > RHS;
+ }
/// \brief Unsigned greater or equal comparison
///
/// the validity of the greater-or-equal relationship.
///
/// \returns true if *this >= RHS when considered unsigned.
- bool uge(uint64_t RHS) const { return uge(APInt(getBitWidth(), RHS)); }
+ bool uge(uint64_t RHS) const { return !ult(RHS); }
/// \brief Signed greather or equal comparison
///
/// the validity of the greater-or-equal relationship.
///
/// \returns true if *this >= RHS when considered signed.
- bool sge(uint64_t RHS) const { return sge(APInt(getBitWidth(), RHS)); }
+ bool sge(int64_t RHS) const { return !slt(RHS); }
/// This operation tests if there are any pairs of corresponding bits
/// between this APInt and RHS that are both set.
/// as "bitPosition".
void flipBit(unsigned bitPosition);
- /// \brief Returns true if the bit in bitPosition is set.
- bool extractBit(unsigned bitPosition) const;
-
/// @}
/// \name Value Characterization Functions
/// @{
/// \returns the number of words to hold the integer value with a given bit
/// width.
static unsigned getNumWords(unsigned BitWidth) {
- return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+ return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
}
/// \brief Compute the number of active bits in the value
/// \brief Count the number of leading one bits.
///
- /// This function is an APInt version of the countLeadingOnes_{32,64}
+ /// This function is an APInt version of the countLeadingOnes
/// functions in MathExtras.h. It counts the number of ones from the most
/// significant bit to the first zero bit.
///
/// \brief Count the number of trailing zero bits.
///
- /// This function is an APInt version of the countTrailingZeros_{32,64}
+ /// This function is an APInt version of the countTrailingZeros
/// functions in MathExtras.h. It counts the number of zeros from the least
/// significant bit to the first set bit.
///
/// \brief Count the number of trailing one bits.
///
- /// This function is an APInt version of the countTrailingOnes_{32,64}
+ /// This function is an APInt version of the countTrailingOnes
/// functions in MathExtras.h. It counts the number of ones from the least
/// significant bit to the first zero bit.
///
/// of ones from the least significant bit to the first zero bit.
unsigned countTrailingOnes() const {
if (isSingleWord())
- return CountTrailingOnes_64(VAL);
+ return llvm::countTrailingOnes(VAL);
return countTrailingOnesSlowCase();
}
/// \brief Count the number of bits set.
///
- /// This function is an APInt version of the countPopulation_{32,64} functions
+ /// This function is an APInt version of the countPopulation functions
/// in MathExtras.h. It counts the number of 1 bits in the APInt value.
///
/// \returns 0 if the value is zero, otherwise returns the number of set bits.
unsigned countPopulation() const {
if (isSingleWord())
- return CountPopulation_64(VAL);
+ return llvm::countPopulation(VAL);
return countPopulationSlowCase();
}
return BitWidth - (*this - 1).countLeadingZeros();
}
+ /// \returns the nearest log base 2 of this APInt. Ties round up.
+ ///
+ /// NOTE: When we have a BitWidth of 1, we define:
+ ///
+ /// log2(0) = UINT32_MAX
+ /// log2(1) = 0
+ ///
+ /// to get around any mathematical concerns resulting from
+ /// referencing 2 in a space where 2 does no exist.
+ unsigned nearestLogBase2() const {
+ // Special case when we have a bitwidth of 1. If VAL is 1, then we
+ // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to
+ // UINT32_MAX.
+ if (BitWidth == 1)
+ return VAL - 1;
+
+ // Handle the zero case.
+ if (!getBoolValue())
+ return UINT32_MAX;
+
+ // The non-zero case is handled by computing:
+ //
+ // nearestLogBase2(x) = logBase2(x) + x[logBase2(x)-1].
+ //
+ // where x[i] is referring to the value of the ith bit of x.
+ unsigned lg = logBase2();
+ return lg + unsigned((*this)[lg - 1]);
+ }
+
/// \returns the log base 2 of this APInt if its an exact power of two, -1
/// otherwise
int32_t exactLogBase2() const {