diff options
author | David Chase <drchase@google.com> | 2017-06-21 17:19:24 -0400 |
---|---|---|
committer | David Chase <drchase@google.com> | 2017-06-21 22:07:33 +0000 |
commit | 0b6fbaae6ec4218fc35d8a6f4415ae8f88198301 (patch) | |
tree | 190fe7f95117686fd55fb86e1d73c5554fe53023 | |
parent | c4e0e816531b679b3e6581e469279df813a9ea3d (diff) | |
download | go-0b6fbaae6ec4218fc35d8a6f4415ae8f88198301.tar.gz go-0b6fbaae6ec4218fc35d8a6f4415ae8f88198301.zip |
cmd/compile: make loop guard+rotate conditional on GOEXPERIMENT
Loops of the form "for i,e := range" needed to have their
condition rotated to the "bottom" for the preemptible loops
GOEXPERIMENT, but this caused a performance regression
because it degraded bounds check removal. For now, make
the loop rotation/guarding conditional on the experiment.
Fixes #20711.
Updates #10958.
Change-Id: Icfba14cb3b13a910c349df8f84838cf4d9d20cf6
Reviewed-on: https://go-review.googlesource.com/46410
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
-rw-r--r-- | src/cmd/compile/internal/gc/range.go | 11 | ||||
-rw-r--r-- | test/loopbce.go | 2 |
2 files changed, 9 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index 963c26824d..032601ca3d 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -6,6 +6,7 @@ package gc import ( "cmd/compile/internal/types" + "cmd/internal/objabi" "unicode/utf8" ) @@ -211,9 +212,13 @@ func walkrange(n *Node) *Node { } else if v2 == nil { body = []*Node{nod(OAS, v1, hv1)} } else { // for i,a := range thing { body } - ifGuard = nod(OIF, nil, nil) - ifGuard.Left = nod(OLT, hv1, hn) - translatedLoopOp = OFORUNTIL + if objabi.Preemptibleloops_enabled != 0 { + // Doing this transformation makes a bounds check removal less trivial; see #20711 + // TODO enhance the preemption check insertion so that this transformation is not necessary. + ifGuard = nod(OIF, nil, nil) + ifGuard.Left = nod(OLT, hv1, hn) + translatedLoopOp = OFORUNTIL + } a := nod(OAS2, nil, nil) a.List.Set2(v1, v2) diff --git a/test/loopbce.go b/test/loopbce.go index 63bb4bae58..857cf2442b 100644 --- a/test/loopbce.go +++ b/test/loopbce.go @@ -31,7 +31,7 @@ func f0c(a []int) int { func f1(a []int) int { x := 0 - for _, i := range a { // Change to "for i,e := range array/slice" hides IV report. + for _, i := range a { // ERROR "Induction variable with minimum 0 and increment 1" x += i } return x |