325 Commits

Author SHA1 Message Date
Craig Topper
483eed9183 [APInt] Remove an APInt copy from the return of APInt::multiplicativeInverse.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302816 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-11 18:40:53 +00:00
Craig Topper
3daa11c74b [APInt] Fix typo in comment. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302815 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-11 17:57:43 +00:00
Craig Topper
5c7bb0a38a [APInt] Remove an unneeded extra temporary APInt from toString.
Turns out udivrem can write its output to the same location as one of its inputs so the extra temporary isn't needed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302772 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-11 07:10:43 +00:00
Craig Topper
e74359195a [APInt] Use negate() instead of copying an APInt to negate it and then writing back over the original value.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302770 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-11 07:02:04 +00:00
Craig Topper
d53f653e9b [APInt] Add negate helper method to implement twos complement. Use it to shorten code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302716 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 20:01:38 +00:00
Craig Topper
66571bbb0a [APInt] Make toString use udivrem instead of calling the divide helper method directly. Do a better job of reusing allocations while looping. NFCI
This lets toString take advantage of the degenerate case checks in udivrem and is just generally cleaner.

One minor downside of this is that the divisor APInt now needs to be the same size as Tmp which requires an additional allocation. But we were doing a poor job of reusing allocations before so the new code should still be an improvement.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302704 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 18:15:24 +00:00
Craig Topper
439700ccdd [APInt] Use uint32_t instead of unsigned for the storage type throughout the divide code. Use Lo_32/Hi_32/Make_64 helpers instead of casts and shifts. NFCI
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302703 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 18:15:20 +00:00
Craig Topper
223d23f311 [APInt] Use getRawData to slightly simplify some code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302702 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 18:15:17 +00:00
Craig Topper
b97c98e5dc [APInt] Remove check for single word since single word was handled earlier in the function. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302701 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 18:15:14 +00:00
Craig Topper
a2ef53afc0 [APInt] Fix indentation of tcDivide. Combine variable declaration and initialization.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302626 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 07:50:17 +00:00
Craig Topper
78609efbe9 [APInt] Use getNumWords function in udiv/urem/udivrem instead of reimplementinging it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302625 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 07:50:15 +00:00
Craig Topper
80f6556e8a [APInt] Remove return value from tcFullMultiply.
The description says it returns the number of words needed to represent the results. But the way it was coded it always returns (lhsWords + rhsWords) or (lhsWords + rhsWords - 1). But the result could be even smaller than that and it wouldn't tell you.

No one uses the result today so rather than try to fix it, just remove it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302551 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-09 16:47:33 +00:00
Craig Topper
5bc7ae494b [APInt] Use default constructor instead of explicitly creating a 1-bit APInt in udiv and urem. NFC
The default constructor does the same thing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302487 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-08 23:49:54 +00:00
Craig Topper
8894742d7d [APInt] Remove 'else' after 'return' in udiv and urem. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302486 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-08 23:49:49 +00:00
Craig Topper
c571744eac [APInt] Modify tcMultiplyPart's overflow detection to not depend on 'i' from the earlier loop. NFC
The value of 'i' is always the smaller of DstParts and SrcParts so we can just use that fact to write all the code in terms of SrcParts and DstParts.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302408 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-08 06:34:41 +00:00
Craig Topper
df5e49783f [APInt] Use std::min instead of writing the same thing with the ternary operator. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302407 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-08 06:34:39 +00:00
Craig Topper
3522a09753 [APInt] Remove 'else' after 'return' in tcMultiply methods. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302406 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-08 06:34:36 +00:00
Craig Topper
b33f45017e [APInt] Take advantage of new operator*=(uint64_t) to remove a temporary APInt.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302403 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-08 04:55:12 +00:00
Craig Topper
1e5158d3c8 [APInt] Add support for multiplying by a uint64_t.
This makes multiply similar to add, sub, xor, and, and or.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302402 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-08 04:55:09 +00:00
Craig Topper
f0e5c5056f [APInt] Reduce number of allocations involved in multiplying. Reduce worst case multiply size
Currently multiply is implemented in operator*=. Operator* makes a copy and uses operator*= to modify the copy.

