]> Cypherpunks repositories - gostls13.git/commitdiff
strconv: add comment explaining bounded shift in formatBits
authorMartin Möhrmann <moehrmann@google.com>
Sun, 6 May 2018 10:19:25 +0000 (12:19 +0200)
committerMartin Möhrmann <moehrmann@google.com>
Mon, 15 Oct 2018 21:45:52 +0000 (21:45 +0000)
The compiler can generate better code for shifts bounded to be less than 32
and thereby known to be less than any register width.
See https://golang.org/cl/109776.

Change-Id: I0c4c9f0faafa065fce3c10fd328830deb92f9e38
Reviewed-on: https://go-review.googlesource.com/c/111735
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/strconv/itoa.go

index 8afe7af2517db73bf1193b9e55f87b342954bec6..4aaf57830cf71c80e70faa77e68a7027c1ba7a16 100644 (file)
@@ -152,10 +152,14 @@ func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s
                }
 
        } else if isPowerOfTwo(base) {
-               // It is known that base is a power of two and
-               // 2 <= base <= len(digits).
                // Use shifts and masks instead of / and %.
-               shift := uint(bits.TrailingZeros(uint(base))) & 31
+               // Base is a power of 2 and 2 <= base <= len(digits) where len(digits) is 36.
+               // The largest power of 2 below or equal to 36 is 32, which is 1 << 5;
+               // i.e., the largest possible shift count is 5. By &-ind that value with
+               // the constant 7 we tell the compiler that the shift count is always
+               // less than 8 which is smaller than any register width. This allows
+               // the compiler to generate better code for the shift operation.
+               shift := uint(bits.TrailingZeros(uint(base))) & 7
                b := uint64(base)
                m := uint(base) - 1 // == 1<<shift - 1
                for u >= b {