aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-02-26 23:38:21 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-02-26 23:38:21 +0000
commit9ac44113a808c5c7e6c311f1d58fd698b6ffca38 (patch)
tree7f42f488133cd36b86039e666b437baca11bf5ba /lib/Support/APInt.cpp
parentedeffb37dc41591b3d3943a5c02c04e55d348524 (diff)
downloadexternal_llvm-9ac44113a808c5c7e6c311f1d58fd698b6ffca38.zip
external_llvm-9ac44113a808c5c7e6c311f1d58fd698b6ffca38.tar.gz
external_llvm-9ac44113a808c5c7e6c311f1d58fd698b6ffca38.tar.bz2
1. Make sure all delete operators of arrays use the array form of delete.
2. Rewrite operator=(const APInt& RHS) to allow the RHS to be a different bit width than the LHS. This makes it possible to use APInt as the key of a DenseMap, as needed for the IntConstants map in Constants.cpp 3. Fix operator=(uint64_t) to clear unused bits in case the client assigns a value that has more bits than the APInt allows. 4. Assert that bit widths are equal in operator== 5. Revise getHashValue() to put the bit width in the low order six bits. This should help to make i1 0, i2 0, ... i64 0 all distinct in the IntConstants DenseMap. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34646 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/APInt.cpp')
-rw-r--r--lib/Support/APInt.cpp64
1 files changed, 45 insertions, 19 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 44aed75..31327cb 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -99,16 +99,43 @@ APInt::APInt(const APInt& that)
APInt::~APInt() {
if (!isSingleWord() && pVal)
- delete[] pVal;
+ delete [] pVal;
}
APInt& APInt::operator=(const APInt& RHS) {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
+ // Don't do anything for X = X
+ if (this == &RHS)
+ return *this;
+
+ // If the bitwidths are the same, we can avoid mucking with memory
+ if (BitWidth == RHS.getBitWidth()) {
+ if (isSingleWord())
+ VAL = RHS.VAL;
+ else
+ memcpy(pVal, RHS.pVal, getNumWords() * APINT_WORD_SIZE);
+ return *this;
+ }
+
+ if (isSingleWord())
+ if (RHS.isSingleWord())
+ VAL = RHS.VAL;
+ else {
+ VAL = 0;
+ pVal = getMemory(RHS.getNumWords());
+ memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ }
+ else if (getNumWords() == RHS.getNumWords())
+ memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ else if (RHS.isSingleWord()) {
+ delete [] pVal;
VAL = RHS.VAL;
- else
- memcpy(pVal, RHS.pVal, getNumWords() * APINT_WORD_SIZE);
- return *this;
+ } else {
+ delete [] pVal;
+ pVal = getMemory(RHS.getNumWords());
+ memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ }
+ BitWidth = RHS.BitWidth;
+ return clearUnusedBits();
}
APInt& APInt::operator=(uint64_t RHS) {
@@ -118,7 +145,7 @@ APInt& APInt::operator=(uint64_t RHS) {
pVal[0] = RHS;
memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
}
- return *this;
+ return clearUnusedBits();
}
/// add_1 - This function adds a single "digit" integer, y, to the multiple
@@ -457,6 +484,7 @@ bool APInt::operator[](uint32_t bitPosition) const {
}
bool APInt::operator==(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
if (isSingleWord())
return VAL == RHS.VAL;
@@ -662,17 +690,15 @@ APInt APInt::getNullValue(uint32_t numBits) {
}
uint64_t APInt::getHashValue() const {
- // LLVM only supports bit widths up to 2^23 so shift the bitwidth into the
- // high range. This makes the hash unique for integer values < 2^41 bits and
- // doesn't hurt for larger values.
- uint64_t hash = uint64_t(BitWidth) << (APINT_BITS_PER_WORD - 23);
+ // Put the bit width into the low order bits.
+ uint64_t hash = BitWidth;
// Add the sum of the words to the hash.
if (isSingleWord())
- hash += VAL;
+ hash += VAL << 6; // clear separation of up to 64 bits
else
for (uint32_t i = 0; i < getNumWords(); ++i)
- hash += pVal[i];
+ hash += pVal[i] << 6; // clear sepration of up to 64 bits
return hash;
}
@@ -867,12 +893,12 @@ void APInt::trunc(uint32_t width) {
if (wordsAfter == 1) {
uint64_t *tmp = pVal;
VAL = pVal[0];
- delete tmp;
+ delete [] tmp;
} else {
uint64_t *newVal = getClearedMemory(wordsAfter);
for (uint32_t i = 0; i < wordsAfter; ++i)
newVal[i] = pVal[i];
- delete pVal;
+ delete [] pVal;
pVal = newVal;
}
}
@@ -920,7 +946,7 @@ void APInt::sext(uint32_t width) {
for (uint32_t i = wordsBefore; i < wordsAfter; i++)
newVal[i] = -1ULL;
if (wordsBefore != 1)
- delete pVal;
+ delete [] pVal;
pVal = newVal;
clearUnusedBits();
}
@@ -940,7 +966,7 @@ void APInt::zext(uint32_t width) {
for (uint32_t i = 0; i < wordsBefore; ++i)
newVal[i] = pVal[i];
if (wordsBefore != 1)
- delete pVal;
+ delete [] pVal;
pVal = newVal;
}
}
@@ -1407,7 +1433,7 @@ void APInt::divide(const APInt LHS, uint32_t lhsWords,
if (Quotient->isSingleWord())
Quotient->VAL = 0;
else
- delete Quotient->pVal;
+ delete [] Quotient->pVal;
Quotient->BitWidth = LHS.BitWidth;
if (!Quotient->isSingleWord())
Quotient->pVal = getClearedMemory(Quotient->getNumWords());
@@ -1438,7 +1464,7 @@ void APInt::divide(const APInt LHS, uint32_t lhsWords,
if (Remainder->isSingleWord())
Remainder->VAL = 0;
else
- delete Remainder->pVal;
+ delete [] Remainder->pVal;
Remainder->BitWidth = RHS.BitWidth;
if (!Remainder->isSingleWord())
Remainder->pVal = getClearedMemory(Remainder->getNumWords());