Operator*= itself allocates a temporary buffer to hold the multiply result as it computes it. Then copies it to the buffer in *this.

Operator*= attempts to bound the size of the result based on the number of active bits in its inputs. It also has a couple special cases to handle 0 inputs without any memory allocations or multiply operations. The best case is that it calculates a single word regardless of input bit width. The worst case is that it calculates the a 2x input width result and drop the upper bits.

Since operator* uses operator*= it incurs two allocations, one for a copy of *this and one for the temporary allocation. Neither of these allocations are kept after the method operation is done.

The main usage in the backend appears to be ConstantRange::multiply which uses operator* rather than operator*=.

This patch moves the multiply operation to operator* and implements operator*= using it. This avoids the copy in operator*. operator* now allocates a result buffer sized the same width as its inputs no matter what. This buffer will be used as the buffer for the returned APInt. Finally, we reuse tcMultiply to implement the multiply operation. This function is capable of not calculating additional upper words that will be discarded.

This change does lose the special optimizations for the inputs using less words than their size implies. But it also removed the getActiveBits calls from all multiplies. If we think those optimizations are important we could look at providing additional bounds to tcMultiply to limit the computations.

Differential Revision: https://reviews.llvm.org/D32830

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302171 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-04 17:00:41 +00:00
Craig Topper
52bc9d9102 [APInt] Give the value union a name so we can remove assumptions on VAL being the larger member
Currently several places assume the VAL member is always at least the same size as pVal. In particular for a memcpy in the move assignment operator. While this is a true assumption, it isn't good practice to assume this.

This patch gives the union a name so we can write the memcpy in terms of the union itself. This also adds a similar memcpy to the move constructor where we previously just copied using VAL directly.

This patch is mostly just a mechanical addition of the U in front of VAL and pVAL everywhere. But several constructors had to be modified since we can't directly initializer a field of named union from the initializer list.

Differential Revision: https://reviews.llvm.org/D30629

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302040 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-03 15:46:24 +00:00
Craig Topper
7d66f52694 [APInt] Move APInt::getSplat out of line.
I think this method is probably too complex to be inlined.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301901 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-02 06:32:27 +00:00
Craig Topper
382616f0dc [APInt] Move the setBit and clearBit methods inline.
This makes setBit/clearBit more consistent with setBits which is already inlined.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301900 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-02 05:49:40 +00:00
Craig Topper
a7fa95c0e5 [APInt] Use inplace shift methods where possible. NFCI
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301612 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-28 03:36:24 +00:00
Craig Topper
36e5af50c1 [APInt] Simplify the zext and sext methods
This replaces a hand written copy loop with a call to memcpy for both zext and sext.

For sext, it replaces multiple if/else blocks propagating sign information forward. Now we just do a copy, a sign extension on the last copied word, a memset, and clearUnusedBits.

Differential Revision: https://reviews.llvm.org/D32417

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301201 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-24 17:37:10 +00:00
Craig Topper
f322f9268c [APInt] Add ashrInPlace method and rewrite ashr to make a copy and then call ashrInPlace.
This patch adds an in place version of ashr to match lshr and shl which were recently added.

I've tried to make this similar to the lshr code with additions to handle the sign extension. I've also tried to do this with less if checks than the current ashr code by sign extending the original result to a word boundary before doing any of the shifting. This removes a lot of the complexity of determining where to fill in sign bits after the shifting.

