Commit 60c76f76 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: optimize bvec routines

The recent improvements to the prove pass
make it possible to provide bounds
hints to the compiler in some bvec routines.

This speeds up the compilation of the code in

name  old time/op       new time/op       delta
Pkg         7.93s ± 4%        7.69s ± 3%  -2.98%  (p=0.000 n=29+26)

While we're here, clean up some C-isms.

Updates #13554
Updates #20393

Change-Id: I47a0ec68543a9fc95c5359c3f37813fb529cb4f0
Reviewed-on: https://go-review.googlesource.com/110560
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent d91e9705
...@@ -118,8 +118,8 @@ func (bv bvec) Next(i int32) int32 { ...@@ -118,8 +118,8 @@ func (bv bvec) Next(i int32) int32 {
} }
func (bv bvec) IsEmpty() bool { func (bv bvec) IsEmpty() bool {
for i := int32(0); i < bv.n; i += wordBits { for _, x := range bv.b {
if bv.b[i>>wordShift] != 0 { if x != 0 {
return false return false
} }
} }
...@@ -127,15 +127,18 @@ func (bv bvec) IsEmpty() bool { ...@@ -127,15 +127,18 @@ func (bv bvec) IsEmpty() bool {
} }
func (bv bvec) Not() { func (bv bvec) Not() {
i := int32(0) for i, x := range bv.b {
w := int32(0) bv.b[i] = ^x
for ; i < bv.n; i, w = i+wordBits, w+1 {
bv.b[w] = ^bv.b[w]
} }
} }
// union // union
func (dst bvec) Or(src1, src2 bvec) { func (dst bvec) Or(src1, src2 bvec) {
if len(src1.b) == 0 {
return
}
_, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
for i, x := range src1.b { for i, x := range src1.b {
dst.b[i] = x | src2.b[i] dst.b[i] = x | src2.b[i]
} }
...@@ -143,6 +146,11 @@ func (dst bvec) Or(src1, src2 bvec) { ...@@ -143,6 +146,11 @@ func (dst bvec) Or(src1, src2 bvec) {
// intersection // intersection
func (dst bvec) And(src1, src2 bvec) { func (dst bvec) And(src1, src2 bvec) {
if len(src1.b) == 0 {
return
}
_, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
for i, x := range src1.b { for i, x := range src1.b {
dst.b[i] = x & src2.b[i] dst.b[i] = x & src2.b[i]
} }
...@@ -150,6 +158,11 @@ func (dst bvec) And(src1, src2 bvec) { ...@@ -150,6 +158,11 @@ func (dst bvec) And(src1, src2 bvec) {
// difference // difference
func (dst bvec) AndNot(src1, src2 bvec) { func (dst bvec) AndNot(src1, src2 bvec) {
if len(src1.b) == 0 {
return
}
_, _ = dst.b[len(src1.b)-1], src2.b[len(src1.b)-1] // hoist bounds checks out of the loop
for i, x := range src1.b { for i, x := range src1.b {
dst.b[i] = x &^ src2.b[i] dst.b[i] = x &^ src2.b[i]
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment