diff options
Diffstat (limited to 'lib/Support/APInt.cpp')
| -rw-r--r-- | lib/Support/APInt.cpp | 109 | 
1 files changed, 43 insertions, 66 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 0ddc2ab8af302..23f89bb66f9e5 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -162,7 +162,7 @@ APInt& APInt::operator=(uint64_t RHS) {    return clearUnusedBits();  } -/// Profile - This method 'profiles' an APInt for use with FoldingSet. +/// This method 'profiles' an APInt for use with FoldingSet.  void APInt::Profile(FoldingSetNodeID& ID) const {    ID.AddInteger(BitWidth); @@ -176,7 +176,7 @@ void APInt::Profile(FoldingSetNodeID& ID) const {      ID.AddInteger(pVal[i]);  } -/// add_1 - This function adds a single "digit" integer, y, to the multiple +/// 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.  /// @returns the carry of the addition. @@ -202,7 +202,7 @@ APInt& APInt::operator++() {    return clearUnusedBits();  } -/// sub_1 - This function subtracts a single "digit" (64-bit word), y, from +/// This function subtracts a single "digit" (64-bit word), y, from  /// the multi-digit integer array, x[], propagating the borrowed 1 value until  /// no further borrowing is neeeded or it runs out of "digits" in x.  The result  /// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted. @@ -231,7 +231,7 @@ APInt& APInt::operator--() {    return clearUnusedBits();  } -/// add - This function adds the integer array x to the integer array Y and +/// This function adds the integer array x to the integer array Y and  /// places the result in dest.  /// @returns the carry out from the addition  /// @brief General addition of 64-bit integer arrays @@ -672,12 +672,20 @@ hash_code llvm::hash_value(const APInt &Arg) {    return hash_combine_range(Arg.pVal, Arg.pVal + Arg.getNumWords());  } -/// HiBits - This function returns the high "numBits" bits of this APInt. +bool APInt::isSplat(unsigned SplatSizeInBits) const { +  assert(getBitWidth() % SplatSizeInBits == 0 && +         "SplatSizeInBits must divide width!"); +  // We can check that all parts of an integer are equal by making use of a +  // little trick: rotate and check if it's still the same value. +  return *this == rotl(SplatSizeInBits); +} + +/// This function returns the high "numBits" bits of this APInt.  APInt APInt::getHiBits(unsigned numBits) const {    return APIntOps::lshr(*this, BitWidth - numBits);  } -/// LoBits - This function returns the low "numBits" bits of this APInt. +/// This function returns the low "numBits" bits of this APInt.  APInt APInt::getLoBits(unsigned numBits) const {    return APIntOps::lshr(APIntOps::shl(*this, BitWidth - numBits),                          BitWidth - numBits); @@ -713,7 +721,7 @@ unsigned APInt::countLeadingZerosSlowCase() const {  unsigned APInt::countLeadingOnes() const {    if (isSingleWord()) -    return CountLeadingOnes_64(VAL << (APINT_BITS_PER_WORD - BitWidth)); +    return llvm::countLeadingOnes(VAL << (APINT_BITS_PER_WORD - BitWidth));    unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD;    unsigned shift; @@ -724,13 +732,13 @@ unsigned APInt::countLeadingOnes() const {      shift = APINT_BITS_PER_WORD - highWordBits;    }    int i = getNumWords() - 1; -  unsigned Count = CountLeadingOnes_64(pVal[i] << shift); +  unsigned Count = llvm::countLeadingOnes(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]); +        Count += llvm::countLeadingOnes(pVal[i]);          break;        }      } @@ -756,14 +764,14 @@ unsigned APInt::countTrailingOnesSlowCase() const {    for (; i < getNumWords() && pVal[i] == -1ULL; ++i)      Count += APINT_BITS_PER_WORD;    if (i < getNumWords()) -    Count += CountTrailingOnes_64(pVal[i]); +    Count += llvm::countTrailingOnes(pVal[i]);    return std::min(Count, BitWidth);  }  unsigned APInt::countPopulationSlowCase() const {    unsigned Count = 0;    for (unsigned i = 0; i < getNumWords(); ++i) -    Count += CountPopulation_64(pVal[i]); +    Count += llvm::countPopulation(pVal[i]);    return Count;  } @@ -853,7 +861,7 @@ APInt llvm::APIntOps::RoundDoubleToAPInt(double Double, unsigned width) {    return isNeg ? -Tmp : Tmp;  } -/// RoundToDouble - This function converts this APInt to a double. +/// This function converts this APInt to a double.  /// The layout for double is as following (IEEE Standard 754):  ///  --------------------------------------  /// |  Sign    Exponent    Fraction    Bias | @@ -1310,13 +1318,8 @@ APInt APInt::sqrt() const {    // libc sqrt function which will probably use a hardware sqrt computation.    // This should be faster than the algorithm below.    if (magnitude < 52) { -#if HAVE_ROUND      return APInt(BitWidth,                   uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0]))))); -#else -    return APInt(BitWidth, -                 uint64_t(::sqrt(double(isSingleWord()?VAL:pVal[0])) + 0.5)); -#endif    }    // Okay, all the short cuts are exhausted. We must compute it. The following @@ -1508,21 +1511,18 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,    assert(u && "Must provide dividend");    assert(v && "Must provide divisor");    assert(q && "Must provide quotient"); -  assert(u != v && u != q && v != q && "Must us different memory"); +  assert(u != v && u != q && v != q && "Must use different memory");    assert(n>1 && "n must be > 1"); -  // Knuth uses the value b as the base of the number system. In our case b -  // is 2^31 so we just set it to -1u. -  uint64_t b = uint64_t(1) << 32; +  // b denotes the base of the number system. In our case b is 2^32. +  LLVM_CONSTEXPR uint64_t b = uint64_t(1) << 32; -#if 0    DEBUG(dbgs() << "KnuthDiv: m=" << m << " n=" << n << '\n');    DEBUG(dbgs() << "KnuthDiv: original:");    DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);    DEBUG(dbgs() << " by");    DEBUG(for (int i = n; i >0; i--) dbgs() << " " << v[i-1]);    DEBUG(dbgs() << '\n'); -#endif    // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of    // u and v by d. Note that we have taken Knuth's advice here to use a power    // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of @@ -1547,13 +1547,12 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,      }    }    u[m+n] = u_carry; -#if 0 +    DEBUG(dbgs() << "KnuthDiv:   normal:");    DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);    DEBUG(dbgs() << " by");    DEBUG(for (int i = n; i >0; i--) dbgs() << " " << v[i-1]);    DEBUG(dbgs() << '\n'); -#endif    // D2. [Initialize j.]  Set j to m. This is the loop counter over the places.    int j = m; @@ -1583,44 +1582,23 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,      // (u[j+n]u[j+n-1]..u[j]) - qp * (v[n-1]...v[1]v[0]). This computation      // consists of a simple multiplication by a one-place number, combined with      // a subtraction. -    bool isNeg = false; -    for (unsigned i = 0; i < n; ++i) { -      uint64_t u_tmp = uint64_t(u[j+i]) | (uint64_t(u[j+i+1]) << 32); -      uint64_t subtrahend = uint64_t(qp) * uint64_t(v[i]); -      bool borrow = subtrahend > u_tmp; -      DEBUG(dbgs() << "KnuthDiv: u_tmp == " << u_tmp -                   << ", subtrahend == " << subtrahend -                   << ", borrow = " << borrow << '\n'); - -      uint64_t result = u_tmp - subtrahend; -      unsigned k = j + i; -      u[k++] = (unsigned)(result & (b-1)); // subtract low word -      u[k++] = (unsigned)(result >> 32);   // subtract high word -      while (borrow && k <= m+n) { // deal with borrow to the left -        borrow = u[k] == 0; -        u[k]--; -        k++; -      } -      isNeg |= borrow; -      DEBUG(dbgs() << "KnuthDiv: u[j+i] == " << u[j+i] << ",  u[j+i+1] == " << -                    u[j+i+1] << '\n'); -    } -    DEBUG(dbgs() << "KnuthDiv: after subtraction:"); -    DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]); -    DEBUG(dbgs() << '\n');      // The digits (u[j+n]...u[j]) should be kept positive; if the result of      // this step is actually negative, (u[j+n]...u[j]) should be left as the      // true value plus b**(n+1), namely as the b's complement of      // the true value, and a "borrow" to the left should be remembered. -    // -    if (isNeg) { -      bool carry = true;  // true because b's complement is "complement + 1" -      for (unsigned i = 0; i <= m+n; ++i) { -        u[i] = ~u[i] + carry; // b's complement -        carry = carry && u[i] == 0; -      } +    int64_t borrow = 0; +    for (unsigned i = 0; i < n; ++i) { +      uint64_t p = uint64_t(qp) * uint64_t(v[i]); +      int64_t subres = int64_t(u[j+i]) - borrow - (unsigned)p; +      u[j+i] = (unsigned)subres; +      borrow = (p >> 32) - (subres >> 32); +      DEBUG(dbgs() << "KnuthDiv: u[j+i] = " << u[j+i] +                   << ", borrow = " << borrow << '\n');      } -    DEBUG(dbgs() << "KnuthDiv: after complement:"); +    bool isNeg = u[j+n] < borrow; +    u[j+n] -= (unsigned)borrow; + +    DEBUG(dbgs() << "KnuthDiv: after subtraction:");      DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);      DEBUG(dbgs() << '\n'); @@ -1644,7 +1622,7 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,        u[j+n] += carry;      }      DEBUG(dbgs() << "KnuthDiv: after correction:"); -    DEBUG(for (int i = m+n; i >=0; i--) dbgs() <<" " << u[i]); +    DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);      DEBUG(dbgs() << "\nKnuthDiv: digit result = " << q[j] << '\n');    // D7. [Loop on j.]  Decrease j by one. Now if j >= 0, go back to D3. @@ -1677,9 +1655,7 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,      }      DEBUG(dbgs() << '\n');    } -#if 0    DEBUG(dbgs() << '\n'); -#endif  }  void APInt::divide(const APInt LHS, unsigned lhsWords, @@ -1803,6 +1779,8 @@ void APInt::divide(const APInt LHS, unsigned lhsWords,      // The quotient is in Q. Reconstitute the quotient into Quotient's low      // order words. +    // This case is currently dead as all users of divide() handle trivial cases +    // earlier.      if (lhsWords == 1) {        uint64_t tmp =          uint64_t(Q[0]) | (uint64_t(Q[1]) << (APINT_BITS_PER_WORD / 2)); @@ -2281,9 +2259,8 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,    std::reverse(Str.begin()+StartDig, Str.end());  } -/// toString - This returns the APInt as a std::string.  Note that this is an -/// inefficient method.  It is better to pass in a SmallVector/SmallString -/// to the methods above. +/// Returns the APInt as a std::string. Note that this is an inefficient method. +/// It is better to pass in a SmallVector/SmallString to the methods above.  std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const {    SmallString<40> S;    toString(S, Radix, Signed, /* formatAsCLiteral = */false); @@ -2296,13 +2273,13 @@ void APInt::dump() const {    this->toStringUnsigned(U);    this->toStringSigned(S);    dbgs() << "APInt(" << BitWidth << "b, " -         << U.str() << "u " << S.str() << "s)"; +         << U << "u " << S << "s)";  }  void APInt::print(raw_ostream &OS, bool isSigned) const {    SmallString<40> S;    this->toString(S, 10, isSigned, /* formatAsCLiteral = */false); -  OS << S.str(); +  OS << S;  }  // This implements a variety of operations on a representation of  | 
