Skip to content

Commit e99e9a6

Browse files
committed
[dev.typeparams] cmd/compile: simplify ~r/~b naming
The compiler renames anonymous and blank result parameters to ~rN or ~bN, but the current semantics for computing N are rather annoying and difficult to reproduce cleanly. They also lead to difficult to read escape analysis results in tests. This CL changes N to always be calculated as the parameter's index within the function's result parameter tuple. E.g., if a function has a single result, it will now always be named "~r0". The normative change to this CL is fairly simple, but it requires updating a lot of test expectations. Change-Id: I58a3c94de00cb822cb94efe52d115531193c993c Reviewed-on: https://go-review.googlesource.com/c/go/+/323010 Trust: Matthew Dempsky <[email protected]> Trust: Dan Scales <[email protected]> Run-TryBot: Matthew Dempsky <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Dan Scales <[email protected]>
1 parent 4c68edd commit e99e9a6

File tree

17 files changed

+101
-102
lines changed

17 files changed

+101
-102
lines changed

src/cmd/compile/internal/logopt/logopt_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func s15a8(x *[15]int64) [15]int64 {
209209
want(t, slogged, `{"range":{"start":{"line":11,"character":6},"end":{"line":11,"character":6}},"severity":3,"code":"isInBounds","source":"go compiler","message":""}`)
210210
want(t, slogged, `{"range":{"start":{"line":7,"character":6},"end":{"line":7,"character":6}},"severity":3,"code":"canInlineFunction","source":"go compiler","message":"cost: 35"}`)
211211
// escape analysis explanation
212-
want(t, slogged, `{"range":{"start":{"line":7,"character":13},"end":{"line":7,"character":13}},"severity":3,"code":"leak","source":"go compiler","message":"parameter z leaks to ~r2 with derefs=0",`+
212+
want(t, slogged, `{"range":{"start":{"line":7,"character":13},"end":{"line":7,"character":13}},"severity":3,"code":"leak","source":"go compiler","message":"parameter z leaks to ~r0 with derefs=0",`+
213213
`"relatedInformation":[`+
214214
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: flow: y = z:"},`+
215215
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from y := z (assign-pair)"},`+
@@ -220,7 +220,7 @@ func s15a8(x *[15]int64) [15]int64 {
220220
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from \u0026y.b (address-of)"},`+
221221
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":9},"end":{"line":4,"character":9}}},"message":"inlineLoc"},`+
222222
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from ~R0 = \u0026y.b (assign-pair)"},`+
223-
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow: flow: ~r2 = ~R0:"},`+
223+
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow: flow: ~r0 = ~R0:"},`+
224224
`{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow: from return (*int)(~R0) (return)"}]}`)
225225
})
226226
}

src/cmd/compile/internal/noder/object.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,21 @@ func (g *irgen) obj(obj types2.Object) *ir.Name {
113113
}
114114

115115
case *types2.Var:
116-
var sym *types.Sym
117-
if class == ir.PPARAMOUT {
116+
sym := g.sym(obj)
117+
if class == ir.PPARAMOUT && (sym == nil || sym.IsBlank()) {
118118
// Backend needs names for result parameters,
119119
// even if they're anonymous or blank.
120-
switch obj.Name() {
121-
case "":
122-
sym = typecheck.LookupNum("~r", len(ir.CurFunc.Dcl)) // 'r' for "result"
123-
case "_":
124-
sym = typecheck.LookupNum("~b", len(ir.CurFunc.Dcl)) // 'b' for "blank"
120+
nresults := 0
121+
for _, n := range ir.CurFunc.Dcl {
122+
if n.Class == ir.PPARAMOUT {
123+
nresults++
124+
}
125+
}
126+
if sym == nil {
127+
sym = typecheck.LookupNum("~r", nresults) // 'r' for "result"
128+
} else {
129+
sym = typecheck.LookupNum("~b", nresults) // 'b' for "blank"
125130
}
126-
}
127-
if sym == nil {
128-
sym = g.sym(obj)
129131
}
130132
name = g.objCommon(pos, ir.ONAME, sym, class, g.typ(obj.Type()))
131133

src/cmd/compile/internal/typecheck/dcl.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,10 @@ func funcargs(nt *ir.FuncType) {
353353
}
354354

355355
// declare the out arguments.
356-
gen := len(nt.Params)
357-
for _, n := range nt.Results {
356+
for i, n := range nt.Results {
358357
if n.Sym == nil {
359358
// Name so that escape analysis can track it. ~r stands for 'result'.
360-
n.Sym = LookupNum("~r", gen)
361-
gen++
359+
n.Sym = LookupNum("~r", i)
362360
}
363361
if n.Sym.IsBlank() {
364362
// Give it a name so we can assign to it during return. ~b stands for 'blank'.
@@ -367,8 +365,7 @@ func funcargs(nt *ir.FuncType) {
367365
// func g() int
368366
// f is allowed to use a plain 'return' with no arguments, while g is not.
369367
// So the two cases must be distinguished.
370-
n.Sym = LookupNum("~b", gen)
371-
gen++
368+
n.Sym = LookupNum("~b", i)
372369
}
373370

374371
funcarg(n, ir.PPARAMOUT)

test/escape2.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func foo8(xx, yy *int) int { // ERROR "xx does not escape$" "yy does not escape$
5959
return *xx
6060
}
6161

62-
func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r2 level=0$" "leaking param: yy to result ~r2 level=0$"
62+
func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r0 level=0$" "leaking param: yy to result ~r0 level=0$"
6363
xx = yy
6464
return xx
6565
}
@@ -343,11 +343,11 @@ func indaddr1(x int) *int { // ERROR "moved to heap: x$"
343343
return &x
344344
}
345345

346-
func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
346+
func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
347347
return *&x
348348
}
349349

350-
func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 level=0$"
350+
func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r0 level=0$"
351351
return *(**int)(unsafe.Pointer(&x))
352352
}
353353

@@ -374,11 +374,11 @@ func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
374374
return (*uint64)(unsafe.Pointer(&f))
375375
}
376376

377-
func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r1 level=0$"
377+
func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r0 level=0$"
378378
return (*uint64)(unsafe.Pointer(f))
379379
}
380380

