Optimize integer pow by removing exit branch
The branch at the end of the `pow` implementations is redundant with multiplication code already present in the loop. By rotating the exit check, this branch can be largely removed, improving code size and instruction cache coherence.
This commit is contained in:
parent
bcf1f6db45
commit
df27dfa0ea
2 changed files with 52 additions and 73 deletions
|
@ -1495,18 +1495,17 @@ macro_rules! int_impl {
|
|||
let mut base = self;
|
||||
let mut acc: Self = 1;
|
||||
|
||||
while exp > 1 {
|
||||
loop {
|
||||
if (exp & 1) == 1 {
|
||||
acc = try_opt!(acc.checked_mul(base));
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
if exp == 1 {
|
||||
return Some(acc);
|
||||
}
|
||||
}
|
||||
exp /= 2;
|
||||
base = try_opt!(base.checked_mul(base));
|
||||
}
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
// Deal with the final bit of the exponent separately, since
|
||||
// squaring the base afterwards is not necessary and may cause a
|
||||
// needless overflow.
|
||||
acc.checked_mul(base)
|
||||
}
|
||||
|
||||
/// Strict exponentiation. Computes `self.pow(exp)`, panicking if
|
||||
|
@ -1546,18 +1545,17 @@ macro_rules! int_impl {
|
|||
let mut base = self;
|
||||
let mut acc: Self = 1;
|
||||
|
||||
while exp > 1 {
|
||||
loop {
|
||||
if (exp & 1) == 1 {
|
||||
acc = acc.strict_mul(base);
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
if exp == 1 {
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
exp /= 2;
|
||||
base = base.strict_mul(base);
|
||||
}
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
// Deal with the final bit of the exponent separately, since
|
||||
// squaring the base afterwards is not necessary and may cause a
|
||||
// needless overflow.
|
||||
acc.strict_mul(base)
|
||||
}
|
||||
|
||||
/// Returns the square root of the number, rounded down.
|
||||
|
@ -2181,19 +2179,17 @@ macro_rules! int_impl {
|
|||
let mut base = self;
|
||||
let mut acc: Self = 1;
|
||||
|
||||
while exp > 1 {
|
||||
loop {
|
||||
if (exp & 1) == 1 {
|
||||
acc = acc.wrapping_mul(base);
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
if exp == 1 {
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
exp /= 2;
|
||||
base = base.wrapping_mul(base);
|
||||
}
|
||||
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
// Deal with the final bit of the exponent separately, since
|
||||
// squaring the base afterwards is not necessary and may cause a
|
||||
// needless overflow.
|
||||
acc.wrapping_mul(base)
|
||||
}
|
||||
|
||||
/// Calculates `self` + `rhs`
|
||||
|
@ -2687,9 +2683,14 @@ macro_rules! int_impl {
|
|||
// Scratch space for storing results of overflowing_mul.
|
||||
let mut r;
|
||||
|
||||
while exp > 1 {
|
||||
loop {
|
||||
if (exp & 1) == 1 {
|
||||
r = acc.overflowing_mul(base);
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
if exp == 1 {
|
||||
r.1 |= overflown;
|
||||
return r;
|
||||
}
|
||||
acc = r.0;
|
||||
overflown |= r.1;
|
||||
}
|
||||
|
@ -2698,14 +2699,6 @@ macro_rules! int_impl {
|
|||
base = r.0;
|
||||
overflown |= r.1;
|
||||
}
|
||||
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
// Deal with the final bit of the exponent separately, since
|
||||
// squaring the base afterwards is not necessary and may cause a
|
||||
// needless overflow.
|
||||
r = acc.overflowing_mul(base);
|
||||
r.1 |= overflown;
|
||||
r
|
||||
}
|
||||
|
||||
/// Raises self to the power of `exp`, using exponentiation by squaring.
|
||||
|
@ -2732,19 +2725,17 @@ macro_rules! int_impl {
|
|||
let mut base = self;
|
||||
let mut acc = 1;
|
||||
|
||||
while exp > 1 {
|
||||
loop {
|
||||
if (exp & 1) == 1 {
|
||||
acc = acc * base;
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
if exp == 1 {
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
exp /= 2;
|
||||
base = base * base;
|
||||
}
|
||||
|
||||
// since exp!=0, finally the exp must be 1.
|
||||
// Deal with the final bit of the exponent separately, since
|
||||
// squaring the base afterwards is not necessary and may cause a
|
||||
// needless overflow.
|
||||
acc * base
|
||||
}
|
||||
|
||||
/// Returns the square root of the number, rounded down.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue