llvm.org GIT mirror llvm / 34adcf1
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302863 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 3 years ago
2 changed file(s) with 37 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
156156 return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
157157 }
158158
159 /// Utility method to change the bit width of this APInt to new bit width,
160 /// allocating and/or deallocating as necessary. There is no guarantee on the
161 /// value of any bits upon return. Caller should populate the bits after.
162 void reallocate(unsigned NewBitWidth);
163
159164 /// \brief Convert a char array into an APInt
160165 ///
161166 /// \param radix 2, 8, 10, 16, or 36
121121 fromString(numbits, Str, radix);
122122 }
123123
124 void APInt::reallocate(unsigned NewBitWidth) {
125 // If the number of words is the same we can just change the width and stop.
126 if (getNumWords() == getNumWords(NewBitWidth)) {
127 BitWidth = NewBitWidth;
128 return;
129 }
130
131 // If we have an allocation, delete it.
132 if (!isSingleWord())
133 delete [] U.pVal;
134
135 // Update BitWidth.
136 BitWidth = NewBitWidth;
137
138 // If we are supposed to have an allocation, create it.
139 if (!isSingleWord())
140 U.pVal = getMemory(getNumWords());
141 }
142
124143 void APInt::AssignSlowCase(const APInt& RHS) {
125144 // Don't do anything for X = X
126145 if (this == &RHS)
127146 return;
128147
129 if (BitWidth == RHS.getBitWidth()) {
130 // assume same bit-width single-word case is already handled
131 assert(!isSingleWord());
148 // Adjust the bit width and handle allocations as necessary.
149 reallocate(RHS.getBitWidth());
150
151 // Copy the data.
152 if (isSingleWord())
153 U.VAL = RHS.U.VAL;
154 else
132155 memcpy(U.pVal, RHS.U.pVal, getNumWords() * APINT_WORD_SIZE);
133 return;
134 }
135
136 if (isSingleWord()) {
137 // assume case where both are single words is already handled
138 assert(!RHS.isSingleWord());
139 U.pVal = getMemory(RHS.getNumWords());
140 memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
141 } else if (getNumWords() == RHS.getNumWords())
142 memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
143 else if (RHS.isSingleWord()) {
144 delete [] U.pVal;
145 U.VAL = RHS.U.VAL;
146 } else {
147 delete [] U.pVal;
148 U.pVal = getMemory(RHS.getNumWords());
149 memcpy(U.pVal, RHS.U.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
150 }
151 BitWidth = RHS.BitWidth;
152 clearUnusedBits();
153156 }
154157
155158 /// This method 'profiles' an APInt for use with FoldingSet.
14991502 // If the caller wants the quotient
15001503 if (Quotient) {
15011504 // Set up the Quotient value's memory.
1502 if (Quotient->BitWidth != LHS.BitWidth) {
1503 if (Quotient->isSingleWord())
1504 Quotient->U.VAL = 0;
1505 else
1506 delete [] Quotient->U.pVal;
1507 Quotient->BitWidth = LHS.BitWidth;
1508 if (!Quotient->isSingleWord())
1509 Quotient->U.pVal = getClearedMemory(Quotient->getNumWords());
1510 } else
1511 Quotient->clearAllBits();
1505 Quotient->reallocate(LHS.BitWidth);
1506 // Clear out any previous bits.
1507 Quotient->clearAllBits();
15121508
15131509 // The quotient is in Q. Reconstitute the quotient into Quotient's low
15141510 // order words.
15301526 // If the caller wants the remainder
15311527 if (Remainder) {
15321528 // Set up the Remainder value's memory.
1533 if (Remainder->BitWidth != RHS.BitWidth) {
1534 if (Remainder->isSingleWord())
1535 Remainder->U.VAL = 0;
1536 else
1537 delete [] Remainder->U.pVal;
1538 Remainder->BitWidth = RHS.BitWidth;
1539 if (!Remainder->isSingleWord())
1540 Remainder->U.pVal = getClearedMemory(Remainder->getNumWords());
1541 } else
1542 Remainder->clearAllBits();
1529 Remainder->reallocate(RHS.BitWidth);
1530 // Clear out any previous bits.
1531 Remainder->clearAllBits();
15431532
15441533 // The remainder is in R. Reconstitute the remainder into Remainder's low
15451534 // order words.