381-
func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level=0$"
381+
func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r0 level=0$"
382382
switch val := i.(type) {
383383
case *int:
384384
return val
@@ -389,7 +389,7 @@ func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level
389389
return nil
390390
}
391391

392-
func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
392+
func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
393393
switch j := i; *j + 110 {
394394
case 12:
395395
return j
@@ -401,7 +401,7 @@ func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
401401
}
402402

403403
// assigning to an array element is like assigning to the array
404-
func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
404+
func foo60(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
405405
var a [12]*int
406406
a[0] = i
407407
return a[1]
@@ -414,7 +414,7 @@ func foo60a(i *int) *int { // ERROR "i does not escape$"
414414
}
415415

416416
// assigning to a struct field is like assigning to the struct
417-
func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
417+
func foo61(i *int) *int { // ERROR "leaking param: i to result ~r0 level=0$"
418418
type S struct {
419419
a, b *int
420420
}
@@ -611,11 +611,11 @@ func foo74c() {
611611
}
612612
}
613613

614-
func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "x does not escape$"
614+
func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r0 level=0$" "x does not escape$"
615615
return y
616616
}
617617

618-
func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "y does not escape$"
618+
func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r0 level=0$" "y does not escape$"
619619
return &x[0]
620620
}
621621

@@ -770,7 +770,7 @@ func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
770770
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
771771
}
772772

773-
func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
773+
func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r0 level=0$"
774774
return [2]*int{x, nil}
775775
}
776776

@@ -783,7 +783,7 @@ func foo93(c chan *int) *int { // ERROR "c does not escape$"
783783
}
784784

785785
// does not leak m
786-
func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1"
786+
func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r0 level=1"
787787
for k, v := range m {
788788
if b {
789789
return k
@@ -799,12 +799,12 @@ func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape$" "leaking par
799799
}
800800

801801
// does not leak m but does leak content
802-
func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
802+
func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r0 level=1"
803803
return m[0]
804804
}
805805

806806
// does leak m
807-
func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
807+
func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r0 level=0$"
808808
return m[0]
809809
}
810810

@@ -814,20 +814,20 @@ func foo98(m map[int]*int) *int { // ERROR "m does not escape$"
814814
}
815815

816816
// does leak m
817-
func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$"
817+
func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r0 level=0$"
818818
return m[:]
819819
}
820820

821821
// does not leak m
822-
func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
822+
func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r0 level=1"
823823
for _, v := range m {
824824
return v
825825
}
826826
return nil
827827
}
828828

829829
// does leak m
830-
func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
830+
func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r0 level=0$"
831831
for _, v := range m {
832832
return v
833833
}
@@ -890,27 +890,27 @@ func foo110(x *int) *int { // ERROR "leaking param: x$"
890890
return m[nil]
891891
}
892892

893-
func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
893+
func foo111(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0"
894894
m := []*int{x} // ERROR "\[\]\*int{...} does not escape$"
895895
return m[0]
896896
}
897897

898-
func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
898+
func foo112(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
899899
m := [1]*int{x}
900900
return m[0]
901901
}
902902

903-
func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
903+
func foo113(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
904904
m := Bar{ii: x}
905905
return m.ii
906906
}
907907

908-
func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
908+
func foo114(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
909909
m := &Bar{ii: x} // ERROR "&Bar{...} does not escape$"
910910
return m.ii
911911
}
912912

913-
func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
913+
func foo115(x *int) *int { // ERROR "leaking param: x to result ~r0 level=0$"
914914
return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
915915
}
916916

0 commit comments

Comments
 (0)