aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ADT/APInt.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT/APInt.h')
-rw-r--r--include/llvm/ADT/APInt.h135
1 files changed, 69 insertions, 66 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 6d74f344aad5..63c92c1a7fce 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -86,7 +86,7 @@ private:
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.
@@ -98,7 +98,9 @@ private:
///
/// 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) : pVal(val), BitWidth(bits) {}
+ APInt(uint64_t *val, unsigned bits) : BitWidth(bits) {
+ U.pVal = val;
+ }
/// \brief Determine if this APInt just has one word to store value.
///
@@ -143,16 +145,16 @@ private:
// Mask out the high bits.
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - WordBits);
if (isSingleWord())
- VAL &= mask;
+ U.VAL &= mask;
else
- pVal[getNumWords() - 1] &= mask;
+ U.pVal[getNumWords() - 1] &= mask;
return *this;
}
/// \brief 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() ? VAL : pVal[whichWord(bitPosition)];
+ return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
}
/// \brief Convert a char array into an APInt
@@ -258,7 +260,7 @@ public:
: BitWidth(numBits) {
assert(BitWidth && "bitwidth too small");
if (isSingleWord()) {
- VAL = val;
+ U.VAL = val;
clearUnusedBits();
} else {
initSlowCase(val, isSigned);
@@ -300,20 +302,21 @@ public:
/// @brief Copy Constructor.
APInt(const APInt &that) : BitWidth(that.BitWidth) {
if (isSingleWord())
- VAL = that.VAL;
+ U.VAL = that.U.VAL;
else
initSlowCase(that);
}
/// \brief Move Constructor.
- APInt(APInt &&that) : VAL(that.VAL), BitWidth(that.BitWidth) {
+ APInt(APInt &&that) : BitWidth(that.BitWidth) {
+ memcpy(&U, &that.U, sizeof(U));
that.BitWidth = 0;
}
/// \brief Destructor.
~APInt() {
if (needsCleanup())
- delete[] pVal;
+ delete[] U.pVal;
}
/// \brief Default constructor that creates an uninteresting APInt
@@ -321,7 +324,7 @@ public:
///
/// This is useful for object deserialization (pair this with the static
/// method Read).
- explicit APInt() : VAL(0), BitWidth(1) {}
+ explicit APInt() : BitWidth(1) { U.VAL = 0; }
/// \brief Returns whether this instance allocated memory.
bool needsCleanup() const { return !isSingleWord(); }
@@ -373,7 +376,7 @@ public:
/// This checks to see if the value has all bits of the APInt are set or not.
bool isAllOnesValue() const {
if (isSingleWord())
- return VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth);
+ return U.VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth);
return countPopulationSlowCase() == BitWidth;
}
@@ -428,7 +431,7 @@ public:
/// \returns true if the argument APInt value is a power of two > 0.
bool isPowerOf2() const {
if (isSingleWord())
- return isPowerOf2_64(VAL);
+ return isPowerOf2_64(U.VAL);
return countPopulationSlowCase() == 1;
}
@@ -461,7 +464,7 @@ public:
assert(numBits != 0 && "numBits must be non-zero");
assert(numBits <= BitWidth && "numBits out of range");
if (isSingleWord())
- return VAL == (WORD_MAX >> (APINT_BITS_PER_WORD - numBits));
+ return U.VAL == (WORD_MAX >> (APINT_BITS_PER_WORD - numBits));
unsigned Ones = countTrailingOnesSlowCase();
return (numBits == Ones) &&
((Ones + countLeadingZerosSlowCase()) == BitWidth);
@@ -472,7 +475,7 @@ public:
/// Ex. isMask(0x0000FFFFU) == true.
bool isMask() const {
if (isSingleWord())
- return isMask_64(VAL);
+ return isMask_64(U.VAL);
unsigned Ones = countTrailingOnesSlowCase();
return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);
}
@@ -481,7 +484,7 @@ public:
/// the remainder zero.
bool isShiftedMask() const {
if (isSingleWord())
- return isShiftedMask_64(VAL);
+ return isShiftedMask_64(U.VAL);
unsigned Ones = countPopulationSlowCase();
unsigned LeadZ = countLeadingZerosSlowCase();
return (Ones + LeadZ + countTrailingZeros()) == BitWidth;
@@ -639,8 +642,8 @@ public:
/// conversions.
const uint64_t *getRawData() const {
if (isSingleWord())
- return &VAL;
- return &pVal[0];
+ return &U.VAL;
+ return &U.pVal[0];
}
/// @}
@@ -686,7 +689,7 @@ public:
/// \returns true if *this is zero, false otherwise.
bool operator!() const {
if (isSingleWord())
- return VAL == 0;
+ return U.VAL == 0;
return countLeadingZerosSlowCase() == BitWidth;
}
@@ -700,7 +703,7 @@ public:
APInt &operator=(const APInt &RHS) {
// If the bitwidths are the same, we can avoid mucking with memory
if (isSingleWord() && RHS.isSingleWord()) {
- VAL = RHS.VAL;
+ U.VAL = RHS.U.VAL;
BitWidth = RHS.BitWidth;
return clearUnusedBits();
}
@@ -713,11 +716,11 @@ public:
APInt &operator=(APInt &&that) {
assert(this != &that && "Self-move not supported");
if (!isSingleWord())
- delete[] pVal;
+ delete[] U.pVal;
// Use memcpy so that type based alias analysis sees both VAL and pVal
// as modified.
- memcpy(&VAL, &that.VAL, sizeof(uint64_t));
+ memcpy(&U, &that.U, sizeof(U));
BitWidth = that.BitWidth;
that.BitWidth = 0;
@@ -734,11 +737,11 @@ public:
/// \returns *this after assignment of RHS value.
APInt &operator=(uint64_t RHS) {
if (isSingleWord()) {
- VAL = RHS;
+ U.VAL = RHS;
clearUnusedBits();
} else {
- pVal[0] = RHS;
- memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ U.pVal[0] = RHS;
+ memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
}
return *this;
}
@@ -752,7 +755,7 @@ public:
APInt &operator&=(const APInt &RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL &= RHS.VAL;
+ U.VAL &= RHS.U.VAL;
else
AndAssignSlowCase(RHS);
return *this;
@@ -765,11 +768,11 @@ public:
/// the LHS.
APInt &operator&=(uint64_t RHS) {
if (isSingleWord()) {
- VAL &= RHS;
+ U.VAL &= RHS;
return *this;
}
- pVal[0] &= RHS;
- memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ U.pVal[0] &= RHS;
+ memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
return *this;
}
@@ -782,7 +785,7 @@ public:
APInt &operator|=(const APInt &RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL |= RHS.VAL;
+ U.VAL |= RHS.U.VAL;
else
OrAssignSlowCase(RHS);
return *this;
@@ -795,10 +798,10 @@ public:
/// the LHS.
APInt &operator|=(uint64_t RHS) {
if (isSingleWord()) {
- VAL |= RHS;
+ U.VAL |= RHS;
clearUnusedBits();
} else {
- pVal[0] |= RHS;
+ U.pVal[0] |= RHS;
}
return *this;
}
@@ -812,7 +815,7 @@ public:
APInt &operator^=(const APInt &RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- VAL ^= RHS.VAL;
+ U.VAL ^= RHS.U.VAL;
else
XorAssignSlowCase(RHS);
return *this;
@@ -825,10 +828,10 @@ public:
/// the LHS.
APInt &operator^=(uint64_t RHS) {
if (isSingleWord()) {
- VAL ^= RHS;
+ U.VAL ^= RHS;
clearUnusedBits();
} else {
- pVal[0] ^= RHS;
+ U.pVal[0] ^= RHS;
}
return *this;
}
@@ -865,9 +868,9 @@ public:
assert(ShiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
if (ShiftAmt == BitWidth)
- VAL = 0;
+ U.VAL = 0;
else
- VAL <<= ShiftAmt;
+ U.VAL <<= ShiftAmt;
return clearUnusedBits();
}
shlSlowCase(ShiftAmt);
@@ -913,11 +916,11 @@ public:
void ashrInPlace(unsigned ShiftAmt) {
assert(ShiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
- int64_t SExtVAL = SignExtend64(VAL, BitWidth);
+ int64_t SExtVAL = SignExtend64(U.VAL, BitWidth);
if (ShiftAmt == BitWidth)
- VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
+ U.VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
else
- VAL = SExtVAL >> ShiftAmt;
+ U.VAL = SExtVAL >> ShiftAmt;
clearUnusedBits();
return;
}
@@ -938,9 +941,9 @@ public:
assert(ShiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
if (ShiftAmt == BitWidth)
- VAL = 0;
+ U.VAL = 0;
else
- VAL >>= ShiftAmt;
+ U.VAL >>= ShiftAmt;
return;
}
lshrSlowCase(ShiftAmt);
@@ -1059,7 +1062,7 @@ public:
bool operator[](unsigned bitPosition) const {
assert(bitPosition < getBitWidth() && "Bit position out of bounds!");
return (maskBit(bitPosition) &
- (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) !=
+ (isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)])) !=
0;
}
@@ -1074,7 +1077,7 @@ public:
bool operator==(const APInt &RHS) const {
assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
if (isSingleWord())
- return VAL == RHS.VAL;
+ return U.VAL == RHS.U.VAL;
return EqualSlowCase(RHS);
}
@@ -1265,7 +1268,7 @@ public:
bool intersects(const APInt &RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- return (VAL & RHS.VAL) != 0;
+ return (U.VAL & RHS.U.VAL) != 0;
return intersectsSlowCase(RHS);
}
@@ -1273,7 +1276,7 @@ public:
bool isSubsetOf(const APInt &RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
- return (VAL & ~RHS.VAL) == 0;
+ return (U.VAL & ~RHS.U.VAL) == 0;
return isSubsetOfSlowCase(RHS);
}
@@ -1333,10 +1336,10 @@ public:
/// \brief Set every bit to 1.
void setAllBits() {
if (isSingleWord())
- VAL = WORD_MAX;
+ U.VAL = WORD_MAX;
else
// Set all the bits in all the words.
- memset(pVal, -1, getNumWords() * APINT_WORD_SIZE);
+ memset(U.pVal, -1, getNumWords() * APINT_WORD_SIZE);
// Clear the unused ones
clearUnusedBits();
}
@@ -1348,9 +1351,9 @@ public:
assert(BitPosition <= BitWidth && "BitPosition out of range");
WordType Mask = maskBit(BitPosition);
if (isSingleWord())
- VAL |= Mask;
+ U.VAL |= Mask;
else
- pVal[whichWord(BitPosition)] |= Mask;
+ U.pVal[whichWord(BitPosition)] |= Mask;
}
/// Set the sign bit to 1.
@@ -1369,9 +1372,9 @@ public:
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
mask <<= loBit;
if (isSingleWord())
- VAL |= mask;
+ U.VAL |= mask;
else
- pVal[0] |= mask;
+ U.pVal[0] |= mask;
} else {
setBitsSlowCase(loBit, hiBit);
}
@@ -1395,9 +1398,9 @@ public:
/// \brief Set every bit to 0.
void clearAllBits() {
if (isSingleWord())
- VAL = 0;
+ U.VAL = 0;
else
- memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
+ memset(U.pVal, 0, getNumWords() * APINT_WORD_SIZE);
}
/// \brief Set a given bit to 0.
@@ -1407,9 +1410,9 @@ public:
assert(BitPosition <= BitWidth && "BitPosition out of range");
WordType Mask = ~maskBit(BitPosition);
if (isSingleWord())
- VAL &= Mask;
+ U.VAL &= Mask;
else
- pVal[whichWord(BitPosition)] &= Mask;
+ U.pVal[whichWord(BitPosition)] &= Mask;
}
/// Set the sign bit to 0.
@@ -1420,7 +1423,7 @@ public:
/// \brief Toggle every bit to its opposite value.
void flipAllBits() {
if (isSingleWord()) {
- VAL ^= WORD_MAX;
+ U.VAL ^= WORD_MAX;
clearUnusedBits();
} else {
flipAllBitsSlowCase();
@@ -1500,9 +1503,9 @@ public:
/// uint64_t. Otherwise an assertion will result.
uint64_t getZExtValue() const {
if (isSingleWord())
- return VAL;
+ return U.VAL;
assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
- return pVal[0];
+ return U.pVal[0];
}
/// \brief Get sign extended value
@@ -1512,9 +1515,9 @@ public:
/// int64_t. Otherwise an assertion will result.
int64_t getSExtValue() const {
if (isSingleWord())
- return SignExtend64(VAL, BitWidth);
+ return SignExtend64(U.VAL, BitWidth);
assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
- return int64_t(pVal[0]);
+ return int64_t(U.pVal[0]);
}
/// \brief Get bits required for string value.
@@ -1534,7 +1537,7 @@ public:
unsigned countLeadingZeros() const {
if (isSingleWord()) {
unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
- return llvm::countLeadingZeros(VAL) - unusedBits;
+ return llvm::countLeadingZeros(U.VAL) - unusedBits;
}
return countLeadingZerosSlowCase();
}
@@ -1575,7 +1578,7 @@ public:
/// of ones from the least significant bit to the first zero bit.
unsigned countTrailingOnes() const {
if (isSingleWord())
- return llvm::countTrailingOnes(VAL);
+ return llvm::countTrailingOnes(U.VAL);
return countTrailingOnesSlowCase();
}
@@ -1587,7 +1590,7 @@ public:
/// \returns 0 if the value is zero, otherwise returns the number of set bits.
unsigned countPopulation() const {
if (isSingleWord())
- return llvm::countPopulation(VAL);
+ return llvm::countPopulation(U.VAL);
return countPopulationSlowCase();
}
@@ -1646,7 +1649,7 @@ public:
uint64_t I;
double D;
} T;
- T.I = (isSingleWord() ? VAL : pVal[0]);
+ T.I = (isSingleWord() ? U.VAL : U.pVal[0]);
return T.D;
}
@@ -1660,7 +1663,7 @@ public:
unsigned I;
float F;
} T;
- T.I = unsigned((isSingleWord() ? VAL : pVal[0]));
+ T.I = unsigned((isSingleWord() ? U.VAL : U.pVal[0]));
return T.F;
}
@@ -1718,7 +1721,7 @@ public:
// get 0. If VAL is 0, we get WORD_MAX which gets truncated to
// UINT32_MAX.
if (BitWidth == 1)
- return VAL - 1;
+ return U.VAL - 1;
// Handle the zero case.
if (isNullValue())