]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: refactor walkIndexMap
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Mon, 24 May 2021 05:15:17 +0000 (12:15 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 24 Mar 2022 03:04:13 +0000 (03:04 +0000)
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 <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/walk/assign.go
src/cmd/compile/internal/walk/builtin.go
src/cmd/compile/internal/walk/expr.go

index 9350c389c162d6f3bbccee60d84014c9e4442b83..9b09e097fac685d94c9492a9ad499aa865896be6 100644 (file)
@@ -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]
index d0aaee03d59d07b4bd39ef861f1ea62ccc5fae30..b25627bd2247db19553548b6c7ba1be26c5c2429 100644 (file)
@@ -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)
 }
 
index 43201dbd3d4e0dad3bc3ca05e66c933666439f79..4c1e7adddd7eaa24f19f1c6897f5b35d92e51ee2 100644 (file)
@@ -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)