This is the escape analysis analog of CL 37499.
Fixes #12397
Fixes #16871
The only "moved to heap" decisions eliminated by this
CL in std+cmd are:
cmd/compile/internal/gc/const.go:1514: moved to heap: ac
cmd/compile/internal/gc/const.go:1515: moved to heap: bd
cmd/compile/internal/gc/const.go:1516: moved to heap: bc
cmd/compile/internal/gc/const.go:1517: moved to heap: ad
cmd/compile/internal/gc/const.go:1546: moved to heap: ac
cmd/compile/internal/gc/const.go:1547: moved to heap: bd
cmd/compile/internal/gc/const.go:1548: moved to heap: bc
cmd/compile/internal/gc/const.go:1549: moved to heap: ad
cmd/compile/internal/gc/const.go:1550: moved to heap: cc_plus
cmd/compile/internal/gc/export.go:162: moved to heap: copy
cmd/compile/internal/gc/mpfloat.go:66: moved to heap: b
cmd/compile/internal/gc/mpfloat.go:97: moved to heap: b
Change-Id: I0d420b69c84a41ba9968c394e8957910bab5edea
Reviewed-on: https://go-review.googlesource.com/37508
Reviewed-by: David Chase <drchase@google.com>
e.escassignSinkWhy(n, n, "too large for stack") // TODO category: tooLarge
}
- e.esc(n.Left, n)
- e.esc(n.Right, n)
- e.esclist(n.Nbody, n)
- e.esclist(n.List, n)
- e.esclist(n.Rlist, n)
+ if n.Op == OIF && Isconst(n.Left, CTBOOL) {
+ // Don't examine dead code.
+ if n.Left.Bool() {
+ e.esclist(n.Nbody, n)
+ } else {
+ e.esclist(n.Rlist, n)
+ }
+ } else {
+ e.esc(n.Left, n)
+ e.esc(n.Right, n)
+ e.esclist(n.Nbody, n)
+ e.esclist(n.List, n)
+ e.esclist(n.Rlist, n)
+ }
if n.Op == OFOR || n.Op == ORANGE {
e.loopdepth--
copy(slice2, slice1)
return slice2[0]
}
+
+func issue12397(x, y int) { // ERROR "moved to heap: y$"
+ // x does not escape below, because all relevant code is dead.
+ if false {
+ gxx = &x
+ } else {
+ gxx = &y // ERROR "&y escapes to heap$"
+ }
+
+ if true {
+ gxx = &y // ERROR "&y escapes to heap$"
+ } else {
+ gxx = &x
+ }
+}