aboutsummaryrefslogtreecommitdiff
path: root/test/sliceopt.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2016-10-25 15:49:52 -0700
committerKeith Randall <khr@golang.org>2016-10-27 20:22:49 +0000
commitdeb4177cf0b8352f4908c0eba9e81dfb0213545c (patch)
tree7ce0c1d471b5d7aeeeeb7d6eb699c3a97888d8df /test/sliceopt.go
parent50f66fbb66c2f3cdfc9f942c5e11cc1b9ec17a73 (diff)
downloadgo-deb4177cf0b8352f4908c0eba9e81dfb0213545c.tar.gz
go-deb4177cf0b8352f4908c0eba9e81dfb0213545c.zip
cmd/compile: use masks instead of branches for slicing
When we do var x []byte = ... y := x[i:] We can't just use y.ptr = x.ptr + i, as the new pointer may point to the next object in memory after the backing array. We used to fix this by doing: y.cap = x.cap - i delta := i if y.cap == 0 { delta = 0 } y.ptr = x.ptr + delta That generates a branch in what is otherwise straight-line code. Better to do: y.cap = x.cap - i mask := (y.cap - 1) >> 63 // -1 if y.cap==0, 0 otherwise y.ptr = x.ptr + i &^ mask It's about the same number of instructions (~4, depending on what parts are constant, and the target architecture), but it is all inline. It plays nicely with CSE, and the mask can be computed in parallel with the index (in cases where a multiply is required). It is a minor win in both speed and space. Change-Id: Ied60465a0b8abb683c02208402e5bb7ac0e8370f Reviewed-on: https://go-review.googlesource.com/32022 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'test/sliceopt.go')
-rw-r--r--test/sliceopt.go9
1 files changed, 5 insertions, 4 deletions
diff --git a/test/sliceopt.go b/test/sliceopt.go
index 17959e9326..eb24701f31 100644
--- a/test/sliceopt.go
+++ b/test/sliceopt.go
@@ -43,10 +43,11 @@ func s1(x **[]int, xs **string, i, j int) {
z = (**x)[i:0:j] // ERROR "Disproved IsSliceInBounds$"
z = (**x)[0:i:j] // ERROR "Proved boolean IsSliceInBounds$"
z = (**x)[0:] // ERROR "slice: omit slice operation$"
- z = (**x)[2:8] // ERROR "Disproved Eq(32|64)$"
- z = (**x)[2:2] // ERROR "Disproved Eq(32|64)$" "Proved boolean IsSliceInBounds$"
- z = (**x)[0:i] // ERROR "Proved boolean IsSliceInBounds$"
- z = (**x)[2:i:8] // ERROR "Disproved IsSliceInBounds$" "Proved IsSliceInBounds$" "Proved boolean IsSliceInBounds$"
+ z = (**x)[2:8] // ERROR "Proved slicemask not needed$"
+ println(z)
+ z = (**x)[2:2]
+ z = (**x)[0:i]
+ z = (**x)[2:i:8] // ERROR "Disproved IsSliceInBounds$" "Proved IsSliceInBounds$"
z = (**x)[i:2:i] // ERROR "Proved IsSliceInBounds$" "Proved boolean IsSliceInBounds$"
z = z[0:i] // ERROR "Proved boolean IsSliceInBounds"