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:
parent
515bb0129d
commit
5322776215
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user