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.

`