mirror of
https://github.com/golang/go
synced 2024-09-25 03:10:12 -06:00
cmd/compile: recognize more memory runs in generated algs
The old implementation assumed that all memory runs were terminated by non-memory fields. This isn't necessarily so. They might be terminated by padding or blank fields. For example, given type T struct { a int64 b byte c, d, e int64 } the old implementation did a memory comparison on a+b, on c, and on d+e. Instead, check for memory runs at the beginning of every round. This now generates a memory comparison on a+b and on c+d+e. Also, delete some now-dead code. Change-Id: I66bffb111420adf6919bd708e4fb3a1e1f07fadd Reviewed-on: https://go-review.googlesource.com/19841 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
0f5d78f678
commit
92bf58c238
@ -2515,7 +2515,8 @@ func genhash(sym *Sym, t *Type) {
|
||||
var na *Node
|
||||
var hashel *Node
|
||||
|
||||
for t1 := t.Type; ; t1 = t1.Down {
|
||||
t1 := t.Type
|
||||
for {
|
||||
first, size, next := memrun(t, t1)
|
||||
t1 = next
|
||||
|
||||
@ -2539,36 +2540,25 @@ func genhash(sym *Sym, t *Type) {
|
||||
break
|
||||
}
|
||||
if isblanksym(t1.Sym) {
|
||||
t1 = t1.Down
|
||||
continue
|
||||
}
|
||||
if algtype1(t1.Type, nil) == AMEM {
|
||||
// Our memory run might have been stopped by padding or a blank field.
|
||||
// If the next field is memory-ish, it could be the start of a new run.
|
||||
continue
|
||||
}
|
||||
|
||||
// Run hash for this field.
|
||||
if algtype1(t1.Type, nil) == AMEM {
|
||||
hashel = hashmem(t1.Type)
|
||||
hashel = hashfor(t1.Type)
|
||||
call = Nod(OCALL, hashel, nil)
|
||||
nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages?
|
||||
na = Nod(OADDR, nx, nil)
|
||||
na.Etype = 1 // no escape to heap
|
||||
call.List = list(call.List, na)
|
||||
call.List = list(call.List, nh)
|
||||
fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call))
|
||||
|
||||
// h = memhash(&p.t1, h, size)
|
||||
call = Nod(OCALL, hashel, nil)
|
||||
|
||||
nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages?
|
||||
na = Nod(OADDR, nx, nil)
|
||||
na.Etype = 1 // no escape to heap
|
||||
call.List = list(call.List, na)
|
||||
call.List = list(call.List, nh)
|
||||
call.List = list(call.List, Nodintconst(t1.Type.Width))
|
||||
fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call))
|
||||
} else {
|
||||
hashel = hashfor(t1.Type)
|
||||
|
||||
// h = hashel(&p.t1, h)
|
||||
call = Nod(OCALL, hashel, nil)
|
||||
|
||||
nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages?
|
||||
na = Nod(OADDR, nx, nil)
|
||||
na.Etype = 1 // no escape to heap
|
||||
call.List = list(call.List, na)
|
||||
call.List = list(call.List, nh)
|
||||
fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call))
|
||||
}
|
||||
t1 = t1.Down
|
||||
}
|
||||
}
|
||||
|
||||
@ -2730,7 +2720,8 @@ func geneq(sym *Sym, t *Type) {
|
||||
case TSTRUCT:
|
||||
var conjuncts []*Node
|
||||
|
||||
for t1 := t.Type; ; t1 = t1.Down {
|
||||
t1 := t.Type
|
||||
for {
|
||||
first, size, next := memrun(t, t1)
|
||||
t1 = next
|
||||
|
||||
@ -2756,11 +2747,18 @@ func geneq(sym *Sym, t *Type) {
|
||||
break
|
||||
}
|
||||
if isblanksym(t1.Sym) {
|
||||
t1 = t1.Down
|
||||
continue
|
||||
}
|
||||
if algtype1(t1.Type, nil) == AMEM {
|
||||
// Our memory run might have been stopped by padding or a blank field.
|
||||
// If the next field is memory-ish, it could be the start of a new run.
|
||||
continue
|
||||
}
|
||||
|
||||
// Check this field, which is not just memory.
|
||||
conjuncts = append(conjuncts, eqfield(np, nq, newname(t1.Sym)))
|
||||
t1 = t1.Down
|
||||
}
|
||||
|
||||
var and *Node
|
||||
|
Loading…
Reference in New Issue
Block a user