Commit 093a9a1f authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: encapsulate map value type

Passes toolstash -cmp.

Change-Id: I83af544974e1e91e0810e13321afb3e665dcdf12
Reviewed-on: https://go-review.googlesource.com/21248
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent bf5f24b9
...@@ -213,8 +213,7 @@ func dowidth(t *Type) { ...@@ -213,8 +213,7 @@ func dowidth(t *Type) {
case TMAP: // implemented as pointer case TMAP: // implemented as pointer
w = int64(Widthptr) w = int64(Widthptr)
checkwidth(t.Val())
checkwidth(t.Type)
checkwidth(t.Key()) checkwidth(t.Key())
case TFORW: // should have been filled in case TFORW: // should have been filled in
......
...@@ -542,8 +542,8 @@ func (p *exporter) typ(t *Type) { ...@@ -542,8 +542,8 @@ func (p *exporter) typ(t *Type) {
case TMAP: case TMAP:
p.tag(mapTag) p.tag(mapTag)
p.typ(t.Key()) // key p.typ(t.Key())
p.typ(t.Type) // val p.typ(t.Val())
case TCHAN: case TCHAN:
p.tag(chanTag) p.tag(chanTag)
......
...@@ -609,7 +609,7 @@ func typefmt(t *Type, flag FmtFlag) string { ...@@ -609,7 +609,7 @@ func typefmt(t *Type, flag FmtFlag) string {
return "chan " + t.Type.String() return "chan " + t.Type.String()
case TMAP: case TMAP:
return "map[" + t.Key().String() + "]" + t.Type.String() return "map[" + t.Key().String() + "]" + t.Val().String()
case TINTER: case TINTER:
var buf bytes.Buffer var buf bytes.Buffer
...@@ -674,15 +674,15 @@ func typefmt(t *Type, flag FmtFlag) string { ...@@ -674,15 +674,15 @@ func typefmt(t *Type, flag FmtFlag) string {
// Format the bucket struct for map[x]y as map.bucket[x]y. // Format the bucket struct for map[x]y as map.bucket[x]y.
// This avoids a recursive print that generates very long names. // This avoids a recursive print that generates very long names.
if t.Map.Bucket == t { if t.Map.Bucket == t {
return "map.bucket[" + t.Map.Key().String() + "]" + t.Map.Type.String() return "map.bucket[" + t.Map.Key().String() + "]" + t.Map.Val().String()
} }
if t.Map.Hmap == t { if t.Map.Hmap == t {
return "map.hdr[" + t.Map.Key().String() + "]" + t.Map.Type.String() return "map.hdr[" + t.Map.Key().String() + "]" + t.Map.Val().String()
} }
if t.Map.Hiter == t { if t.Map.Hiter == t {
return "map.iter[" + t.Map.Key().String() + "]" + t.Map.Type.String() return "map.iter[" + t.Map.Key().String() + "]" + t.Map.Val().String()
} }
Yyerror("unknown internal map type") Yyerror("unknown internal map type")
......
...@@ -55,7 +55,7 @@ func typecheckrange(n *Node) { ...@@ -55,7 +55,7 @@ func typecheckrange(n *Node) {
case TMAP: case TMAP:
t1 = t.Key() t1 = t.Key()
t2 = t.Type t2 = t.Val()
case TCHAN: case TCHAN:
if t.Chan&Crecv == 0 { if t.Chan&Crecv == 0 {
...@@ -231,7 +231,7 @@ func walkrange(n *Node) { ...@@ -231,7 +231,7 @@ func walkrange(n *Node) {
fn := syslook("mapiterinit") fn := syslook("mapiterinit")
fn = substArgTypes(fn, t.Key(), t.Type, th) fn = substArgTypes(fn, t.Key(), t.Val(), th)
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil))) init = append(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil)))
n.Left = Nod(ONE, NodSym(ODOT, hit, keysym), nodnil()) n.Left = Nod(ONE, NodSym(ODOT, hit, keysym), nodnil())
......
...@@ -82,7 +82,7 @@ func mapbucket(t *Type) *Type { ...@@ -82,7 +82,7 @@ func mapbucket(t *Type) *Type {
bucket := typ(TSTRUCT) bucket := typ(TSTRUCT)
keytype := t.Key() keytype := t.Key()
valtype := t.Type valtype := t.Val()
dowidth(keytype) dowidth(keytype)
dowidth(valtype) dowidth(valtype)
if keytype.Width > MAXKEYSIZE { if keytype.Width > MAXKEYSIZE {
...@@ -125,7 +125,7 @@ func mapbucket(t *Type) *Type { ...@@ -125,7 +125,7 @@ func mapbucket(t *Type) *Type {
// so if the struct needs 64-bit padding (because a key or value does) // so if the struct needs 64-bit padding (because a key or value does)
// then it would end with an extra 32-bit padding field. // then it would end with an extra 32-bit padding field.
// Preempt that by emitting the padding here. // Preempt that by emitting the padding here.
if int(t.Type.Align) > Widthptr || int(t.Key().Align) > Widthptr { if int(t.Val().Align) > Widthptr || int(t.Key().Align) > Widthptr {
field = append(field, makefield("pad", Types[TUINTPTR])) field = append(field, makefield("pad", Types[TUINTPTR]))
} }
...@@ -136,7 +136,7 @@ func mapbucket(t *Type) *Type { ...@@ -136,7 +136,7 @@ func mapbucket(t *Type) *Type {
// the type of the overflow field to uintptr in this case. // the type of the overflow field to uintptr in this case.
// See comment on hmap.overflow in ../../../../runtime/hashmap.go. // See comment on hmap.overflow in ../../../../runtime/hashmap.go.
otyp := Ptrto(bucket) otyp := Ptrto(bucket)
if !haspointers(t.Type) && !haspointers(t.Key()) && t.Type.Width <= MAXVALSIZE && t.Key().Width <= MAXKEYSIZE { if !haspointers(t.Val()) && !haspointers(t.Key()) && t.Val().Width <= MAXVALSIZE && t.Key().Width <= MAXKEYSIZE {
otyp = Types[TUINTPTR] otyp = Types[TUINTPTR]
} }
ovf := makefield("overflow", otyp) ovf := makefield("overflow", otyp)
...@@ -211,7 +211,7 @@ func hiter(t *Type) *Type { ...@@ -211,7 +211,7 @@ func hiter(t *Type) *Type {
// must match ../../../../runtime/hashmap.go:hiter. // must match ../../../../runtime/hashmap.go:hiter.
var field [12]*Field var field [12]*Field
field[0] = makefield("key", Ptrto(t.Key())) field[0] = makefield("key", Ptrto(t.Key()))
field[1] = makefield("val", Ptrto(t.Type)) field[1] = makefield("val", Ptrto(t.Val()))
field[2] = makefield("t", Ptrto(Types[TUINT8])) field[2] = makefield("t", Ptrto(Types[TUINT8]))
field[3] = makefield("h", Ptrto(hmap(t))) field[3] = makefield("h", Ptrto(hmap(t)))
field[4] = makefield("buckets", Ptrto(mapbucket(t))) field[4] = makefield("buckets", Ptrto(mapbucket(t)))
...@@ -1226,7 +1226,7 @@ ok: ...@@ -1226,7 +1226,7 @@ ok:
// ../../../../runtime/type.go:/mapType // ../../../../runtime/type.go:/mapType
case TMAP: case TMAP:
s1 := dtypesym(t.Key()) s1 := dtypesym(t.Key())
s2 := dtypesym(t.Type) s2 := dtypesym(t.Val())
s3 := dtypesym(mapbucket(t)) s3 := dtypesym(mapbucket(t))
s4 := dtypesym(hmap(t)) s4 := dtypesym(hmap(t))
ot = dcommontype(s, ot, t) ot = dcommontype(s, ot, t)
...@@ -1242,11 +1242,11 @@ ok: ...@@ -1242,11 +1242,11 @@ ok:
ot = duint8(s, ot, 0) // not indirect ot = duint8(s, ot, 0) // not indirect
} }
if t.Type.Width > MAXVALSIZE { if t.Val().Width > MAXVALSIZE {
ot = duint8(s, ot, uint8(Widthptr)) ot = duint8(s, ot, uint8(Widthptr))
ot = duint8(s, ot, 1) // indirect ot = duint8(s, ot, 1) // indirect
} else { } else {
ot = duint8(s, ot, uint8(t.Type.Width)) ot = duint8(s, ot, uint8(t.Val().Width))
ot = duint8(s, ot, 0) // not indirect ot = duint8(s, ot, 0) // not indirect
} }
......
...@@ -860,7 +860,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init *Nodes) { ...@@ -860,7 +860,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init *Nodes) {
// build type [count]struct { a Tindex, b Tvalue } // build type [count]struct { a Tindex, b Tvalue }
t := n.Type t := n.Type
tk := t.Key() tk := t.Key()
tv := t.Type tv := t.Val()
syma := Lookup("a") syma := Lookup("a")
symb := Lookup("b") symb := Lookup("b")
...@@ -969,7 +969,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init *Nodes) { ...@@ -969,7 +969,7 @@ func maplit(ctxt int, n *Node, var_ *Node, init *Nodes) {
// use temporary so that mapassign1 can have addressable key, val. // use temporary so that mapassign1 can have addressable key, val.
if key == nil { if key == nil {
key = temp(var_.Type.Key()) key = temp(var_.Type.Key())
val = temp(var_.Type.Type) val = temp(var_.Type.Val())
} }
setlineno(r.Left) setlineno(r.Left)
......
...@@ -773,6 +773,7 @@ func eqtype1(t1, t2 *Type, assumedEqual map[typePair]struct{}) bool { ...@@ -773,6 +773,7 @@ func eqtype1(t1, t2 *Type, assumedEqual map[typePair]struct{}) bool {
if !eqtype1(t1.Key(), t2.Key(), assumedEqual) { if !eqtype1(t1.Key(), t2.Key(), assumedEqual) {
return false return false
} }
return eqtype1(t1.Val(), t2.Val(), assumedEqual)
} }
return eqtype1(t1.Type, t2.Type, assumedEqual) return eqtype1(t1.Type, t2.Type, assumedEqual)
......
...@@ -342,6 +342,12 @@ func (t *Type) Key() *Type { ...@@ -342,6 +342,12 @@ func (t *Type) Key() *Type {
return t.Down return t.Down
} }
// Val returns the value type of map type t.
func (t *Type) Val() *Type {
t.wantEtype(TMAP)
return t.Type
}
func (t *Type) Methods() *Fields { func (t *Type) Methods() *Fields {
// TODO(mdempsky): Validate t? // TODO(mdempsky): Validate t?
return &t.methods return &t.methods
...@@ -524,9 +530,10 @@ func (t *Type) cmp(x *Type) ssa.Cmp { ...@@ -524,9 +530,10 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
switch t.Etype { switch t.Etype {
case TMAP: case TMAP:
if c := t.Down.cmp(x.Down); c != ssa.CMPeq { if c := t.Key().cmp(x.Key()); c != ssa.CMPeq {
return c return c
} }
return t.Val().cmp(x.Val())
case TPTR32, TPTR64: case TPTR32, TPTR64:
// No special cases for these two, they are handled // No special cases for these two, they are handled
...@@ -614,7 +621,7 @@ func (t *Type) cmp(x *Type) ssa.Cmp { ...@@ -614,7 +621,7 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
panic(e) panic(e)
} }
// Common element type comparison for TARRAY, TCHAN, TMAP, TPTR32, and TPTR64. // Common element type comparison for TARRAY, TCHAN, TPTR32, and TPTR64.
return t.Type.cmp(x.Type) return t.Type.cmp(x.Type)
} }
......
...@@ -1026,7 +1026,7 @@ OpSwitch: ...@@ -1026,7 +1026,7 @@ OpSwitch:
if n.Right.Type != nil { if n.Right.Type != nil {
n.Right = assignconv(n.Right, t.Key(), "map index") n.Right = assignconv(n.Right, t.Key(), "map index")
} }
n.Type = t.Type n.Type = t.Val()
n.Op = OINDEXMAP n.Op = OINDEXMAP
} }
...@@ -3021,10 +3021,10 @@ func typecheckcomplit(n *Node) *Node { ...@@ -3021,10 +3021,10 @@ func typecheckcomplit(n *Node) *Node {
} }
r = l.Right r = l.Right
pushtype(r, t.Type) pushtype(r, t.Val())
r = typecheck(r, Erv) r = typecheck(r, Erv)
r = defaultlit(r, t.Type) r = defaultlit(r, t.Val())
l.Right = assignconv(r, t.Type, "map value") l.Right = assignconv(r, t.Val(), "map value")
} }
n.Op = OMAPLIT n.Op = OMAPLIT
......
...@@ -835,7 +835,7 @@ opswitch: ...@@ -835,7 +835,7 @@ opswitch:
r.Right = walkexpr(r.Right, init) r.Right = walkexpr(r.Right, init)
t := r.Left.Type t := r.Left.Type
p := "" p := ""
if t.Type.Width <= 128 { // Check ../../runtime/hashmap.go:maxValueSize before changing. if t.Val().Width <= 128 { // Check ../../runtime/hashmap.go:maxValueSize before changing.
switch algtype(t.Key()) { switch algtype(t.Key()) {
case AMEM32: case AMEM32:
p = "mapaccess2_fast32" p = "mapaccess2_fast32"
...@@ -879,7 +879,7 @@ opswitch: ...@@ -879,7 +879,7 @@ opswitch:
// don't generate a = *var if a is _ // don't generate a = *var if a is _
if !isblank(a) { if !isblank(a) {
var_ := temp(Ptrto(t.Type)) var_ := temp(Ptrto(t.Val()))
var_.Typecheck = 1 var_.Typecheck = 1
n.List.SetIndex(0, var_) n.List.SetIndex(0, var_)
n = walkexpr(n, init) n = walkexpr(n, init)
...@@ -1200,7 +1200,7 @@ opswitch: ...@@ -1200,7 +1200,7 @@ opswitch:
t := n.Left.Type t := n.Left.Type
p := "" p := ""
if t.Type.Width <= 128 { // Check ../../runtime/hashmap.go:maxValueSize before changing. if t.Val().Width <= 128 { // Check ../../runtime/hashmap.go:maxValueSize before changing.
switch algtype(t.Key()) { switch algtype(t.Key()) {
case AMEM32: case AMEM32:
p = "mapaccess1_fast32" p = "mapaccess1_fast32"
...@@ -1223,9 +1223,9 @@ opswitch: ...@@ -1223,9 +1223,9 @@ opswitch:
p = "mapaccess1" p = "mapaccess1"
} }
n = mkcall1(mapfn(p, t), Ptrto(t.Type), init, typename(t), n.Left, key) n = mkcall1(mapfn(p, t), Ptrto(t.Val()), init, typename(t), n.Left, key)
n = Nod(OIND, n, nil) n = Nod(OIND, n, nil)
n.Type = t.Type n.Type = t.Val()
n.Typecheck = 1 n.Typecheck = 1
case ORECV: case ORECV:
...@@ -1393,7 +1393,7 @@ opswitch: ...@@ -1393,7 +1393,7 @@ opswitch:
} }
fn := syslook("makemap") fn := syslook("makemap")
fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Type) fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Val())
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r) n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r)
case OMAKESLICE: case OMAKESLICE:
...@@ -2647,7 +2647,7 @@ func mapfn(name string, t *Type) *Node { ...@@ -2647,7 +2647,7 @@ func mapfn(name string, t *Type) *Node {
Fatalf("mapfn %v", t) Fatalf("mapfn %v", t)
} }
fn := syslook(name) fn := syslook(name)
fn = substArgTypes(fn, t.Key(), t.Type, t.Key(), t.Type) fn = substArgTypes(fn, t.Key(), t.Val(), t.Key(), t.Val())
return fn return fn
} }
...@@ -2656,7 +2656,7 @@ func mapfndel(name string, t *Type) *Node { ...@@ -2656,7 +2656,7 @@ func mapfndel(name string, t *Type) *Node {
Fatalf("mapfn %v", t) Fatalf("mapfn %v", t)
} }
fn := syslook(name) fn := syslook(name)
fn = substArgTypes(fn, t.Key(), t.Type, t.Key()) fn = substArgTypes(fn, t.Key(), t.Val(), t.Key())
return fn return fn
} }
......
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