]> granicus.if.org Git - llvm/commitdiff
[APInt] Allow GreatestCommonDivisor to take rvalue inputs efficiently. Use moves...
authorCraig Topper <craig.topper@gmail.com>
Sat, 1 Apr 2017 20:30:57 +0000 (20:30 +0000)
committerCraig Topper <craig.topper@gmail.com>
Sat, 1 Apr 2017 20:30:57 +0000 (20:30 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299314 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/APInt.h
lib/Support/APInt.cpp

index 402422507a57842814d13c69a009500f58c1d7dc..56d5777288ec9b7523fc3822ff06849e77fc757c 100644 (file)
@@ -1937,8 +1937,8 @@ inline bool isShiftedMask(const APInt &APIVal) {
 /// This function returns the greatest common divisor of the two APInt values
 /// using Euclid's algorithm.
 ///
-/// \returns the greatest common divisor of Val1 and Val2
-APInt GreatestCommonDivisor(const APInt &Val1, const APInt &Val2);
+/// \returns the greatest common divisor of \param A and \param B.
+APInt GreatestCommonDivisor(APInt A, APInt B);
 
 /// \brief Converts the given APInt to a double value.
 ///
index d6139504f9abd7020f9df62a3da01288af112dfc..0d4255da7f00b1fdfb68bcb24183063bbe97cf1d 100644 (file)
@@ -876,13 +876,11 @@ APInt APInt::reverseBits() const {
   return Reversed;
 }
 
-APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1,
-                                            const APInt& API2) {
-  APInt A = API1, B = API2;
+APInt llvm::APIntOps::GreatestCommonDivisor(APInt A, APInt B) {
   while (!!B) {
-    APInt T = B;
-    B = A.urem(B);
-    A = T;
+    APInt R = A.urem(B);
+    A = std::move(B);
+    B = std::move(R);
   }
   return A;
 }