Differential Revision: https://reviews.llvm.org/D32415

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301198 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-24 17:18:47 +00:00
Craig Topper
e115996cce [APInt] Fix repeated word in comments. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301192 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-24 17:00:22 +00:00
Craig Topper
6a61317c63 [APInt] Make behavior of ashr by BitWidth consistent between single and multi word.
Previously single word would always return 0 regardless of the original sign. Multi word would return all 0s or all 1s based on the original sign. Now single word takes into account the sign as well.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301159 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-24 05:38:26 +00:00
Craig Topper
7271492c50 [APInt] In sext single word case, use SignExtend64 and let the APInt constructor mask off any excess bits.
The current code is trying to be clever with shifts to avoid needing to clear unused bits. But it looks like the compiler is unable to optimize out the unused bit handling in the APInt constructor. Given this its better to just use SignExtend64 and have more readable code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301133 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-23 17:16:24 +00:00
Renato Golin
d907744fff Revert "[APInt] Fix a few places that use APInt::getRawData to operate within the normal API."
This reverts commit r301105, 4, 3 and 1, as a follow up of the previous
revert, which broke even more bots.

For reference:
Revert "[APInt] Use operator<<= where possible. NFC"
Revert "[APInt] Use operator<<= instead of shl where possible. NFC"
Revert "[APInt] Use ashInPlace where possible."

PR32754.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301111 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-23 12:15:30 +00:00
Renato Golin
ea7650c4ed Revert "[APInt] Add ashrInPlace method and implement ashr using it. Also fix a bug in the shift by BitWidth handling."
This reverts commit r301094, as it broke all ARM self-hosting bots.

PR32754.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301110 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-23 12:02:07 +00:00
Craig Topper
5e17d2e85c [APInt] Use operator<<= instead of shl where possible. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301103 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-23 05:18:31 +00:00
Craig Topper
0d0472f857 [APInt] Add ashrInPlace method and implement ashr using it. Also fix a bug in the shift by BitWidth handling.
For single word, shift by BitWidth was always returning 0, but for multiword it was based on original sign. Now single word matches multi word.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301094 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-22 22:00:03 +00:00
Craig Topper
e14494685b [APInt] Remove unnecessary min with BitWidth from countTrailingOnesSlowCase.
The unused upper bits are guaranteed to be 0 so we don't need to worry about accidentally counting them.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301091 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-22 19:59:11 +00:00
Craig Topper
b75bb044ee [APInt] Add WORD_MAX constant and use it instead of UINT64_MAX. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301069 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-22 06:31:36 +00:00
Craig Topper
fe916169d7 [APInt] Add compare/compareSigned methods that return -1, 0, 1. Reimplement slt/ult and friends using them
Currently sle and ule have to call slt/ult and eq to get the proper answer. This results in extra code for both calls and additional scans of multiword APInts.

This patch replaces slt/ult with a compareSigned/compare that can return -1, 0, or 1 so we can cover all the comparison functions with a single call.

While I was there I removed the activeBits calls and other checks at the start of the slow part of ult. Both of the activeBits calls potentially scan through each of the APInts separately. I can't imagine that's any better than just scanning them in parallel and doing the compares. Now we just share the code with tcCompare.

These changes seem to be good for about a 7-8k reduction on the size of the opt binary on my local x86-64 build.

Differential Revision: https://reviews.llvm.org/D32339

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300995 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-21 16:13:15 +00:00
Craig Topper
b52e0e4247 [APInt] Add isSubsetOf method that can check if one APInt is a subset of another without creating temporary APInts
This question comes up in many places in SimplifyDemandedBits. This makes it easy to ask without allocating additional temporary APInts.

The BitVector class provides a similar functionality through its (IMHO badly named) test(const BitVector&) method. Though its output polarity is reversed.

I've provided one example use case in this patch. I plan to do more as a follow up.

Differential Revision: https://reviews.llvm.org/D32258



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300851 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-20 16:17:13 +00:00
Craig Topper
be583f25e0 [APInt] Implement APInt::intersects without creating a temporary APInt in the multiword case
Summary: This is a simple question we should be able to answer without creating a temporary to hold the AND result. We can also get an early out as soon as we find a word that intersects.

Reviewers: RKSimon, hans, spatel, davide

