mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 19:42:54 +02:00
[APInt] Add a utility method to change the bit width and storage size of an APInt.
Summary: This adds a resize method to APInt that manages deleting/allocating storage for an APInt and changes its bit width. Use this to simplify code in copy assignment and divide. The assignment code in particular was overly complicated. Treating every possible case as a separate implementation. I'm also pretty sure the clearUnusedBits code at the end was unnecessary. Since we always copying whole words from the source APInt. All unused bits should be clear in the source. Reviewers: hans, RKSimon Reviewed By: RKSimon Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33073 llvm-svn: 302863
This commit is contained in:
parent
ea27535943
commit
bf05ecc53e
@ -157,6 +157,11 @@ private:
|
|||||||
return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
|
return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility method to change the bit width of this APInt to new bit width,
|
||||||
|
/// allocating and/or deallocating as necessary. There is no guarantee on the
|
||||||
|
/// value of any bits upon return. Caller should populate the bits after.
|
||||||
|
void reallocate(unsigned NewBitWidth);
|
||||||
|
|
||||||
/// \brief Convert a char array into an APInt
|
/// \brief Convert a char array into an APInt
|
||||||
///
|
///
|
||||||
/// \param radix 2, 8, 10, 16, or 36
|
/// \param radix 2, 8, 10, 16, or 36
|
||||||
|
@ -122,35 +122,38 @@ APInt::APInt(unsigned numbits, StringRef Str, uint8_t radix)
|
|||||||
fromString(numbits, Str, radix);
|
fromString(numbits, Str, radix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APInt::reallocate(unsigned NewBitWidth) {
|
||||||
|
// If the number of words is the same we can just change the width and stop.
|
||||||
|
if (getNumWords() == getNumWords(NewBitWidth)) {
|
||||||
|
BitWidth = NewBitWidth;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have an allocation, delete it.
|
||||||
|
if (!isSingleWord())
|
||||||
|
delete [] U.pVal;
|
||||||
|
|
||||||
|
// Update BitWidth.
|
||||||
|
BitWidth = NewBitWidth;
|
||||||
|
|
||||||
|
// If we are supposed to have an allocation, create it.
|
||||||
|
if (!isSingleWord())
|
||||||
|
U.pVal = getMemory(getNumWords());
|
||||||
|
}
|
||||||
|
|
||||||
void APInt::AssignSlowCase(const APInt& RHS) {
|
void APInt::AssignSlowCase(const APInt& RHS) {
|
||||||
// Don't do anything for X = X
|
// Don't do anything for X = X
|
||||||
if (this == &RHS)
|
if (this == &RHS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (BitWidth == RHS.getBitWidth()) {
|
// Adjust the bit width and handle allocations as necessary.
|
||||||
// assume same bit-width single-word case is already handled
|
reallocate(RHS.getBitWidth());
|
||||||
assert(!isSingleWord());
|
|
||||||
memcpy(U.pVal, RHS.U.pVal, getNumWords() * APINT_WORD_SIZE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSingleWord()) {
|
// Copy the data.
|
||||||
// assume case where both are single words is already handled
|
if (isSingleWord())
|
||||||
assert(!RHS.isSingleWord());
|
|
||||||
U.pVal = getMemory(RHS.getNumWords());
|
|
||||||
memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
|
|
||||||
} else if (getNumWords() == RHS.getNumWords())
|
|
||||||
memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
|
|
||||||
else if (RHS.isSingleWord()) {
|
|
||||||
delete [] U.pVal;
|
|
||||||
U.VAL = RHS.U.VAL;
|
U.VAL = RHS.U.VAL;
|
||||||
} else {
|
else
|
||||||
delete [] U.pVal;
|
memcpy(U.pVal, RHS.U.pVal, getNumWords() * APINT_WORD_SIZE);
|
||||||
U.pVal = getMemory(RHS.getNumWords());
|
|
||||||
memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
|
|
||||||
}
|
|
||||||
BitWidth = RHS.BitWidth;
|
|
||||||
clearUnusedBits();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method 'profiles' an APInt for use with FoldingSet.
|
/// This method 'profiles' an APInt for use with FoldingSet.
|
||||||
@ -1500,15 +1503,8 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
|
|||||||
// If the caller wants the quotient
|
// If the caller wants the quotient
|
||||||
if (Quotient) {
|
if (Quotient) {
|
||||||
// Set up the Quotient value's memory.
|
// Set up the Quotient value's memory.
|
||||||
if (Quotient->BitWidth != LHS.BitWidth) {
|
Quotient->reallocate(LHS.BitWidth);
|
||||||
if (Quotient->isSingleWord())
|
// Clear out any previous bits.
|
||||||
Quotient->U.VAL = 0;
|
|
||||||
else
|
|
||||||
delete [] Quotient->U.pVal;
|
|
||||||
Quotient->BitWidth = LHS.BitWidth;
|
|
||||||
if (!Quotient->isSingleWord())
|
|
||||||
Quotient->U.pVal = getClearedMemory(Quotient->getNumWords());
|
|
||||||
} else
|
|
||||||
Quotient->clearAllBits();
|
Quotient->clearAllBits();
|
||||||
|
|
||||||
// The quotient is in Q. Reconstitute the quotient into Quotient's low
|
// The quotient is in Q. Reconstitute the quotient into Quotient's low
|
||||||
@ -1531,15 +1527,8 @@ void APInt::divide(const APInt &LHS, unsigned lhsWords, const APInt &RHS,
|
|||||||
// If the caller wants the remainder
|
// If the caller wants the remainder
|
||||||
if (Remainder) {
|
if (Remainder) {
|
||||||
// Set up the Remainder value's memory.
|
// Set up the Remainder value's memory.
|
||||||
if (Remainder->BitWidth != RHS.BitWidth) {
|
Remainder->reallocate(RHS.BitWidth);
|
||||||
if (Remainder->isSingleWord())
|
// Clear out any previous bits.
|
||||||
Remainder->U.VAL = 0;
|
|
||||||
else
|
|
||||||
delete [] Remainder->U.pVal;
|
|
||||||
Remainder->BitWidth = RHS.BitWidth;
|
|
||||||
if (!Remainder->isSingleWord())
|
|
||||||
Remainder->U.pVal = getClearedMemory(Remainder->getNumWords());
|
|
||||||
} else
|
|
||||||
Remainder->clearAllBits();
|
Remainder->clearAllBits();
|
||||||
|
|
||||||
// The remainder is in R. Reconstitute the remainder into Remainder's low
|
// The remainder is in R. Reconstitute the remainder into Remainder's low
|
||||||
|
Loading…
Reference in New Issue
Block a user