summaryrefslogtreecommitdiff
path: root/lib/Support
diff options
context:
space:
mode:
authorJay Foad <jay.foad@gmail.com>2010-12-07 08:25:19 +0000
committerJay Foad <jay.foad@gmail.com>2010-12-07 08:25:19 +0000
commit40f8f6264d5af2c38e797e0dc59827cd231e8ff7 (patch)
tree3f3b576d6ec060c4063e4630d1ac4fad94997d82 /lib/Support
parent0ea112f104215ccba8d89c839cdeded6e3d49e59 (diff)
downloadllvm-40f8f6264d5af2c38e797e0dc59827cd231e8ff7.tar.gz
llvm-40f8f6264d5af2c38e797e0dc59827cd231e8ff7.tar.bz2
llvm-40f8f6264d5af2c38e797e0dc59827cd231e8ff7.tar.xz
PR5207: Change APInt methods trunc(), sext(), zext(), sextOrTrunc() and
zextOrTrunc(), and APSInt methods extend(), extOrTrunc() and new method trunc(), to be const and to return a new value instead of modifying the object in place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121120 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp6
-rw-r--r--lib/Support/APInt.cpp142
-rw-r--r--lib/Support/ConstantRange.cpp12
-rw-r--r--lib/Support/StringRef.cpp2
4 files changed, 75 insertions, 87 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index c0151e26fb..a83801ed06 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -3310,7 +3310,7 @@ namespace {
// Truncate the significand down to its active bit count, but
// don't try to drop below 32.
unsigned newPrecision = std::max(32U, significand.getActiveBits());
- significand.trunc(newPrecision);
+ significand = significand.trunc(newPrecision);
}
@@ -3415,7 +3415,7 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
// Nothing to do.
} else if (exp > 0) {
// Just shift left.
- significand.zext(semantics->precision + exp);
+ significand = significand.zext(semantics->precision + exp);
significand <<= exp;
exp = 0;
} else { /* exp < 0 */
@@ -3434,7 +3434,7 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
// Multiply significand by 5^e.
// N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
- significand.zext(precision);
+ significand = significand.zext(precision);
APInt five_to_the_i(precision, 5);
while (true) {
if (texp & 1) significand *= five_to_the_i;
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index e7ff15cadb..77033428b5 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -995,96 +995,90 @@ double APInt::roundToDouble(bool isSigned) const {
}
// Truncate to new width.
-APInt &APInt::trunc(unsigned width) {
+APInt APInt::trunc(unsigned width) const {
assert(width < BitWidth && "Invalid APInt Truncate request");
assert(width && "Can't truncate to 0 bits");
- unsigned wordsBefore = getNumWords();
- BitWidth = width;
- unsigned wordsAfter = getNumWords();
- if (wordsBefore != wordsAfter) {
- if (wordsAfter == 1) {
- uint64_t *tmp = pVal;
- VAL = pVal[0];
- delete [] tmp;
- } else {
- uint64_t *newVal = getClearedMemory(wordsAfter);
- for (unsigned i = 0; i < wordsAfter; ++i)
- newVal[i] = pVal[i];
- delete [] pVal;
- pVal = newVal;
- }
- }
- return clearUnusedBits();
+
+ if (width <= APINT_BITS_PER_WORD)
+ return APInt(width, getRawData()[0]);
+
+ APInt Result(getMemory(getNumWords(width)), width);
+
+ // Copy full words.
+ unsigned i;
+ for (i = 0; i != width / APINT_BITS_PER_WORD; i++)
+ Result.pVal[i] = pVal[i];
+
+ // Truncate and copy any partial word.
+ unsigned bits = (0 - width) % APINT_BITS_PER_WORD;
+ if (bits != 0)
+ Result.pVal[i] = pVal[i] << bits >> bits;
+
+ return Result;
}
// Sign extend to a new width.
-APInt &APInt::sext(unsigned width) {
+APInt APInt::sext(unsigned width) const {
assert(width > BitWidth && "Invalid APInt SignExtend request");
- // If the sign bit isn't set, this is the same as zext.
- if (!isNegative()) {
- zext(width);
- return *this;
+
+ if (width <= APINT_BITS_PER_WORD) {
+ uint64_t val = VAL << (APINT_BITS_PER_WORD - BitWidth);
+ val = (int64_t)val >> (width - BitWidth);
+ return APInt(width, val >> (APINT_BITS_PER_WORD - width));
}
- // The sign bit is set. First, get some facts
- unsigned wordsBefore = getNumWords();
- unsigned wordBits = BitWidth % APINT_BITS_PER_WORD;
- BitWidth = width;
- unsigned wordsAfter = getNumWords();
-
- // Mask the high order word appropriately
- if (wordsBefore == wordsAfter) {
- unsigned newWordBits = width % APINT_BITS_PER_WORD;
- // The extension is contained to the wordsBefore-1th word.
- uint64_t mask = ~0ULL;
- if (newWordBits)
- mask >>= APINT_BITS_PER_WORD - newWordBits;
- mask <<= wordBits;
- if (wordsBefore == 1)
- VAL |= mask;
- else
- pVal[wordsBefore-1] |= mask;
- return clearUnusedBits();
+ APInt Result(getMemory(getNumWords(width)), width);
+
+ // Copy full words.
+ unsigned i;
+ uint64_t word = 0;
+ for (i = 0; i != BitWidth / APINT_BITS_PER_WORD; i++) {
+ word = getRawData()[i];
+ Result.pVal[i] = word;
}
- uint64_t mask = wordBits == 0 ? 0 : ~0ULL << wordBits;
- uint64_t *newVal = getMemory(wordsAfter);
- if (wordsBefore == 1)
- newVal[0] = VAL | mask;
- else {
- for (unsigned i = 0; i < wordsBefore; ++i)
- newVal[i] = pVal[i];
- newVal[wordsBefore-1] |= mask;
+ // Read and sign-extend any partial word.
+ unsigned bits = (0 - BitWidth) % APINT_BITS_PER_WORD;
+ if (bits != 0)
+ word = (int64_t)getRawData()[i] << bits >> bits;
+ else
+ word = (int64_t)word >> (APINT_BITS_PER_WORD - 1);
+
+ // Write remaining full words.
+ for (; i != width / APINT_BITS_PER_WORD; i++) {
+ Result.pVal[i] = word;
+ word = (int64_t)word >> (APINT_BITS_PER_WORD - 1);
}
- for (unsigned i = wordsBefore; i < wordsAfter; i++)
- newVal[i] = -1ULL;
- if (wordsBefore != 1)
- delete [] pVal;
- pVal = newVal;
- return clearUnusedBits();
+
+ // Write any partial word.
+ bits = (0 - width) % APINT_BITS_PER_WORD;
+ if (bits != 0)
+ Result.pVal[i] = word << bits >> bits;
+
+ return Result;
}
// Zero extend to a new width.
-APInt &APInt::zext(unsigned width) {
+APInt APInt::zext(unsigned width) const {
assert(width > BitWidth && "Invalid APInt ZeroExtend request");
- unsigned wordsBefore = getNumWords();
- BitWidth = width;
- unsigned wordsAfter = getNumWords();
- if (wordsBefore != wordsAfter) {
- uint64_t *newVal = getClearedMemory(wordsAfter);
- if (wordsBefore == 1)
- newVal[0] = VAL;
- else
- for (unsigned i = 0; i < wordsBefore; ++i)
- newVal[i] = pVal[i];
- if (wordsBefore != 1)
- delete [] pVal;
- pVal = newVal;
- }
- return *this;
+
+ if (width <= APINT_BITS_PER_WORD)
+ return APInt(width, VAL);
+
+ APInt Result(getMemory(getNumWords(width)), width);
+
+ // Copy words.
+ unsigned i;
+ for (i = 0; i != getNumWords(); i++)
+ Result.pVal[i] = getRawData()[i];
+
+ // Zero remaining words.
+ memset(&Result.pVal[i], 0, (Result.getNumWords() - i) * APINT_WORD_SIZE);
+
+ return Result;
}
-APInt &APInt::zextOrTrunc(unsigned width) {
+APInt APInt::zextOrTrunc(unsigned width) const {
if (BitWidth < width)
return zext(width);
if (BitWidth > width)
@@ -1092,7 +1086,7 @@ APInt &APInt::zextOrTrunc(unsigned width) {
return *this;
}
-APInt &APInt::sextOrTrunc(unsigned width) {
+APInt APInt::sextOrTrunc(unsigned width) const {
if (BitWidth < width)
return sext(width);
if (BitWidth > width)
diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp
index 7f68fd32ae..493f7083db 100644
--- a/lib/Support/ConstantRange.cpp
+++ b/lib/Support/ConstantRange.cpp
@@ -442,9 +442,7 @@ ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const {
// Change into [0, 1 << src bit width)
return ConstantRange(APInt(DstTySize,0), APInt(DstTySize,1).shl(SrcTySize));
- APInt L = Lower; L.zext(DstTySize);
- APInt U = Upper; U.zext(DstTySize);
- return ConstantRange(L, U);
+ return ConstantRange(Lower.zext(DstTySize), Upper.zext(DstTySize));
}
/// signExtend - Return a new range in the specified integer type, which must
@@ -461,9 +459,7 @@ ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const {
APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1);
}
- APInt L = Lower; L.sext(DstTySize);
- APInt U = Upper; U.sext(DstTySize);
- return ConstantRange(L, U);
+ return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize));
}
/// truncate - Return a new range in the specified integer type, which must be
@@ -477,9 +473,7 @@ ConstantRange ConstantRange::truncate(uint32_t DstTySize) const {
if (isFullSet() || getSetSize().ugt(Size))
return ConstantRange(DstTySize, /*isFullSet=*/true);
- APInt L = Lower; L.trunc(DstTySize);
- APInt U = Upper; U.trunc(DstTySize);
- return ConstantRange(L, U);
+ return ConstantRange(Lower.trunc(DstTySize), Upper.trunc(DstTySize));
}
/// zextOrTrunc - make this range have the bit width given by \p DstTySize. The
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index 8e636c3317..5398051964 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -371,7 +371,7 @@ bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
if (BitWidth < Result.getBitWidth())
BitWidth = Result.getBitWidth(); // don't shrink the result
else
- Result.zext(BitWidth);
+ Result = Result.zext(BitWidth);
APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix
if (!IsPowerOf2Radix) {