Optimize integer pow by removing exit branch · rust-lang/rust@76d2530 (original) (raw)
`@@ -1416,18 +1416,17 @@ macro_rules! int_impl {
`
1416
1416
`let mut base = self;
`
1417
1417
`let mut acc: Self = 1;
`
1418
1418
``
1419
``
`-
while exp > 1 {
`
``
1419
`+
loop {
`
1420
1420
`if (exp & 1) == 1 {
`
1421
1421
` acc = try_opt!(acc.checked_mul(base));
`
``
1422
`+
// since exp!=0, finally the exp must be 1.
`
``
1423
`+
if exp == 1 {
`
``
1424
`+
return Some(acc);
`
``
1425
`+
}
`
1422
1426
`}
`
1423
1427
` exp /= 2;
`
1424
1428
` base = try_opt!(base.checked_mul(base));
`
1425
1429
`}
`
1426
``
`-
// since exp!=0, finally the exp must be 1.
`
1427
``
`-
// Deal with the final bit of the exponent separately, since
`
1428
``
`-
// squaring the base afterwards is not necessary and may cause a
`
1429
``
`-
// needless overflow.
`
1430
``
`-
acc.checked_mul(base)
`
1431
1430
`}
`
1432
1431
``
1433
1432
`` /// Strict exponentiation. Computes self.pow(exp)
, panicking if
``
`@@ -1467,18 +1466,17 @@ macro_rules! int_impl {
`
1467
1466
`let mut base = self;
`
1468
1467
`let mut acc: Self = 1;
`
1469
1468
``
1470
``
`-
while exp > 1 {
`
``
1469
`+
loop {
`
1471
1470
`if (exp & 1) == 1 {
`
1472
1471
` acc = acc.strict_mul(base);
`
``
1472
`+
// since exp!=0, finally the exp must be 1.
`
``
1473
`+
if exp == 1 {
`
``
1474
`+
return acc;
`
``
1475
`+
}
`
1473
1476
`}
`
1474
1477
` exp /= 2;
`
1475
1478
` base = base.strict_mul(base);
`
1476
1479
`}
`
1477
``
`-
// since exp!=0, finally the exp must be 1.
`
1478
``
`-
// Deal with the final bit of the exponent separately, since
`
1479
``
`-
// squaring the base afterwards is not necessary and may cause a
`
1480
``
`-
// needless overflow.
`
1481
``
`-
acc.strict_mul(base)
`
1482
1480
`}
`
1483
1481
``
1484
1482
`/// Returns the square root of the number, rounded down.
`
`@@ -2102,19 +2100,17 @@ macro_rules! int_impl {
`
2102
2100
`let mut base = self;
`
2103
2101
`let mut acc: Self = 1;
`
2104
2102
``
2105
``
`-
while exp > 1 {
`
``
2103
`+
loop {
`
2106
2104
`if (exp & 1) == 1 {
`
2107
2105
` acc = acc.wrapping_mul(base);
`
``
2106
`+
// since exp!=0, finally the exp must be 1.
`
``
2107
`+
if exp == 1 {
`
``
2108
`+
return acc;
`
``
2109
`+
}
`
2108
2110
`}
`
2109
2111
` exp /= 2;
`
2110
2112
` base = base.wrapping_mul(base);
`
2111
2113
`}
`
2112
``
-
2113
``
`-
// since exp!=0, finally the exp must be 1.
`
2114
``
`-
// Deal with the final bit of the exponent separately, since
`
2115
``
`-
// squaring the base afterwards is not necessary and may cause a
`
2116
``
`-
// needless overflow.
`
2117
``
`-
acc.wrapping_mul(base)
`
2118
2114
`}
`
2119
2115
``
2120
2116
`` /// Calculates self
+ rhs
``
`@@ -2608,9 +2604,14 @@ macro_rules! int_impl {
`
2608
2604
`// Scratch space for storing results of overflowing_mul.
`
2609
2605
`let mut r;
`
2610
2606
``
2611
``
`-
while exp > 1 {
`
``
2607
`+
loop {
`
2612
2608
`if (exp & 1) == 1 {
`
2613
2609
` r = acc.overflowing_mul(base);
`
``
2610
`+
// since exp!=0, finally the exp must be 1.
`
``
2611
`+
if exp == 1 {
`
``
2612
`+
r.1 |= overflown;
`
``
2613
`+
return r;
`
``
2614
`+
}
`
2614
2615
` acc = r.0;
`
2615
2616
` overflown |= r.1;
`
2616
2617
`}
`
`@@ -2619,14 +2620,6 @@ macro_rules! int_impl {
`
2619
2620
` base = r.0;
`
2620
2621
` overflown |= r.1;
`
2621
2622
`}
`
2622
``
-
2623
``
`-
// since exp!=0, finally the exp must be 1.
`
2624
``
`-
// Deal with the final bit of the exponent separately, since
`
2625
``
`-
// squaring the base afterwards is not necessary and may cause a
`
2626
``
`-
// needless overflow.
`
2627
``
`-
r = acc.overflowing_mul(base);
`
2628
``
`-
r.1 |= overflown;
`
2629
``
`-
r
`
2630
2623
`}
`
2631
2624
``
2632
2625
`` /// Raises self to the power of exp
, using exponentiation by squaring.
``
`@@ -2653,19 +2646,17 @@ macro_rules! int_impl {
`
2653
2646
`let mut base = self;
`
2654
2647
`let mut acc = 1;
`
2655
2648
``
2656
``
`-
while exp > 1 {
`
``
2649
`+
loop {
`
2657
2650
`if (exp & 1) == 1 {
`
2658
2651
` acc = acc * base;
`
``
2652
`+
// since exp!=0, finally the exp must be 1.
`
``
2653
`+
if exp == 1 {
`
``
2654
`+
return acc;
`
``
2655
`+
}
`
2659
2656
`}
`
2660
2657
` exp /= 2;
`
2661
2658
` base = base * base;
`
2662
2659
`}
`
2663
``
-
2664
``
`-
// since exp!=0, finally the exp must be 1.
`
2665
``
`-
// Deal with the final bit of the exponent separately, since
`
2666
``
`-
// squaring the base afterwards is not necessary and may cause a
`
2667
``
`-
// needless overflow.
`
2668
``
`-
acc * base
`
2669
2660
`}
`
2670
2661
``
2671
2662
`/// Returns the square root of the number, rounded down.
`