aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-02-27 21:59:26 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-02-27 21:59:26 +0000
commit681dcd14e9d59c2070e3a298328db9aea6069480 (patch)
tree4aafeb60a49d78d286effd129e14dbf66ab0457b
parent3fae29acef408d999914406a77c140b28f8ed91e (diff)
Implement countLeadingOnes() and getMinSignedBits(). This helps to minimize
the bit width of negative numbers by computing the minimum bit width for a negative value. E.g. 0x1800000000000000 could be just 0x8000000000000000 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34695 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/APInt.h15
-rw-r--r--lib/Support/APInt.cpp35
2 files changed, 48 insertions, 2 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 936be5fbd6..51b595b456 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -446,6 +446,12 @@ public:
return BitWidth - countLeadingZeros();
}
+ inline uint32_t getMinSignedBits() const {
+ if (isNegative())
+ return BitWidth - countLeadingOnes() + 1;
+ return getActiveBits();
+ }
+
/// This method attempts to return the value of this APInt as a zero extended
/// uint64_t. The bitwidth must be <= 64 or the value must fit within a
/// uint64_t. Otherwise an assertion will result.
@@ -587,9 +593,16 @@ public:
/// @returns getNumWords() * APINT_BITS_PER_WORD if the value is zero.
/// @returns the number of zeros from the most significant bit to the first
/// one bits.
- /// @brief Count the number of trailing one bits.
+ /// @brief Count the number of leading one bits.
uint32_t countLeadingZeros() const;
+ /// countLeadingOnes - This function counts the number of contiguous 1 bits
+ /// in the high order bits. The count stops when the first 0 bit is reached.
+ /// @returns 0 if the high order bit is not set
+ /// @returns the number of 1 bits from the most significant to the least
+ /// @brief Count the number of leading one bits.
+ uint32_t countLeadingOnes() const;
+
/// countTrailingZeros - This function is an APInt version of the
/// countTrailingZoers_{32,64} functions in MathExtras.h. It counts
/// the number of zeros from the least significant bit to the first one bit.
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index acc9de295b..c13c59e3db 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -702,6 +702,38 @@ uint32_t APInt::countLeadingZeros() const {
return Count;
}
+static uint32_t countLeadingOnes_64(uint64_t V, uint32_t skip) {
+ uint32_t Count = 0;
+ if (skip)
+ V <<= skip;
+ while (V && (V & (1ULL << 63))) {
+ Count++;
+ V <<= 1;
+ }
+ return Count;
+}
+
+uint32_t APInt::countLeadingOnes() const {
+ if (isSingleWord())
+ return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth);
+
+ uint32_t highWordBits = BitWidth % APINT_BITS_PER_WORD;
+ uint32_t shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits);
+ int i = getNumWords() - 1;
+ uint32_t Count = countLeadingOnes_64(pVal[i], shift);
+ if (Count == highWordBits) {
+ for (i--; i >= 0; --i) {
+ if (pVal[i] == -1ULL)
+ Count += APINT_BITS_PER_WORD;
+ else {
+ Count += countLeadingOnes_64(pVal[i], 0);
+ break;
+ }
+ }
+ }
+ return Count;
+}
+
uint32_t APInt::countTrailingZeros() const {
if (isSingleWord())
return CountTrailingZeros_64(VAL);
@@ -1701,6 +1733,7 @@ void APInt::dump() const
else for (unsigned i = getNumWords(); i > 0; i--) {
cerr << pVal[i-1] << " ";
}
- cerr << " (" << this->toString(10) << ")\n" << std::setbase(10);
+ cerr << " U(" << this->toString(10) << ") S(" << this->toStringSigned(10)
+ << ")\n" << std::setbase(10);
}
#endif