Commit 0f5d78f6 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: factor shared code from geneq and genhash

Passes toolstash -cmp.

Change-Id: Ifae69e5ba673f01da3dfc1fd30cdc51873481623
Reviewed-on: https://go-review.googlesource.com/19840Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 3c0fae53
...@@ -2507,35 +2507,20 @@ func genhash(sym *Sym, t *Type) { ...@@ -2507,35 +2507,20 @@ func genhash(sym *Sym, t *Type) {
fn.Nbody = list(fn.Nbody, n) fn.Nbody = list(fn.Nbody, n)
// Walk the struct using memhash for runs of AMEM // Walk the struct using memhash for runs of AMEM
// and calling specific hash functions for the others. // and calling specific hash functions for the others.
case TSTRUCT: case TSTRUCT:
var first *Type
offend := int64(0)
var size int64
var call *Node var call *Node
var nx *Node var nx *Node
var na *Node var na *Node
var hashel *Node var hashel *Node
for t1 := t.Type; ; t1 = t1.Down {
if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) {
offend = t1.Width + t1.Type.Width
if first == nil {
first = t1
}
// If it's a memory field but it's padded, stop here. for t1 := t.Type; ; t1 = t1.Down {
if ispaddedfield(t1, t.Width) { first, size, next := memrun(t, t1)
t1 = t1.Down t1 = next
} else {
continue
}
}
// Run memhash for fields up to this one. // Run memhash for fields up to this one.
if first != nil { if first != nil {
size = offend - first.Width // first->width is offset
hashel = hashmem(first.Type) hashel = hashmem(first.Type)
// h = hashel(&p.first, size, h) // h = hashel(&p.first, size, h)
...@@ -2548,8 +2533,6 @@ func genhash(sym *Sym, t *Type) { ...@@ -2548,8 +2533,6 @@ func genhash(sym *Sym, t *Type) {
call.List = list(call.List, nh) call.List = list(call.List, nh)
call.List = list(call.List, Nodintconst(size)) call.List = list(call.List, Nodintconst(size))
fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call))
first = nil
} }
if t1 == nil { if t1 == nil {
...@@ -2745,25 +2728,11 @@ func geneq(sym *Sym, t *Type) { ...@@ -2745,25 +2728,11 @@ func geneq(sym *Sym, t *Type) {
// and calling specific equality tests for the others. // and calling specific equality tests for the others.
// Skip blank-named fields. // Skip blank-named fields.
case TSTRUCT: case TSTRUCT:
var first *Type
var conjuncts []*Node var conjuncts []*Node
offend := int64(0)
var size int64
for t1 := t.Type; ; t1 = t1.Down {
if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) {
offend = t1.Width + t1.Type.Width
if first == nil {
first = t1
}
// If it's a memory field but it's padded, stop here. for t1 := t.Type; ; t1 = t1.Down {
if ispaddedfield(t1, t.Width) { first, size, next := memrun(t, t1)
t1 = t1.Down t1 = next
} else {
continue
}
}
// Run memequal for fields up to this one. // Run memequal for fields up to this one.
// TODO(rsc): All the calls to newname are wrong for // TODO(rsc): All the calls to newname are wrong for
...@@ -2779,11 +2748,8 @@ func geneq(sym *Sym, t *Type) { ...@@ -2779,11 +2748,8 @@ func geneq(sym *Sym, t *Type) {
} }
} else { } else {
// More than two fields: use memequal. // More than two fields: use memequal.
size = offend - first.Width // first->width is offset
conjuncts = append(conjuncts, eqmem(np, nq, newname(first.Sym), size)) conjuncts = append(conjuncts, eqmem(np, nq, newname(first.Sym), size))
} }
first = nil
} }
if t1 == nil { if t1 == nil {
...@@ -2846,6 +2812,35 @@ func geneq(sym *Sym, t *Type) { ...@@ -2846,6 +2812,35 @@ func geneq(sym *Sym, t *Type) {
Disable_checknil-- Disable_checknil--
} }
// memrun finds runs of struct fields for which memory-only algs are appropriate.
// t is the parent struct type, and field is the field at which to start.
// first is the first field in the memory run.
// size is the length in bytes of the memory included in the run.
// next is the next field after the memory run.
func memrun(t *Type, field *Type) (first *Type, size int64, next *Type) {
var offend int64
for {
if field == nil || algtype1(field.Type, nil) != AMEM || isblanksym(field.Sym) {
break
}
offend = field.Width + field.Type.Width
if first == nil {
first = field
}
// If it's a memory field but it's padded, stop here.
if ispaddedfield(field, t.Width) {
field = field.Down
break
}
field = field.Down
}
if first != nil {
size = offend - first.Width // first.Width is offset
}
return first, size, field
}
func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase int) *Type { func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase int) *Type {
*followptr = false *followptr = false
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment