Skip to content

Commit 759e81a

Browse files
committed
optimize: pow if exp is statically known
Copy the optimization that unrolls the loop from `pow` to `checked_pow` and `overflowing_pow`.
1 parent 97d25c8 commit 759e81a

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

library/core/src/num/uint_macros.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,6 +2078,22 @@ macro_rules! uint_impl {
20782078
let mut base = self;
20792079
let mut acc: Self = 1;
20802080

2081+
if intrinsics::is_val_statically_known(exp) {
2082+
while exp > 1 {
2083+
if (exp & 1) == 1 {
2084+
acc = try_opt!(acc.checked_mul(base));
2085+
}
2086+
exp /= 2;
2087+
base = try_opt!(base.checked_mul(base));
2088+
}
2089+
2090+
// since exp!=0, finally the exp must be 1.
2091+
// Deal with the final bit of the exponent separately, since
2092+
// squaring the base afterwards is not necessary and may cause a
2093+
// needless overflow.
2094+
return acc.checked_mul(base);
2095+
}
2096+
20812097
loop {
20822098
if (exp & 1) == 1 {
20832099
acc = try_opt!(acc.checked_mul(base));
@@ -3230,6 +3246,26 @@ macro_rules! uint_impl {
32303246
let mut overflow = false;
32313247
let mut tmp_overflow;
32323248

3249+
if intrinsics::is_val_statically_known(exp) {
3250+
while exp > 1 {
3251+
if (exp & 1) == 1 {
3252+
(acc, tmp_overflow) = acc.overflowing_mul(base);
3253+
overflow |= tmp_overflow;
3254+
}
3255+
exp /= 2;
3256+
(base, tmp_overflow) = base.overflowing_mul(base);
3257+
overflow |= tmp_overflow;
3258+
}
3259+
3260+
// since exp!=0, finally the exp must be 1.
3261+
// Deal with the final bit of the exponent separately, since
3262+
// squaring the base afterwards is not necessary and may cause a
3263+
// needless overflow.
3264+
(acc, tmp_overflow) = acc.overflowing_mul(base);
3265+
overflow |= tmp_overflow;
3266+
return (acc, overflow);
3267+
}
3268+
32333269
loop {
32343270
if (exp & 1) == 1 {
32353271
(acc, tmp_overflow) = acc.overflowing_mul(base);

0 commit comments

Comments
 (0)