mirror of
https://github.com/golang/go
synced 2024-11-12 02:00:23 -07:00
d71f36b5aa
After benchmarking with a compiler modified to have better spill location, it became clear that this method of checking was actually faster on (at least) two different architectures (ppc64 and amd64) and it also provides more timely interruption of loops. This change adds a modified FOR loop node "FORUNTIL" that checks after executing the loop body instead of before (i.e., always at least once). This ensures that a pointer past the end of a slice or array is not made visible to the garbage collector. Without the rescheduling checks inserted, the restructured loop from this change apparently provides a 1% geomean improvement on PPC64 running the go1 benchmarks; the improvement on AMD64 is only 0.12%. Inserting the rescheduling check exposed some peculiar bug with the ssa test code for s390x; this was updated based on initial code actually generated for GOARCH=s390x to use appropriate OpArg, OpAddr, and OpVarDef. NaCl is disabled in testing. Change-Id: Ieafaa9a61d2a583ad00968110ef3e7a441abca50 Reviewed-on: https://go-review.googlesource.com/36206 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
254 lines
7.1 KiB
Go
254 lines
7.1 KiB
Go
// +build amd64
|
|
// errorcheck -0 -d=ssa/loopbce/debug=3
|
|
|
|
package main
|
|
|
|
func f0a(a []int) int {
|
|
x := 0
|
|
for i := range a { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
x += a[i] // ERROR "Found redundant IsInBounds$"
|
|
}
|
|
return x
|
|
}
|
|
|
|
func f0b(a []int) int {
|
|
x := 0
|
|
for i := range a { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
b := a[i:] // ERROR "Found redundant IsSliceInBounds$"
|
|
x += b[0]
|
|
}
|
|
return x
|
|
}
|
|
|
|
func f0c(a []int) int {
|
|
x := 0
|
|
for i := range a { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
b := a[:i+1] // ERROR "Found redundant IsSliceInBounds \(len promoted to cap\)$"
|
|
x += b[0]
|
|
}
|
|
return x
|
|
}
|
|
|
|
func f1(a []int) int {
|
|
x := 0
|
|
for _, i := range a { // Change to "for i,e := range array/slice" hides IV report.
|
|
x += i
|
|
}
|
|
return x
|
|
}
|
|
|
|
func f2(a []int) int {
|
|
x := 0
|
|
for i := 1; i < len(a); i++ { // ERROR "Induction variable with minimum 1 and increment 1$"
|
|
x += a[i] // ERROR "Found redundant IsInBounds$"
|
|
}
|
|
return x
|
|
}
|
|
|
|
func f4(a [10]int) int {
|
|
x := 0
|
|
for i := 0; i < len(a); i += 2 { // ERROR "Induction variable with minimum 0 and increment 2$"
|
|
x += a[i] // ERROR "Found redundant IsInBounds$"
|
|
}
|
|
return x
|
|
}
|
|
|
|
func f5(a [10]int) int {
|
|
x := 0
|
|
for i := -10; i < len(a); i += 2 { // ERROR "Induction variable with minimum -10 and increment 2$"
|
|
x += a[i]
|
|
}
|
|
return x
|
|
}
|
|
|
|
func f6(a []int) {
|
|
for i := range a { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
b := a[0:i] // ERROR "Found redundant IsSliceInBounds \(len promoted to cap\)$"
|
|
f6(b)
|
|
}
|
|
}
|
|
|
|
func g0a(a string) int {
|
|
x := 0
|
|
for i := 0; i < len(a); i++ { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
x += int(a[i]) // ERROR "Found redundant IsInBounds$"
|
|
}
|
|
return x
|
|
}
|
|
|
|
func g0b(a string) int {
|
|
x := 0
|
|
for i := 0; len(a) > i; i++ { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
x += int(a[i]) // ERROR "Found redundant IsInBounds$"
|
|
}
|
|
return x
|
|
}
|
|
|
|
func g1() int {
|
|
a := "evenlength"
|
|
x := 0
|
|
for i := 0; i < len(a); i += 2 { // ERROR "Induction variable with minimum 0 and increment 2$"
|
|
x += int(a[i]) // ERROR "Found redundant IsInBounds$"
|
|
}
|
|
return x
|
|
}
|
|
|
|
func g2() int {
|
|
a := "evenlength"
|
|
x := 0
|
|
for i := 0; i < len(a); i += 2 { // ERROR "Induction variable with minimum 0 and increment 2$"
|
|
j := i
|
|
if a[i] == 'e' { // ERROR "Found redundant IsInBounds$"
|
|
j = j + 1
|
|
}
|
|
x += int(a[j])
|
|
}
|
|
return x
|
|
}
|
|
|
|
func g3a() {
|
|
a := "this string has length 25"
|
|
for i := 0; i < len(a); i += 5 { // ERROR "Induction variable with minimum 0 and increment 5$"
|
|
useString(a[i:]) // ERROR "Found redundant IsSliceInBounds$"
|
|
useString(a[:i+3])
|
|
}
|
|
}
|
|
|
|
func g3b(a string) {
|
|
for i := 0; i < len(a); i++ { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
useString(a[i+1:]) // ERROR "Found redundant IsSliceInBounds$"
|
|
}
|
|
}
|
|
|
|
func g3c(a string) {
|
|
for i := 0; i < len(a); i++ { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
useString(a[:i+1]) // ERROR "Found redundant IsSliceInBounds$"
|
|
}
|
|
}
|
|
|
|
func h1(a []byte) {
|
|
c := a[:128]
|
|
for i := range c { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
c[i] = byte(i) // ERROR "Found redundant IsInBounds$"
|
|
}
|
|
}
|
|
|
|
func h2(a []byte) {
|
|
for i := range a[:128] { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
a[i] = byte(i)
|
|
}
|
|
}
|
|
|
|
func k0(a [100]int) [100]int {
|
|
for i := 10; i < 90; i++ { // ERROR "Induction variable with minimum 10 and increment 1$"
|
|
a[i-11] = i
|
|
a[i-10] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 80$"
|
|
a[i-5] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 85$"
|
|
a[i] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 90$"
|
|
a[i+5] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 95$"
|
|
a[i+10] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 100$"
|
|
a[i+11] = i
|
|
}
|
|
return a
|
|
}
|
|
|
|
func k1(a [100]int) [100]int {
|
|
for i := 10; i < 90; i++ { // ERROR "Induction variable with minimum 10 and increment 1$"
|
|
useSlice(a[:i-11])
|
|
useSlice(a[:i-10]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 80$"
|
|
useSlice(a[:i-5]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 85$"
|
|
useSlice(a[:i]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 90$"
|
|
useSlice(a[:i+5]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 95$"
|
|
useSlice(a[:i+10]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 100$"
|
|
useSlice(a[:i+11]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 101$"
|
|
|
|
}
|
|
return a
|
|
}
|
|
|
|
func k2(a [100]int) [100]int {
|
|
for i := 10; i < 90; i++ { // ERROR "Induction variable with minimum 10 and increment 1$"
|
|
useSlice(a[i-11:])
|
|
useSlice(a[i-10:]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 80$"
|
|
useSlice(a[i-5:]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 85$"
|
|
useSlice(a[i:]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 90$"
|
|
useSlice(a[i+5:]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 95$"
|
|
useSlice(a[i+10:]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 100$"
|
|
useSlice(a[i+11:]) // ERROR "Found redundant \(IsSliceInBounds ind 100\), ind < 101$"
|
|
}
|
|
return a
|
|
}
|
|
|
|
func k3(a [100]int) [100]int {
|
|
for i := -10; i < 90; i++ { // ERROR "Induction variable with minimum -10 and increment 1$"
|
|
a[i+10] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 100$"
|
|
}
|
|
return a
|
|
}
|
|
|
|
func k4(a [100]int) [100]int {
|
|
min := (-1) << 63
|
|
for i := min; i < min+50; i++ { // ERROR "Induction variable with minimum -9223372036854775808 and increment 1$"
|
|
a[i-min] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 50$"
|
|
}
|
|
return a
|
|
}
|
|
|
|
func k5(a [100]int) [100]int {
|
|
max := (1 << 63) - 1
|
|
for i := max - 50; i < max; i++ { // ERROR "Induction variable with minimum 9223372036854775757 and increment 1$"
|
|
a[i-max+50] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 50$"
|
|
a[i-(max-70)] = i // ERROR "Found redundant \(IsInBounds ind 100\), ind < 70$"
|
|
}
|
|
return a
|
|
}
|
|
|
|
func nobce1() {
|
|
// tests overflow of max-min
|
|
a := int64(9223372036854774057)
|
|
b := int64(-1547)
|
|
z := int64(1337)
|
|
|
|
if a%z == b%z {
|
|
panic("invalid test: modulos should differ")
|
|
}
|
|
|
|
for i := b; i < a; i += z {
|
|
// No induction variable is possible because i will overflow a first iteration.
|
|
useString("foobar")
|
|
}
|
|
}
|
|
|
|
func nobce2(a string) {
|
|
for i := int64(0); i < int64(len(a)); i++ { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
useString(a[i:]) // ERROR "Found redundant IsSliceInBounds$"
|
|
}
|
|
for i := int64(0); i < int64(len(a))-31337; i++ { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
useString(a[i:]) // ERROR "Found redundant IsSliceInBounds$"
|
|
}
|
|
for i := int64(0); i < int64(len(a))+int64(-1<<63); i++ { // ERROR "Induction variable with minimum 0 and increment 1$"
|
|
// tests an overflow of StringLen-MinInt64
|
|
useString(a[i:])
|
|
}
|
|
}
|
|
|
|
func nobce3(a [100]int64) [100]int64 {
|
|
min := int64((-1) << 63)
|
|
max := int64((1 << 63) - 1)
|
|
for i := min; i < max; i++ { // ERROR "Induction variable with minimum -9223372036854775808 and increment 1$"
|
|
a[i] = i
|
|
}
|
|
return a
|
|
}
|
|
|
|
//go:noinline
|
|
func useString(a string) {
|
|
}
|
|
|
|
//go:noinline
|
|
func useSlice(a []int) {
|
|
}
|
|
|
|
func main() {
|
|
}
|