From: Cuong Manh Le Date: Mon, 24 May 2021 05:15:17 +0000 (+0700) Subject: cmd/compile: refactor walkIndexMap X-Git-Tag: go1.19beta1~936 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=209521c3e34820887c9d221f8f09d8f586c72419;p=gostls13.git cmd/compile: refactor walkIndexMap So all runtime map functions will use the same code path, make it easier for future CL to handle stack object for map key. Passes toolstash -cmp. For #43753 Change-Id: I374fa4e351c1eba079e2ccb637b1ef5adad1488f Reviewed-on: https://go-review.googlesource.com/c/go/+/321713 Trust: Cuong Manh Le Reviewed-by: Keith Randall Reviewed-by: Cherry Mui Run-TryBot: Cuong Manh Le TryBot-Result: Gopher Robot --- diff --git a/src/cmd/compile/internal/walk/assign.go b/src/cmd/compile/internal/walk/assign.go index 9350c389c1..9b09e097fa 100644 --- a/src/cmd/compile/internal/walk/assign.go +++ b/src/cmd/compile/internal/walk/assign.go @@ -157,7 +157,7 @@ func walkAssignMapRead(init *ir.Nodes, n *ir.AssignListStmt) ir.Node { t := r.X.Type() fast := mapfast(t) - key := mapKeyArg(fast, r, r.Index) + key := mapKeyArg(fast, r, r.Index, false) // from: // a,b = m[i] diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go index d0aaee03d5..b25627bd22 100644 --- a/src/cmd/compile/internal/walk/builtin.go +++ b/src/cmd/compile/internal/walk/builtin.go @@ -214,7 +214,7 @@ func walkDelete(init *ir.Nodes, n *ir.CallExpr) ir.Node { t := map_.Type() fast := mapfast(t) - key = mapKeyArg(fast, n, key) + key = mapKeyArg(fast, n, key, false) return mkcall1(mapfndel(mapdelete[fast], t), nil, init, reflectdata.TypePtr(t), map_, key) } diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go index 43201dbd3d..4c1e7adddd 100644 --- a/src/cmd/compile/internal/walk/expr.go +++ b/src/cmd/compile/internal/walk/expr.go @@ -723,21 +723,23 @@ func walkIndex(n *ir.IndexExpr, init *ir.Nodes) ir.Node { } // mapKeyArg returns an expression for key that is suitable to be passed -// as the key argument for mapaccess and mapdelete functions. +// as the key argument for runtime map* functions. // n is is the map indexing or delete Node (to provide Pos). -// Note: this is not used for mapassign, which does distinguish pointer vs. -// integer key. -func mapKeyArg(fast int, n, key ir.Node) ir.Node { - switch fast { - case mapslow: +func mapKeyArg(fast int, n, key ir.Node, assigned bool) ir.Node { + if fast == mapslow { // standard version takes key by reference. - // order.expr made sure key is addressable. + // orderState.expr made sure key is addressable. return typecheck.NodAddr(key) + } + if assigned { + // mapassign does distinguish pointer vs. integer key. + return key + } + // mapaccess and mapdelete don't distinguish pointer vs. integer key. + switch fast { case mapfast32ptr: - // mapaccess and mapdelete don't distinguish pointer vs. integer key. return ir.NewConvExpr(n.Pos(), ir.OCONVNOP, types.Types[types.TUINT32], key) case mapfast64ptr: - // mapaccess and mapdelete don't distinguish pointer vs. integer key. return ir.NewConvExpr(n.Pos(), ir.OCONVNOP, types.Types[types.TUINT64], key) default: // fast version takes key by value. @@ -746,34 +748,27 @@ func mapKeyArg(fast int, n, key ir.Node) ir.Node { } // walkIndexMap walks an OINDEXMAP node. +// It replaces m[k] with *map{access1,assign}(maptype, m, &k) func walkIndexMap(n *ir.IndexExpr, init *ir.Nodes) ir.Node { - // Replace m[k] with *map{access1,assign}(maptype, m, &k) n.X = walkExpr(n.X, init) n.Index = walkExpr(n.Index, init) map_ := n.X - key := n.Index t := map_.Type() - var call *ir.CallExpr - if n.Assigned { - // This m[k] expression is on the left-hand side of an assignment. - fast := mapfast(t) - if fast == mapslow { - // standard version takes key by reference. - // order.expr made sure key is addressable. - key = typecheck.NodAddr(key) - } - call = mkcall1(mapfn(mapassign[fast], t, false), nil, init, reflectdata.TypePtr(t), map_, key) - } else { - // m[k] is not the target of an assignment. - fast := mapfast(t) - key = mapKeyArg(fast, n, key) - if w := t.Elem().Size(); w <= zeroValSize { - call = mkcall1(mapfn(mapaccess1[fast], t, false), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key) - } else { - z := reflectdata.ZeroAddr(w) - call = mkcall1(mapfn("mapaccess1_fat", t, true), types.NewPtr(t.Elem()), init, reflectdata.TypePtr(t), map_, key, z) - } + fast := mapfast(t) + key := mapKeyArg(fast, n, n.Index, n.Assigned) + args := []ir.Node{reflectdata.TypePtr(t), map_, key} + + var mapFn ir.Node + switch { + case n.Assigned: + mapFn = mapfn(mapassign[fast], t, false) + case t.Elem().Size() > zeroValSize: + args = append(args, reflectdata.ZeroAddr(t.Elem().Size())) + mapFn = mapfn("mapaccess1_fat", t, true) + default: + mapFn = mapfn(mapaccess1[fast], t, false) } + call := mkcall1(mapFn, nil, init, args...) call.SetType(types.NewPtr(t.Elem())) call.MarkNonNil() // mapaccess1* and mapassign always return non-nil pointers. star := ir.NewStarExpr(base.Pos, call)