Reviewed By: hans, davide

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D32253

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300812 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-20 02:11:27 +00:00
Craig Topper
ba583aa026 [APInt] Implement operator==(uint64_t) similar to ugt/ult(uint64_t) to remove one of the out of line EqualsSlowCase methods.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300799 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-19 23:57:51 +00:00
Craig Topper
51a8438801 [APInt] Move the 'return *this' from the slow cases of assignment operators inline. We should let the compiler see that the fast/slow cases both return *this.
I don't think we chain assignments together very often so this shouldn't matter much.




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300715 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-19 17:01:58 +00:00
Craig Topper
461e0b352d [APInt] Inline the single word case of lshrInPlace similar to what we do for <<=.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300577 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-18 19:13:27 +00:00
Craig Topper
df22034939 [APInt] Use lshrInPlace to replace lshr where possible
This patch uses lshrInPlace to replace code where the object that lshr is called on is being overwritten with the result.

This adds an lshrInPlace(const APInt &) version as well.

Differential Revision: https://reviews.llvm.org/D32155




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300566 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-18 17:14:21 +00:00
Craig Topper
0f06c8216f [APInt] Cleanup the reverseBits slow case a little.
Use lshrInPlace. Use single bit extract and operator|=(uint64_t) to avoid a few temporary APInts.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300527 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-18 05:02:21 +00:00
Craig Topper
4bf2830a01 [APInt] Make operator<<= shift in place. Improve the implementation of tcShiftLeft and use it to implement operator<<=.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300526 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-18 04:39:48 +00:00
Craig Topper
9128da5831 [APInt] Merge the multiword code from lshrInPlace and tcShiftRight into a single implementation
This merges the two different multiword shift right implementations into a single version located in tcShiftRight. lshrInPlace now calls tcShiftRight for the multiword case.

I retained the memmove fast path from lshrInPlace and used a memset for the zeroing. The for loop is basically tcShiftRight's implementation with the zeroing and the intra-shift of 0 removed.

Differential Revision: https://reviews.llvm.org/D32114



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300503 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-17 21:43:43 +00:00
Craig Topper
2f3c5dbfdb [APInt] Fix a bug in lshr by a value more than 64 bits above the bit width.
This was throwing an assert because we determined the intra-word shift amount by subtracting the size of the full word shift from the total shift amount. But we failed to account for the fact that we clipped the full word shifts by total words first. To fix this just calculate the intra-word shift as the remainder of dividing by bits per word.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300405 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-16 01:03:51 +00:00
Richard Smith
74413b926a Remove all allocation and divisions from GreatestCommonDivisor
Switch from Euclid's algorithm to Stein's algorithm for computing GCD. This
avoids the (expensive) APInt division operation in favour of bit operations.
Remove all memory allocation from within the GCD loop by tweaking our `lshr`
implementation so it can operate in-place.

Differential Revision: https://reviews.llvm.org/D31968


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300252 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-13 20:29:59 +00:00
Craig Topper
c170edb60b [APInt] Reorder fields to avoid a hole in the middle of the class
Summary:
APInt is currently implemented with an unsigned BitWidth field first and then a uint_64/pointer union. Due to the 64-bit size of the union there is a hole after the bitwidth.

Putting the union first allows the class to be packed. Making it 12 bytes instead of 16 bytes. An APSInt goes from 20 bytes to 16 bytes.

This shows a 4k reduction on the size of the opt binary on my local x86-64 build. So this enables some other improvement to the code as well.

Reviewers: dblaikie, RKSimon, hans, davide

Reviewed By: davide

Subscribers: davide, llvm-commits

Differential Revision: https://reviews.llvm.org/D32001

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300171 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-13 04:59:11 +00:00
Craig Topper
cd686df68a [APInt] Generalize the implementation of tcIncrement to support adding a full 'word' by introducing tcAddPart. Use this to support tcIncrement, operator++ and operator+=(uint64_t). Do the same for subtract. NFCI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300169 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-13 04:36:06 +00:00
Craig Topper
c94363ef7c [APInt] Make use of whichWord and maskBit to simplify some code. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299342 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-02 19:35:18 +00:00