[APInt] Reduce number of allocations involved in multiplying. Reduce worst case multi...
authorCraig Topper <craig.topper@gmail.com>
Thu, 4 May 2017 17:00:41 +0000 (17:00 +0000)
committerCraig Topper <craig.topper@gmail.com>
Thu, 4 May 2017 17:00:41 +0000 (17:00 +0000)
commit93c68e11893e895a3f70b848c4f6589920c1d2e6
tree6c9f4d81730a214ba8f49db46085a1dfc1197b43
parent5e6f9bd4f8d7361ab16d437274d338750f16e1b8
[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

llvm-svn: 302171
llvm/lib/Support/APInt.cpp