[llvm-commits] CVS: llvm/lib/Support/APInt.cpp

Reid Spencer reid at x10sys.com
Tue Feb 20 15:40:42 PST 2007



Changes in directory llvm/lib/Support:

APInt.cpp updated: 1.24 -> 1.25
---
Log message:

Make long addition and subtraction work. Speed things up by using internal
functions more.


---
Diffs of the changes:  (+69 -72)

 APInt.cpp |  141 ++++++++++++++++++++++++++++++--------------------------------
 1 files changed, 69 insertions(+), 72 deletions(-)


Index: llvm/lib/Support/APInt.cpp
diff -u llvm/lib/Support/APInt.cpp:1.24 llvm/lib/Support/APInt.cpp:1.25
--- llvm/lib/Support/APInt.cpp:1.24	Tue Feb 20 14:42:10 2007
+++ llvm/lib/Support/APInt.cpp	Tue Feb 20 17:40:25 2007
@@ -85,13 +85,13 @@
 }
 
 /// @brief Copy constructor
-APInt::APInt(const APInt& APIVal)
-  : BitWidth(APIVal.BitWidth), pVal(0) {
+APInt::APInt(const APInt& that)
+  : BitWidth(that.BitWidth), pVal(0) {
   if (isSingleWord()) 
-    VAL = APIVal.VAL;
+    VAL = that.VAL;
   else {
     pVal = getMemory(getNumWords());
-    memcpy(pVal, APIVal.pVal, getNumWords() * APINT_WORD_SIZE);
+    memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE);
   }
 }
 
@@ -186,11 +186,11 @@
 /// y[] and returns the carry.
 static uint64_t add(uint64_t dest[], uint64_t x[], 
                            uint64_t y[], uint32_t len) {
-  uint32_t carry = 0;
+  uint64_t carry = 0;
   for (uint32_t i = 0; i< len; ++i) {
-    carry += x[i];
-    dest[i] = carry + y[i];
-    carry = carry < x[i] ? 1 : (dest[i] < carry ? 1 : 0);
+    uint64_t save = x[i];
+    dest[i] = x[i] + y[i] + carry;
+    carry = dest[i] < save ? 1 : 0;
   }
   return carry;
 }
@@ -199,18 +199,10 @@
 /// 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()) VAL += RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
+  if (isSingleWord()) 
+    VAL += RHS.VAL;
   else {
-    if (RHS.isSingleWord()) add_1(pVal, pVal, getNumWords(), RHS.VAL);
-    else {
-      if (getNumWords() <= RHS.getNumWords()) 
-        add(pVal, pVal, RHS.pVal, getNumWords());
-      else {
-        uint64_t carry = add(pVal, pVal, RHS.pVal, RHS.getNumWords());
-        add_1(pVal + RHS.getNumWords(), pVal + RHS.getNumWords(), 
-              getNumWords() - RHS.getNumWords(), carry);
-      }
-    }
+    add(pVal, pVal, RHS.pVal, getNumWords());
   }
   clearUnusedBits();
   return *this;
@@ -220,19 +212,13 @@
 /// integer array y[], and returns the borrow-out carry.
 static uint64_t sub(uint64_t dest[], uint64_t x[], 
                            uint64_t y[], uint32_t len) {
-  // Carry indicator.
-  uint64_t cy = 0;
-  
+  uint64_t borrow = 0;
   for (uint32_t i = 0; i < len; ++i) {
-    uint64_t Y = y[i], X = x[i];
-    Y += cy;
-
-    cy = Y < cy ? 1 : 0;
-    Y = X - Y;
-    cy += Y > X ? 1 : 0;
-    dest[i] = Y;
+    uint64_t save = x[i];
+    dest[i] = x[i] - borrow - y[i];
+    borrow = save < dest[i] ? 1 : 0;
   }
-  return cy;
+  return borrow;
 }
 
 /// @brief Subtraction assignment operator. Subtracts this APInt by the given
@@ -240,20 +226,9 @@
 APInt& APInt::operator-=(const APInt& RHS) {
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
   if (isSingleWord()) 
-    VAL -= RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
-  else {
-    if (RHS.isSingleWord())
-      sub_1(pVal, getNumWords(), RHS.VAL);
-    else {
-      if (RHS.getNumWords() < getNumWords()) { 
-        uint64_t carry = sub(pVal, pVal, RHS.pVal, RHS.getNumWords());
-        sub_1(pVal + RHS.getNumWords(), getNumWords() - RHS.getNumWords(), 
-              carry); 
-      }
-      else
-        sub(pVal, pVal, RHS.pVal, getNumWords());
-    }
-  }
+    VAL -= RHS.VAL;
+  else
+    sub(pVal, pVal, RHS.pVal, getNumWords());
   clearUnusedBits();
   return *this;
 }
@@ -330,7 +305,7 @@
 /// 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.
