Reorganize some code to make it clearer, avoid a few uninitialized memory
authorReid Spencer <rspencer@reidspencer.com>
Wed, 21 Feb 2007 08:21:52 +0000 (08:21 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Wed, 21 Feb 2007 08:21:52 +0000 (08:21 +0000)
reads, and reduce the number of temporary APInt instances we construct.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34467 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/APInt.cpp

index ae7cc439d3d9287bb2dfe51d8e51d5d57713700c..a515366db21df727d3938edf60a645d98139b3fe 100644 (file)
@@ -280,7 +280,7 @@ static void mul(uint64_t dest[], uint64_t x[], uint32_t xlen,
 
   for (uint32_t i = 1; i < ylen; ++i) {
     uint64_t ly = y[i] & 0xffffffffULL, hy = y[i] >> 32;
-    uint64_t carry = 0, lx, hx;
+    uint64_t carry = 0, lx = 0, hx = 0;
     for (uint32_t j = 0; j < xlen; ++j) {
       lx = x[j] & 0xffffffffULL;
       hx = x[j] >> 32;
@@ -309,29 +309,42 @@ static void mul(uint64_t dest[], uint64_t x[], uint32_t xlen,
 /// given APInt& RHS and assigns the result to this APInt.
 APInt& APInt::operator*=(const APInt& RHS) {
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
-  if (isSingleWord())
+  if (isSingleWord()) {
     VAL *= RHS.VAL;
-  else {
-    // one-based first non-zero bit position.
-    uint32_t first = getActiveBits();
-    uint32_t xlen = !first ? 0 : whichWord(first - 1) + 1;
-    if (!xlen) 
-      return *this;
-    else {
-      first = RHS.getActiveBits();
-      uint32_t ylen = !first ? 0 : whichWord(first - 1) + 1;
-      if (!ylen) {
-        memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
-        return *this;
-      }
-      uint64_t *dest = getMemory(xlen+ylen);
-      mul(dest, pVal, xlen, RHS.pVal, ylen);
-      memcpy(pVal, dest, ((xlen + ylen >= getNumWords()) ? 
-                         getNumWords() : xlen + ylen) * APINT_WORD_SIZE);
-      delete[] dest;
-    }
+    clearUnusedBits();
+    return *this;
   }
-  clearUnusedBits();
+
+  // Get some bit facts about LHS and check for zero
+  uint32_t lhsBits = getActiveBits();
+  uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1;
+  if (!lhsWords) 
+    // 0 * X ===> 0
+    return *this;
+
+  // Get some bit facts about RHS and check for zero
+  uint32_t rhsBits = RHS.getActiveBits();
+  uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1;
+  if (!rhsWords) {
+    // X * 0 ===> 0
+    clear();
+    return *this;
+  }
+
+  // Allocate space for the result
+  uint32_t destWords = rhsWords + lhsWords;
+  uint64_t *dest = getMemory(destWords);
+
+  // Perform the long multiply
+  mul(dest, pVal, lhsWords, RHS.pVal, rhsWords);
+
+  // Copy result back into *this
+  clear();
+  uint32_t wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
+  memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
+
+  // delete dest array and return
+  delete[] dest;
   return *this;
 }
 
@@ -1239,7 +1252,7 @@ void APInt::divide(const APInt LHS, uint32_t lhsWords,
         delete Quotient->pVal;
       Quotient->BitWidth = LHS.BitWidth;
       if (!Quotient->isSingleWord())
-        Quotient->pVal = getClearedMemory(lhsWords);
+        Quotient->pVal = getClearedMemory(Quotient->getNumWords());
     } else
       Quotient->clear();
 
@@ -1270,7 +1283,7 @@ void APInt::divide(const APInt LHS, uint32_t lhsWords,
         delete Remainder->pVal;
       Remainder->BitWidth = RHS.BitWidth;
       if (!Remainder->isSingleWord())
-        Remainder->pVal = getClearedMemory(rhsWords);
+        Remainder->pVal = getClearedMemory(Remainder->getNumWords());
     } else
       Remainder->clear();
 
@@ -1316,25 +1329,19 @@ APInt APInt::udiv(const APInt& RHS) const {
   uint32_t lhsBits = this->getActiveBits();
   uint32_t lhsWords = !lhsBits ? 0 : (APInt::whichWord(lhsBits - 1) + 1);
 
-  // Make a temporary to hold the result
-  APInt Result(*this);
-
   // Deal with some degenerate cases
   if (!lhsWords) 
-    return Result; // 0 / X == 0
-  else if (lhsWords < rhsWords || Result.ult(RHS)) {
-    // X / Y with X < Y == 0
-    memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
-    return Result;
-  } else if (Result == RHS) {
-    // X / X == 1
-    memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
-    Result.pVal[0] = 1;
-    return Result;
+    // 0 / X ===> 0
+    return APInt(BitWidth, 0); 
+  else if (lhsWords < rhsWords || this->ult(RHS)) {
+    // X / Y ===> 0, iff X < Y
+    return APInt(BitWidth, 0);
+  } else if (*this == RHS) {
+    // X / X ===> 1
+    return APInt(BitWidth, 1);
   } else if (lhsWords == 1 && rhsWords == 1) {
     // All high words are zero, just use native divide
-    Result.pVal[0] /= RHS.pVal[0];
-    return Result;
+    return APInt(BitWidth, this->pVal[0] / RHS.pVal[0]);
   }
 
   // We have to compute it the hard way. Invoke the Knuth divide algorithm.
@@ -1352,34 +1359,28 @@ APInt APInt::urem(const APInt& RHS) const {
     return APInt(BitWidth, VAL % RHS.VAL);
   }
 
-  // Make a temporary to hold the result
-  APInt Result(*this);
+  // Get some facts about the LHS
+  uint32_t lhsBits = getActiveBits();
+  uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1);
 
   // Get some facts about the RHS
   uint32_t rhsBits = RHS.getActiveBits();
   uint32_t rhsWords = !rhsBits ? 0 : (APInt::whichWord(rhsBits - 1) + 1);
   assert(rhsWords && "Performing remainder operation by zero ???");
 
-  // Get some facts about the LHS
-  uint32_t lhsBits = Result.getActiveBits();
-  uint32_t lhsWords = !lhsBits ? 0 : (Result.whichWord(lhsBits - 1) + 1);
-
   // Check the degenerate cases
   if (lhsWords == 0) {
-    // 0 % Y == 0
-    memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
-    return Result;
-  } else if (lhsWords < rhsWords || Result.ult(RHS)) {
-    // X % Y == X iff X < Y
-    return Result;
-  } else if (Result == RHS) {
+    // 0 % Y ===> 0
+    return APInt(BitWidth, 0);
+  } else if (lhsWords < rhsWords || this->ult(RHS)) {
+    // X % Y ===> X, iff X < Y
+    return *this;
+  } else if (*this == RHS) {
     // X % X == 0;
-    memset(Result.pVal, 0, Result.getNumWords() * APINT_WORD_SIZE);
-    return Result;
+    return APInt(BitWidth, 0);
   } else if (lhsWords == 1) {
     // All high words are zero, just use native remainder
-    Result.pVal[0] %=  RHS.pVal[0];
-    return Result;
+    return APInt(BitWidth, pVal[0] % RHS.pVal[0]);
   }
 
   // We have to compute it the hard way. Invoke the Knute divide algorithm.