Skip to content

Commit 07249ab

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 b2bf646 commit 07249ab

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
@@ -2091,6 +2091,22 @@ macro_rules! uint_impl {
20912091
let mut base = self;
20922092
let mut acc: Self = 1;
20932093

2094+
if intrinsics::is_val_statically_known(exp) {
2095+
while exp > 1 {
2096+
if (exp & 1) == 1 {
2097+
acc = try_opt!(acc.checked_mul(base));
2098+
}
2099+
exp /= 2;
2100+
base = try_opt!(base.checked_mul(base));
2101+
}
2102+
2103+
// since exp!=0, finally the exp must be 1.
2104+
// Deal with the final bit of the exponent separately, since
2105+
// squaring the base afterwards is not necessary and may cause a
2106+
// needless overflow.
2107+
return acc.checked_mul(base);
2108+
}
2109+
20942110
loop {
20952111
if (exp & 1) == 1 {
20962112
acc = try_opt!(acc.checked_mul(base));
@@ -3247,6 +3263,26 @@ macro_rules! uint_impl {
32473263
let mut overflow = false;
32483264
let mut tmp_overflow;
32493265

3266+
if intrinsics::is_val_statically_known(exp) {
3267+
while exp > 1 {
3268+
if (exp & 1) == 1 {
3269+
(acc, tmp_overflow) = acc.overflowing_mul(base);
3270+
overflow |= tmp_overflow;
3271+
}
3272+
exp /= 2;
3273+
(base, tmp_overflow) = base.overflowing_mul(base);
3274+
overflow |= tmp_overflow;
3275+
}
3276+
3277+
// since exp!=0, finally the exp must be 1.
3278+
// Deal with the final bit of the exponent separately, since
3279+
// squaring the base afterwards is not necessary and may cause a
3280+
// needless overflow.
3281+
(acc, tmp_overflow) = acc.overflowing_mul(base);
3282+
overflow |= tmp_overflow;
3283+
return (acc, overflow);
3284+
}
3285+
32503286
loop {
32513287
if (exp & 1) == 1 {
32523288
(acc, tmp_overflow) = acc.overflowing_mul(base);

0 commit comments

Comments
 (0)