@@ -338,8 +313,6 @@
     uint32_t xlen = !first ? 0 : whichWord(first - 1) + 1;
     if (!xlen) 
       return *this;
-    else if (RHS.isSingleWord()) 
-      mul_1(pVal, pVal, xlen, RHS.VAL);
     else {
       first = RHS.getActiveBits();
       uint32_t ylen = !first ? 0 : whichWord(first - 1) + 1;
@@ -392,11 +365,13 @@
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
   if (isSingleWord()) {
     VAL ^= RHS.VAL;
+    this->clearUnusedBits();
     return *this;
   } 
   uint32_t numWords = getNumWords();
   for (uint32_t i = 0; i < numWords; ++i)
     pVal[i] ^= RHS.pVal[i];
+  this->clearUnusedBits();
   return *this;
 }
 
@@ -420,6 +395,7 @@
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
   if (isSingleWord())
     return APInt(getBitWidth(), VAL | RHS.VAL);
+
   APInt Result(*this);
   uint32_t numWords = getNumWords();
   for (uint32_t i = 0; i < numWords; ++i)
@@ -431,8 +407,11 @@
 /// and the given APInt& RHS.
 APInt APInt::operator^(const APInt& RHS) const {
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
-  if (isSingleWord())
-    return APInt(getBitWidth(), VAL ^ RHS.VAL);
+  if (isSingleWord()) {
+    APInt Result(BitWidth, VAL ^ RHS.VAL);
+    Result.clearUnusedBits();
+    return Result;
+  }
   APInt Result(*this);
   uint32_t numWords = getNumWords();
   for (uint32_t i = 0; i < numWords; ++i)
@@ -456,6 +435,11 @@
 /// RHS.
 APInt APInt::operator*(const APInt& RHS) const {
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+  if (isSingleWord()) {
+    APInt Result(BitWidth, VAL * RHS.VAL);
+    Result.clearUnusedBits();
+    return Result;
+  }
   APInt Result(*this);
   Result *= RHS;
   Result.clearUnusedBits();
@@ -465,18 +449,29 @@
 /// @brief Addition operator. Adds this APInt by the given APInt& RHS.
 APInt APInt::operator+(const APInt& RHS) const {
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
-  APInt API(*this);
-  API += RHS;
-  API.clearUnusedBits();
-  return API;
+  if (isSingleWord()) {
+    APInt Result(BitWidth, VAL + RHS.VAL);
+    Result.clearUnusedBits();
+    return Result;
+  }
+  APInt Result(BitWidth, 0);
+  add(Result.pVal, this->pVal, RHS.pVal, getNumWords());
+  Result.clearUnusedBits();
+  return Result;
 }
 
 /// @brief Subtraction operator. Subtracts this APInt by the given APInt& RHS
 APInt APInt::operator-(const APInt& RHS) const {
   assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
-  APInt API(*this);
-  API -= RHS;
-  return API;
+  if (isSingleWord()) {
+    APInt Result(BitWidth, VAL - RHS.VAL);
+    Result.clearUnusedBits();
+    return Result;
+  }
+  APInt Result(BitWidth, 0);
+  sub(Result.pVal, this->pVal, RHS.pVal, getNumWords());
+  Result.clearUnusedBits();
+  return Result;
 }
 
 /// @brief Array-indexing support.
@@ -488,17 +483,20 @@
 /// @brief Equality operator. Compare this APInt with the given APInt& RHS 
 /// for the validity of the equality relationship.
 bool APInt::operator==(const APInt& RHS) const {
+  if (isSingleWord())
+    return VAL == RHS.VAL;
+
   uint32_t n1 = getActiveBits();
   uint32_t n2 = RHS.getActiveBits();
-  if (n1 != n2) return false;
-  else if (isSingleWord()) 
-    return VAL == (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
-  else {
-    if (n1 <= APINT_BITS_PER_WORD)
-      return pVal[0] == (RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0]);
-    for (int i = whichWord(n1 - 1); i >= 0; --i)
-      if (pVal[i] != RHS.pVal[i]) return false;
-  }
+  if (n1 != n2) 
+    return false;
+
+  if (n1 <= APINT_BITS_PER_WORD)
+    return pVal[0] == RHS.pVal[0];
+
+  for (int i = whichWord(n1 - 1); i >= 0; --i)
+    if (pVal[i] != RHS.pVal[i]) 
+      return false;
   return true;
 }
 
@@ -507,13 +505,12 @@
 bool APInt::operator==(uint64_t Val) const {
   if (isSingleWord())
     return VAL == Val;
-  else {
-    uint32_t n = getActiveBits(); 
-    if (n <= APINT_BITS_PER_WORD)
-      return pVal[0] == Val;
-    else
-      return false;
-  }
+
+  uint32_t n = getActiveBits(); 
+  if (n <= APINT_BITS_PER_WORD)
+    return pVal[0] == Val;
+  else
+    return false;
 }
 
 /// @brief Unsigned less than comparison






More information about the llvm-commits mailing list