]> granicus.if.org Git - llvm/commitdiff
[APInt] Move operator~ out of line to make it better able to reused memory allocation...
authorCraig Topper <craig.topper@gmail.com>
Mon, 6 Mar 2017 06:30:47 +0000 (06:30 +0000)
committerCraig Topper <craig.topper@gmail.com>
Mon, 6 Mar 2017 06:30:47 +0000 (06:30 +0000)
Summary:
This makes operator~ take the APInt by value so if it came from a temporary APInt the move constructor will get invoked and it will be able to reuse the memory allocation from the temporary.

This is similar to what was already done for 2s complement negation.

Reviewers: hans, davide, RKSimon

Reviewed By: davide

Subscribers: llvm-commits

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

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

include/llvm/ADT/APInt.h
unittests/ADT/APIntTest.cpp

index 2d3f62075057a96660eef95d4b003c4e6047282e..af284aa491e8eb878d9459ba3825863dc36101f8 100644 (file)
@@ -612,17 +612,6 @@ public:
   /// \returns *this decremented by one.
   APInt &operator--();
 
-  /// \brief Unary bitwise complement operator.
-  ///
-  /// Performs a bitwise complement operation on this APInt.
-  ///
-  /// \returns an APInt that is the bitwise complement of *this
-  APInt operator~() const {
-    APInt Result(*this);
-    Result.flipAllBits();
-    return Result;
-  }
-
   /// \brief Logical negation operator.
   ///
   /// Performs logical negation operation on this APInt.
@@ -1733,6 +1722,14 @@ inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; }
 
 inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; }
 
+/// \brief Unary bitwise complement operator.
+///
+/// \returns an APInt that is the bitwise complement of \p v.
+inline APInt operator~(APInt v) {
+  v.flipAllBits();
+  return v;
+}
+
 inline APInt operator&(APInt a, uint64_t RHS) {
   a &= RHS;
   return a;
index a818d26787e5947efbdc5f0e8ccccf419e6b37db..aa1288e88a1730bac8572dc670b30c31c0a3bb6c 100644 (file)
@@ -761,6 +761,30 @@ TEST(APIntTest, rvalue_arithmetic) {
   }
 }
 
+TEST(APIntTest, rvalue_invert) {
+  // Lamdba to return an APInt by value, but also provide the raw value of the
+  // allocated data.
+  auto getRValue = [](const char *HexString, uint64_t const *&RawData) {
+    APInt V(129, HexString, 16);
+    RawData = V.getRawData();
+    return V;
+  };
+
+  APInt One(129, 1);
+  APInt NegativeTwo(129, -2ULL, true);
+
+  const uint64_t *RawData = nullptr;
+
+  {
+    // ~1 = -2
+    APInt NegL = ~One;
+    EXPECT_EQ(NegL, NegativeTwo);
+
+    APInt NegR = ~getRValue("1", RawData);
+    EXPECT_EQ(NegR, NegativeTwo);
+    EXPECT_EQ(NegR.getRawData(), RawData);
+  }
+}
 
 // Tests different div/rem varaints using scheme (a * b + c) / a
 void testDiv(APInt a, APInt b, APInt c) {