Implement countLeadingOnes() and getMinSignedBits(). This helps to minimize
authorReid Spencer <rspencer@reidspencer.com>
Tue, 27 Feb 2007 21:59:26 +0000 (21:59 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Tue, 27 Feb 2007 21:59:26 +0000 (21:59 +0000)
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

include/llvm/ADT/APInt.h
lib/Support/APInt.cpp

index 936be5fbd638a1a5e4fb24853d21f935cd19b40c..51b595b4560571a58014afbe8c47f9cb365f1c02 100644 (file)
@@ -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.
index acc9de295b40bd5864a75c4d1d3bf4ffa8b0a644..c13c59e3dbd1894e6dffd68831c9ef267de7e8a1 100644 (file)
@@ -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