1
0
mirror of https://github.com/golang/go synced 2024-11-26 08:48:13 -07:00

cmd/compile: make isfat handle 1-element array, 1-field struct

This will improve liveness analysis slightly, the same logic as
isdirectiface curently does. In:

	type T struct {
	    m map[int]int
	}

        v := T{}
        v.m = make(map[int]int)

T is considered "fat", now it is not. So assigning to v.m is considered
to clobber the entire v.

This is follow up of CL 179057.

Change-Id: Id6b4807b8e8521ef5d8bcb14fedb6dceb9dbf18c
Reviewed-on: https://go-review.googlesource.com/c/go/+/179578
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
LE Manh Cuong 2019-05-30 13:01:03 +07:00 committed by Matthew Dempsky
parent 515bb0129d
commit 5322776215
3 changed files with 16 additions and 4 deletions

View File

@ -1453,9 +1453,21 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap {
func isfat(t *types.Type) bool { func isfat(t *types.Type) bool {
if t != nil { if t != nil {
switch t.Etype { switch t.Etype {
case TSTRUCT, TARRAY, TSLICE, TSTRING, case TSLICE, TSTRING,
TINTER: // maybe remove later TINTER: // maybe remove later
return true return true
case TARRAY:
// Array of 1 element, check if element is fat
if t.NumElem() == 1 {
return isfat(t.Elem())
}
return true
case TSTRUCT:
// Struct with 1 field, check if field is fat
if t.NumFields() == 1 {
return isfat(t.Field(0).Type)
}
return true
} }
} }

View File

@ -659,7 +659,7 @@ func bad40() {
func good40() { func good40() {
ret := T40{} // ERROR "stack object ret T40$" ret := T40{} // ERROR "stack object ret T40$"
ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+ ret$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$" ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
t := &ret t := &ret
printnl() // ERROR "live at call to printnl: ret$" printnl() // ERROR "live at call to printnl: ret$"
// Note: ret is live at the printnl because the compiler moves &ret // Note: ret is live at the printnl because the compiler moves &ret

View File

@ -27,14 +27,14 @@ func newT40() *T40 {
} }
func bad40() { func bad40() {
t := newT40() // ERROR "live at call to makemap: ret$" "stack object ret T40$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$" t := newT40() // ERROR "stack object ret T40$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
printnl() // ERROR "live at call to printnl: ret$" printnl() // ERROR "live at call to printnl: ret$"
useT40(t) useT40(t)
} }
func good40() { func good40() {
ret := T40{} // ERROR "stack object ret T40$" ret := T40{} // ERROR "stack object ret T40$"
ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: ret$" "stack object .autotmp_[0-9]+ map.hdr\[int\]int$" ret.m = make(map[int]int, 42) // ERROR "stack object .autotmp_[0-9]+ map.hdr\[int\]int$"
t := &ret t := &ret
printnl() // ERROR "live at call to printnl: ret$" printnl() // ERROR "live at call to printnl: ret$"
useT40(t) useT40(t)