aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2011-03-17 20:39:06 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2011-03-17 20:39:06 +0000
commitd9103df51b858cf051a1650ac7eb33d416e9ac41 (patch)
tree8b6f8e90439018b65d736d50ca4c8cb9b9b206d2
parent6a3dbd3b25bbc99bd1a233d6a74ddea3493ba6ac (diff)
Add an argument to APInt's magic udiv calculation to specify the number of bits that are known zero in the divided number.
This will come in handy soon. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127828 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/APInt.h2
-rw-r--r--lib/Support/APInt.cpp6
-rw-r--r--unittests/ADT/APIntTest.cpp2
3 files changed, 7 insertions, 3 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index d1fd3e5034..82819d57a2 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -1372,7 +1372,7 @@ public:
/// Calculate the magic number for unsigned division by a constant.
struct mu;
- mu magicu() const;
+ mu magicu(unsigned LeadingZeros = 0) const;
/// @}
/// @name Building-block Operations for APInt and APFloat
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 08f36d2af3..f4aae72eca 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -1517,13 +1517,15 @@ APInt::ms APInt::magic() const {
/// division by a constant as a sequence of multiplies, adds and shifts.
/// Requires that the divisor not be 0. Taken from "Hacker's Delight", Henry
/// S. Warren, Jr., chapter 10.
-APInt::mu APInt::magicu() const {
+/// LeadingZeros can be used to simplify the calculation if the upper bits
+/// of the devided value are known zero.
+APInt::mu APInt::magicu(unsigned LeadingZeros) const {
const APInt& d = *this;
unsigned p;
APInt nc, delta, q1, r1, q2, r2;
struct mu magu;
magu.a = 0; // initialize "add" indicator
- APInt allOnes = APInt::getAllOnesValue(d.getBitWidth());
+ APInt allOnes = APInt::getAllOnesValue(d.getBitWidth()).lshr(LeadingZeros);
APInt signedMin = APInt::getSignedMinValue(d.getBitWidth());
APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth());
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index e05bdbfc71..dbd0cb7a24 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -348,6 +348,8 @@ TEST(APIntTest, magicu) {
EXPECT_EQ(APInt(32, 5).magicu().s, 2U);
EXPECT_EQ(APInt(32, 7).magicu().m, APInt(32, "24924925", 16));
EXPECT_EQ(APInt(32, 7).magicu().s, 3U);
+ EXPECT_EQ(APInt(64, 25).magicu(1).m, APInt(64, "A3D70A3D70A3D70B", 16));
+ EXPECT_EQ(APInt(64, 25).magicu(1).s, 4U);
}
#ifdef GTEST_HAS_DEATH_TEST