[APInt] Allow GreatestCommonDivisor to take rvalue inputs efficiently. Use moves instead of copies in the loop.

Summary:
GreatestComonDivisor currently makes a copy of both its inputs. Then in the loop we do one move and two copies, plus any allocation the urem call does.

This patch changes it to take its inputs by value so that we can do a move of any rvalue inputs instead of copying. Then in the loop we do 3 move assignments and no copies. This way the only possible allocations we have in the loop is from the urem call.

Reviewers: dblaikie, RKSimon, hans

Reviewed By: dblaikie

Subscribers: llvm-commits

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

llvm-svn: 299314
This commit is contained in:
Craig Topper 2017-04-01 20:30:57 +00:00
parent 16fe5822f2
commit 278ebd2f98
2 changed files with 6 additions and 8 deletions

View File

@ -1937,8 +1937,8 @@ inline bool isShiftedMask(const APInt &APIVal) {
/// This function returns the greatest common divisor of the two APInt values /// This function returns the greatest common divisor of the two APInt values
/// using Euclid's algorithm. /// using Euclid's algorithm.
/// ///
/// \returns the greatest common divisor of Val1 and Val2 /// \returns the greatest common divisor of \param A and \param B.
APInt GreatestCommonDivisor(const APInt &Val1, const APInt &Val2); APInt GreatestCommonDivisor(APInt A, APInt B);
/// \brief Converts the given APInt to a double value. /// \brief Converts the given APInt to a double value.
/// ///

View File

@ -876,13 +876,11 @@ APInt APInt::reverseBits() const {
return Reversed; return Reversed;
} }
APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1, APInt llvm::APIntOps::GreatestCommonDivisor(APInt A, APInt B) {
const APInt& API2) {
APInt A = API1, B = API2;
while (!!B) { while (!!B) {
APInt T = B; APInt R = A.urem(B);
B = A.urem(B); A = std::move(B);
A = T; B = std::move(R);
} }
return A; return A;
} }