Avoid creating a redundant zero APInt.
[oota-llvm.git] / lib / Support / APInt.cpp
index 7af0101ece81d8247f0ab1e5ee0c0731bcc66988..38b379005af0f77a910b5ba3accc4b82f37555f4 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Sheng Zhou and is distributed under the 
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -14,7 +14,7 @@
 
 #define DEBUG_TYPE "apint"
 #include "llvm/ADT/APInt.h"
-#include "llvm/DerivedTypes.h"
+#include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
 #include <math.h>
 
 using namespace llvm;
 
+/// This enumeration just provides for internal constants used in this
+/// translation unit. 
+enum {
+  MIN_INT_BITS = 1,        ///< Minimum number of bits that can be specified
+  ///< Note that this must remain synchronized with IntegerType::MIN_INT_BITS
+  MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
+  ///< Note that this must remain synchronized with IntegerType::MAX_INT_BITS
+};
+
 /// A utility function for allocating memory, checking for allocation failures,
 /// and ensuring the contents are zeroed.
 inline static uint64_t* getClearedMemory(uint32_t numWords) {
@@ -44,8 +53,8 @@ inline static uint64_t* getMemory(uint32_t numWords) {
 
 APInt::APInt(uint32_t numBits, uint64_t val, bool isSigned) 
   : BitWidth(numBits), VAL(0) {
-  assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
-  assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
+  assert(BitWidth >= MIN_INT_BITS && "bitwidth too small");
+  assert(BitWidth <= MAX_INT_BITS && "bitwidth too large");
   if (isSingleWord())
     VAL = val;
   else {
@@ -60,8 +69,8 @@ APInt::APInt(uint32_t numBits, uint64_t val, bool isSigned)
 
 APInt::APInt(uint32_t numBits, uint32_t numWords, const uint64_t bigVal[])
   : BitWidth(numBits), VAL(0)  {
-  assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
-  assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
+  assert(BitWidth >= MIN_INT_BITS && "bitwidth too small");
+  assert(BitWidth <= MAX_INT_BITS && "bitwidth too large");
   assert(bigVal && "Null pointer detected!");
   if (isSingleWord())
     VAL = bigVal[0];
@@ -80,23 +89,23 @@ APInt::APInt(uint32_t numBits, uint32_t numWords, const uint64_t bigVal[])
 APInt::APInt(uint32_t numbits, const char StrStart[], uint32_t slen, 
              uint8_t radix) 
   : BitWidth(numbits), VAL(0) {
-  assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
-  assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
+  assert(BitWidth >= MIN_INT_BITS && "bitwidth too small");
+  assert(BitWidth <= MAX_INT_BITS && "bitwidth too large");
   fromString(numbits, StrStart, slen, radix);
 }
 
 APInt::APInt(uint32_t numbits, const std::string& Val, uint8_t radix)
   : BitWidth(numbits), VAL(0) {
-  assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
-  assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
+  assert(BitWidth >= MIN_INT_BITS && "bitwidth too small");
+  assert(BitWidth <= MAX_INT_BITS && "bitwidth too large");
   assert(!Val.empty() && "String empty?");
-  fromString(numbits, Val.c_str(), Val.size(), radix);
+  fromString(numbits, Val.c_str(), (uint32_t)Val.size(), radix);
 }
 
 APInt::APInt(const APInt& that)
   : BitWidth(that.BitWidth), VAL(0) {
-  assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
-  assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
+  assert(BitWidth >= MIN_INT_BITS && "bitwidth too small");
+  assert(BitWidth <= MAX_INT_BITS && "bitwidth too large");
   if (isSingleWord()) 
     VAL = that.VAL;
   else {
@@ -156,6 +165,20 @@ APInt& APInt::operator=(uint64_t RHS) {
   return clearUnusedBits();
 }
 
+/// Profile - This method 'profiles' an APInt for use with FoldingSet.
+void APInt::Profile(FoldingSetNodeID& ID) const {
+  ID.AddInteger(BitWidth);
+  
+  if (isSingleWord()) {
+    ID.AddInteger(VAL);
+    return;
+  }
+
+  uint32_t NumWords = getNumWords();
+  for (unsigned i = 0; i < NumWords; ++i)
+    ID.AddInteger(pVal[i]);
+}
+
 /// add_1 - This function adds a single "digit" integer, y, to the multiple 
 /// "digit" integer array,  x[]. x[] is modified to reflect the addition and
 /// 1 is returned if there is a carry out, otherwise 0 is returned.
@@ -745,7 +768,7 @@ uint32_t APInt::countLeadingZeros() const {
   uint32_t remainder = BitWidth % APINT_BITS_PER_WORD;
   if (remainder)
     Count -= APINT_BITS_PER_WORD - remainder;
-  return Count;
+  return std::min(Count, BitWidth);
 }
 
 static uint32_t countLeadingOnes_64(uint64_t V, uint32_t skip) {
@@ -782,7 +805,7 @@ uint32_t APInt::countLeadingOnes() const {
 
 uint32_t APInt::countTrailingZeros() const {
   if (isSingleWord())
-    return std::min(CountTrailingZeros_64(VAL), BitWidth);
+    return std::min(uint32_t(CountTrailingZeros_64(VAL)), BitWidth);
   uint32_t Count = 0;
   uint32_t i = 0;
   for (; i < getNumWords() && pVal[i] == 0; ++i)
@@ -792,6 +815,18 @@ uint32_t APInt::countTrailingZeros() const {
   return std::min(Count, BitWidth);
 }
 
+uint32_t APInt::countTrailingOnes() const {
+  if (isSingleWord())
+    return std::min(uint32_t(CountTrailingOnes_64(VAL)), BitWidth);
+  uint32_t Count = 0;
+  uint32_t i = 0;
+  for (; i < getNumWords() && pVal[i] == -1ULL; ++i)
+    Count += APINT_BITS_PER_WORD;
+  if (i < getNumWords())
+    Count += CountTrailingOnes_64(pVal[i]);
+  return std::min(Count, BitWidth);
+}
+
 uint32_t APInt::countPopulation() const {
   if (isSingleWord())
     return CountPopulation_64(VAL);
@@ -870,7 +905,7 @@ APInt llvm::APIntOps::RoundDoubleToAPInt(double Double, uint32_t width) {
 
   // Otherwise, we have to shift the mantissa bits up to the right location
   APInt Tmp(width, mantissa);
-  Tmp = Tmp.shl(exp - 52);
+  Tmp = Tmp.shl((uint32_t)exp - 52);
   return isNeg ? -Tmp : Tmp;
 }
 
@@ -943,7 +978,7 @@ double APInt::roundToDouble(bool isSigned) const {
 // Truncate to new width.
 APInt &APInt::trunc(uint32_t width) {
   assert(width < BitWidth && "Invalid APInt Truncate request");
-  assert(width >= IntegerType::MIN_INT_BITS && "Can't truncate to 0 bits");
+  assert(width >= MIN_INT_BITS && "Can't truncate to 0 bits");
   uint32_t wordsBefore = getNumWords();
   BitWidth = width;
   uint32_t wordsAfter = getNumWords();
@@ -966,7 +1001,7 @@ APInt &APInt::trunc(uint32_t width) {
 // Sign extend to a new width.
 APInt &APInt::sext(uint32_t width) {
   assert(width > BitWidth && "Invalid APInt SignExtend request");
-  assert(width <= IntegerType::MAX_INT_BITS && "Too many bits");
+  assert(width <= MAX_INT_BITS && "Too many bits");
   // If the sign bit isn't set, this is the same as zext.
   if (!isNegative()) {
     zext(width);
@@ -1014,7 +1049,7 @@ APInt &APInt::sext(uint32_t width) {
 //  Zero extend to a new width.
 APInt &APInt::zext(uint32_t width) {
   assert(width > BitWidth && "Invalid APInt ZeroExtend request");
-  assert(width <= IntegerType::MAX_INT_BITS && "Too many bits");
+  assert(width <= MAX_INT_BITS && "Too many bits");
   uint32_t wordsBefore = getNumWords();
   BitWidth = width;
   uint32_t wordsAfter = getNumWords();
@@ -1048,6 +1083,12 @@ APInt &APInt::sextOrTrunc(uint32_t width) {
   return *this;
 }
 
+/// Arithmetic right-shift this APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+APInt APInt::ashr(const APInt &shiftAmt) const {
+  return ashr((uint32_t)shiftAmt.getLimitedValue(BitWidth));
+}
+
 /// Arithmetic right-shift this APInt by shiftAmt.
 /// @brief Arithmetic right-shift function.
 APInt APInt::ashr(uint32_t shiftAmt) const {
@@ -1072,7 +1113,7 @@ APInt APInt::ashr(uint32_t shiftAmt) const {
   // issues in the algorithm below.
   if (shiftAmt == BitWidth) {
     if (isNegative())
-      return APInt(BitWidth, -1ULL);
+      return APInt(BitWidth, -1ULL, true);
     else
       return APInt(BitWidth, 0);
   }
@@ -1131,6 +1172,12 @@ APInt APInt::ashr(uint32_t shiftAmt) const {
   return APInt(val, BitWidth).clearUnusedBits();
 }
 
+/// Logical right-shift this APInt by shiftAmt.
+/// @brief Logical right-shift function.
+APInt APInt::lshr(const APInt &shiftAmt) const {
+  return lshr((uint32_t)shiftAmt.getLimitedValue(BitWidth));
+}
+
 /// Logical right-shift this APInt by shiftAmt.
 /// @brief Logical right-shift function.
 APInt APInt::lshr(uint32_t shiftAmt) const {
@@ -1193,6 +1240,13 @@ APInt APInt::lshr(uint32_t shiftAmt) const {
   return APInt(val, BitWidth).clearUnusedBits();
 }
 
+/// Left-shift this APInt by shiftAmt.
+/// @brief Left-shift function.
+APInt APInt::shl(const APInt &shiftAmt) const {
+  // It's undefined behavior in C to shift by BitWidth or greater, but
+  return shl((uint32_t)shiftAmt.getLimitedValue(BitWidth));
+}
+
 /// Left-shift this APInt by shiftAmt.
 /// @brief Left-shift function.
 APInt APInt::shl(uint32_t shiftAmt) const {
@@ -1252,6 +1306,10 @@ APInt APInt::shl(uint32_t shiftAmt) const {
   return APInt(val, BitWidth).clearUnusedBits();
 }
 
+APInt APInt::rotl(const APInt &rotateAmt) const {
+  return rotl((uint32_t)rotateAmt.getLimitedValue(BitWidth));
+}
+
 APInt APInt::rotl(uint32_t rotateAmt) const {
   if (rotateAmt == 0)
     return *this;
@@ -1263,6 +1321,10 @@ APInt APInt::rotl(uint32_t rotateAmt) const {
   return hi | lo;
 }
 
+APInt APInt::rotr(const APInt &rotateAmt) const {
+  return rotr((uint32_t)rotateAmt.getLimitedValue(BitWidth));
+}
+
 APInt APInt::rotr(uint32_t rotateAmt) const {
   if (rotateAmt == 0)
     return *this;
@@ -1455,8 +1517,8 @@ static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t* r,
 
       uint64_t result = u_tmp - subtrahend;
       uint32_t k = j + i;
-      u[k++] = result & (b-1); // subtract low word
-      u[k++] = result >> 32;   // subtract high word
+      u[k++] = (uint32_t)(result & (b-1)); // subtract low word
+      u[k++] = (uint32_t)(result >> 32);   // subtract high word
       while (borrow && k <= m+n) { // deal with borrow to the left
         borrow = u[k] == 0;
         u[k]--;
@@ -1487,7 +1549,7 @@ static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t* r,
 
     // D5. [Test remainder.] Set q[j] = qp. If the result of step D4 was 
     // negative, go to step D6; otherwise go on to step D7.
-    q[j] = qp;
+    q[j] = (uint32_t)qp;
     if (isNeg) {
       // D6. [Add back]. The probability that this step is necessary is very 
       // small, on the order of only 2/b. Make sure that test data accounts for
@@ -1583,8 +1645,8 @@ void APInt::divide(const APInt LHS, uint32_t lhsWords,
   memset(U, 0, (m+n+1)*sizeof(uint32_t));
   for (unsigned i = 0; i < lhsWords; ++i) {
     uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]);
-    U[i * 2] = tmp & mask;
-    U[i * 2 + 1] = tmp >> (sizeof(uint32_t)*8);
+    U[i * 2] = (uint32_t)(tmp & mask);
+    U[i * 2 + 1] = (uint32_t)(tmp >> (sizeof(uint32_t)*8));
   }
   U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm.
 
@@ -1592,8 +1654,8 @@ void APInt::divide(const APInt LHS, uint32_t lhsWords,
   memset(V, 0, (n)*sizeof(uint32_t));
   for (unsigned i = 0; i < rhsWords; ++i) {
     uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.VAL : RHS.pVal[i]);
-    V[i * 2] = tmp & mask;
-    V[i * 2 + 1] = tmp >> (sizeof(uint32_t)*8);
+    V[i * 2] = (uint32_t)(tmp & mask);
+    V[i * 2 + 1] = (uint32_t)(tmp >> (sizeof(uint32_t)*8));
   }
 
   // initialize the quotient and remainder
@@ -1629,13 +1691,13 @@ void APInt::divide(const APInt LHS, uint32_t lhsWords,
         remainder = 0;
       } else if (partial_dividend < divisor) {
         Q[i] = 0;
-        remainder = partial_dividend;
+        remainder = (uint32_t)partial_dividend;
       } else if (partial_dividend == divisor) {
         Q[i] = 1;
         remainder = 0;
       } else {
-        Q[i] = partial_dividend / divisor;
-        remainder = partial_dividend - (Q[i] * divisor);
+        Q[i] = (uint32_t)(partial_dividend / divisor);
+        remainder = (uint32_t)(partial_dividend - (Q[i] * divisor));
       }
     }
     if (R)
@@ -1878,6 +1940,10 @@ void APInt::fromString(uint32_t numbits, const char *str, uint32_t slen,
         assert(0 && "huh? we shouldn't get here");
     } else if (isdigit(cdigit)) {
       digit = cdigit - '0';
+      assert((radix == 10 ||
+              (radix == 8 && digit != 8 && digit != 9) ||
+              (radix == 2 && (digit == 0 || digit == 1))) &&
+             "Invalid digit in string for given radix");
     } else {
       assert(0 && "Invalid character in digit string");
     }
@@ -1905,7 +1971,7 @@ void APInt::fromString(uint32_t numbits, const char *str, uint32_t slen,
 std::string APInt::toString(uint8_t radix, bool wantSigned) const {
   assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
          "Radix should be 2, 8, 10, or 16!");
-  static const char *digits[] = { 
+  static const char *const digits[] = { 
     "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F" 
   };
   std::string result;
@@ -1925,7 +1991,7 @@ std::string APInt::toString(uint8_t radix, bool wantSigned) const {
       memset(buf, 0, 65);
       uint64_t v = VAL;
       while (bits_used) {
-        uint32_t bit = v & 1;
+        uint32_t bit = (uint32_t)v & 1;
         bits_used--;
         buf[bits_used] = digits[bit][0];
         v >>=1;
@@ -1960,7 +2026,8 @@ std::string APInt::toString(uint8_t radix, bool wantSigned) const {
       uint64_t mask = radix - 1;
       APInt zero(tmp.getBitWidth(), 0);
       while (tmp.ne(zero)) {
-        unsigned digit = (tmp.isSingleWord() ? tmp.VAL : tmp.pVal[0]) & mask;
+        unsigned digit =
+          (unsigned)((tmp.isSingleWord() ? tmp.VAL : tmp.pVal[0]) & mask);
         result.insert(insert_at, digits[digit]);
         tmp = tmp.lshr(shift);
       }
@@ -1981,14 +2048,14 @@ std::string APInt::toString(uint8_t radix, bool wantSigned) const {
     result = "-";
     insert_at = 1;
   }
-  if (tmp == APInt(tmp.getBitWidth(), 0))
+  if (tmp == zero)
     result = "0";
   else while (tmp.ne(zero)) {
     APInt APdigit(1,0);
     APInt tmp2(tmp.getBitWidth(), 0);
     divide(tmp, tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2, 
            &APdigit);
-    uint32_t digit = APdigit.getZExtValue();
+    uint32_t digit = (uint32_t)APdigit.getZExtValue();
     assert(digit < radix && "divide failed");
     result.insert(insert_at,digits[digit]);
     tmp = tmp2;
@@ -2021,7 +2088,7 @@ namespace {
 
   /* Returns the integer part with the least significant BITS set.
      BITS cannot be zero.  */
-  inline integerPart
+  static inline integerPart
   lowBitMask(unsigned int bits)
   {
     assert (bits != 0 && bits <= integerPartWidth);
@@ -2030,14 +2097,14 @@ namespace {
   }
 
   /* Returns the value of the lower half of PART.  */
-  inline integerPart
+  static inline integerPart
   lowHalf(integerPart part)
   {
     return part & lowBitMask(integerPartWidth / 2);
   }
 
   /* Returns the value of the upper half of PART.  */
-  inline integerPart
+  static inline integerPart
   highHalf(integerPart part)
   {
     return part >> (integerPartWidth / 2);
@@ -2045,7 +2112,7 @@ namespace {
 
   /* Returns the bit number of the most significant set bit of a part.
      If the input number has no bits set -1U is returned.  */
-  unsigned int
+  static unsigned int
   partMSB(integerPart value)
   {
     unsigned int n, msb;
@@ -2070,7 +2137,7 @@ namespace {
 
   /* Returns the bit number of the least significant set bit of a
      part.  If the input number has no bits set -1U is returned.  */
-  unsigned int
+  static unsigned int
   partLSB(integerPart value)
   {
     unsigned int n, lsb;