cmd/compile/internal/gc: avoid allocation in bnum
Although bnum was being called with a Bits value, a limitation
of the escape analyser (golang/go#12588) meant that taking the
address of the Bits.b array in the range statement caused the
formal parameter to escape to the heap.
Passing the a pointer to a Bits, as with all the other Bits helper
methods avoids the allocation.
Before:
BenchmarkBnum1-4 20000000 69.6 ns/op 32 B/op 1 allocs/op
After:
BenchmarkBnum1-4 100000000 10.1 ns/op 0 B/op 0 allocs/op
Change-Id: I673bd57ddc032ee67d09474156d795fb1ba72018
Reviewed-on: https://go-review.googlesource.com/14501
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/cmd/compile/internal/gc/reg.go b/src/cmd/compile/internal/gc/reg.go
index b3e9621..ff6ec32 100644
--- a/src/cmd/compile/internal/gc/reg.go
+++ b/src/cmd/compile/internal/gc/reg.go
@@ -170,7 +170,7 @@
for bany(&bit) {
// convert each bit to a variable
- i = bnum(bit)
+ i = bnum(&bit)
node = vars[i].node
n = int(vars[i].name)
@@ -1321,7 +1321,7 @@
bit.b[z] = LOAD(r, z) &^ (r.act.b[z] | addrs.b[z])
}
for bany(&bit) {
- i = bnum(bit)
+ i = bnum(&bit)
change = 0
paint1(f, i)
biclr(&bit, uint(i))
@@ -1465,7 +1465,7 @@
}
// bnum reports the lowest index of a 1 bit in a.
-func bnum(a Bits) int {
+func bnum(a *Bits) int {
for i, x := range &a.b { // & to avoid making a copy of a.b
if x != 0 {
return 64*i + Bitno(x)
@@ -1541,7 +1541,7 @@
var buf bytes.Buffer
sep := ""
for bany(&bits) {
- i := bnum(bits)
+ i := bnum(&bits)
buf.WriteString(sep)
sep = " "
v := &vars[i]