mirror of
https://github.com/golang/go
synced 2024-09-05 16:04:50 +00:00
![David Chase](/assets/img/avatar_default.png)
Loop breaking with a counter. Benchmarked (see comments), eyeball checked for sanity on popular loops. This code ought to handle loops in general, and properly inserts phi functions in cases where the earlier version might not have. Includes test, plus modifications to test/run.go to deal with timeout and killing looping test. Tests broken by the addition of extra code (branch frequency and live vars) for added checks turn the check insertion off. If GOEXPERIMENT=preemptibleloops, the compiler inserts reschedule checks on every backedge of every reducible loop. Alternately, specifying GO_GCFLAGS=-d=ssa/insert_resched_checks/on will enable it for a single compilation, but because the core Go libraries contain some loops that may run long, this is less likely to have the desired effect. This is intended as a tool to help in the study and diagnosis of GC and other latency problems, now that goal STW GC latency is on the order of 100 microseconds or less. Updates #17831. Updates #10958. Change-Id: I6206c163a5b0248e3f21eb4fc65f73a179e1f639 Reviewed-on: https://go-review.googlesource.com/33910 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
87 lines
2.1 KiB
Go
87 lines
2.1 KiB
Go
// +build amd64
|
|
// errorcheck -0 -d=ssa/likelyadjust/debug=1,ssa/insert_resched_checks/off
|
|
// rescheduling check insertion is turend off because the inserted conditional branches perturb the errorcheck
|
|
|
|
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Test that branches have some prediction properties.
|
|
package foo
|
|
|
|
func f(x, y, z int) int {
|
|
a := 0
|
|
for i := 0; i < x; i++ { // ERROR "Branch prediction rule stay in loop"
|
|
for j := 0; j < y; j++ { // ERROR "Branch prediction rule stay in loop"
|
|
a += j
|
|
}
|
|
for k := 0; k < z; k++ { // ERROR "Branch prediction rule stay in loop"
|
|
a -= x + y + z
|
|
}
|
|
}
|
|
return a
|
|
}
|
|
|
|
func g(x, y, z int) int {
|
|
a := 0
|
|
if y == 0 { // ERROR "Branch prediction rule default < call"
|
|
y = g(y, z, x)
|
|
} else {
|
|
y++
|
|
}
|
|
if y == x { // ERROR "Branch prediction rule default < call"
|
|
y = g(y, z, x)
|
|
} else {
|
|
}
|
|
if y == 2 { // ERROR "Branch prediction rule default < call"
|
|
z++
|
|
} else {
|
|
y = g(z, x, y)
|
|
}
|
|
if y+z == 3 { // ERROR "Branch prediction rule call < exit"
|
|
println("ha ha")
|
|
} else {
|
|
panic("help help help")
|
|
}
|
|
if x != 0 { // ERROR "Branch prediction rule default < ret"
|
|
for i := 0; i < x; i++ { // ERROR "Branch prediction rule stay in loop"
|
|
if x == 4 { // ERROR "Branch prediction rule stay in loop"
|
|
return a
|
|
}
|
|
for j := 0; j < y; j++ { // ERROR "Branch prediction rule stay in loop"
|
|
for k := 0; k < z; k++ { // ERROR "Branch prediction rule stay in loop"
|
|
a -= j * i
|
|
}
|
|
a += j
|
|
}
|
|
}
|
|
}
|
|
return a
|
|
}
|
|
|
|
func h(x, y, z int) int {
|
|
a := 0
|
|
for i := 0; i < x; i++ { // ERROR "Branch prediction rule stay in loop"
|
|
for j := 0; j < y; j++ { // ERROR "Branch prediction rule stay in loop"
|
|
a += j
|
|
if i == j { // ERROR "Branch prediction rule stay in loop"
|
|
break
|
|
}
|
|
a *= j
|
|
}
|
|
for k := 0; k < z; k++ { // ERROR "Branch prediction rule stay in loop"
|
|
a -= k
|
|
if i == k {
|
|
continue
|
|
}
|
|
a *= k
|
|
}
|
|
}
|
|
if a > 0 { // ERROR "Branch prediction rule default < call"
|
|
a = g(x, y, z)
|
|
} else {
|
|
a = -a
|
|
}
|
|
return a
|
|
}
|