cmd/compile/internal/typecheck: merge SubstArgTypes into LookupRuntime

LookupRuntime is the only reason for using SubstArgTypes, and most
callers to LookupRuntime need to immediately call it anyway. So might
as well fuse them together.

Change-Id: Ie0724ed164b949040e898a2a77bea632801b64fd
Reviewed-on: https://go-review.googlesource.com/c/go/+/521415
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Matthew Dempsky 2023-08-20 16:14:50 -07:00 committed by Gopher Robot
parent c6dd97e533
commit 08a08083c1
8 changed files with 48 additions and 82 deletions

View file

@ -294,8 +294,7 @@ func EqString(s, t ir.Node) (eqlen *ir.BinaryExpr, eqmem *ir.CallExpr) {
cmplen = tlen
}
fn := typecheck.LookupRuntime("memequal")
fn = typecheck.SubstArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
fn := typecheck.LookupRuntime("memequal", types.Types[types.TUINT8], types.Types[types.TUINT8])
call := typecheck.Call(base.Pos, fn, []ir.Node{sptr, tptr, ir.Copy(cmplen)}, false).(*ir.CallExpr)
cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, slen, tlen)
@ -373,14 +372,10 @@ func eqmem(p, q ir.Node, field int, size int64) ir.Node {
func eqmemfunc(size int64, t *types.Type) (fn *ir.Name, needsize bool) {
switch size {
default:
fn = typecheck.LookupRuntime("memequal")
needsize = true
case 1, 2, 4, 8, 16:
buf := fmt.Sprintf("memequal%d", int(size)*8)
fn = typecheck.LookupRuntime(buf)
return typecheck.LookupRuntime(buf, t, t), false
}
fn = typecheck.SubstArgTypes(fn, t, t)
return fn, needsize
return typecheck.LookupRuntime("memequal", t, t), true
}

View file

@ -249,9 +249,7 @@ func hashFunc(t *types.Type) *ir.Func {
}
func runtimeHashFor(name string, t *types.Type) *ir.Name {
n := typecheck.LookupRuntime(name)
n = typecheck.SubstArgTypes(n, t)
return n
return typecheck.LookupRuntime(name, t)
}
// hashfor returns the function to compute the hash of a value of type t.
@ -647,9 +645,7 @@ func eqFunc(t *types.Type) *ir.Func {
func EqFor(t *types.Type) (ir.Node, bool) {
switch a, _ := types.AlgType(t); a {
case types.AMEM:
n := typecheck.LookupRuntime("memequal")
n = typecheck.SubstArgTypes(n, t, t)
return n, true
return typecheck.LookupRuntime("memequal", t, t), true
case types.ASPECIAL:
fn := eqFunc(t)
return fn.Nname, false
@ -667,7 +663,5 @@ func anyCall(fn *ir.Func) bool {
}
func hashmem(t *types.Type) ir.Node {
n := typecheck.LookupRuntime("memhash")
n = typecheck.SubstArgTypes(n, t)
return n
return typecheck.LookupRuntime("memhash", t)
}

View file

@ -11,21 +11,25 @@ import (
"cmd/internal/obj"
)
func LookupRuntime(name string) *ir.Name {
// LookupRuntime returns a function or variable declared in
// _builtin/runtime.go. If types_ is non-empty, successive occurrences
// of the "any" placeholder type will be substituted.
func LookupRuntime(name string, types_ ...*types.Type) *ir.Name {
s := ir.Pkgs.Runtime.Lookup(name)
if s == nil || s.Def == nil {
base.Fatalf("LookupRuntime: can't find runtime.%s", name)
}
return s.Def.(*ir.Name)
n := s.Def.(*ir.Name)
if len(types_) != 0 {
n = substArgTypes(n, types_...)
}
return n
}
// SubstArgTypes substitutes the given list of types for
// successive occurrences of the "any" placeholder in the
// type syntax expression n.Type.
// The result of SubstArgTypes MUST be assigned back to old, e.g.
//
// n.Left = SubstArgTypes(n.Left, t1, t2)
func SubstArgTypes(old *ir.Name, types_ ...*types.Type) *ir.Name {
func substArgTypes(old *ir.Name, types_ ...*types.Type) *ir.Name {
for _, t := range types_ {
types.CalcSize(t)
}

View file

@ -514,8 +514,7 @@ func appendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, slice)}
// func growslice(oldPtr unsafe.Pointer, newLen, oldCap, num int, et *_type) []T
fn := typecheck.LookupRuntime("growslice")
fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
fn := typecheck.LookupRuntime("growslice", elemtype, elemtype)
// else { s = growslice(oldPtr, newLen, oldCap, num, T) }
call := mkcall1(fn, s.Type(), nif.PtrInit(), oldPtr, newLen, oldCap, num, reflectdata.TypePtrAt(base.Pos, elemtype))
@ -541,8 +540,7 @@ func appendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
ir.CurFunc.SetWBPos(n.Pos())
// instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
fn := typecheck.LookupRuntime("typedslicecopy")
fn = typecheck.SubstArgTypes(fn, l1.Type().Elem(), l2.Type().Elem())
fn := typecheck.LookupRuntime("typedslicecopy", l1.Type().Elem(), l2.Type().Elem())
ptr1, len1 := backingArrayPtrLen(cheapExpr(slice, &nodes))
ptr2, len2 := backingArrayPtrLen(l2)
ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, reflectdata.AppendElemRType(base.Pos, n), ptr1, len1, ptr2, len2)
@ -557,8 +555,7 @@ func appendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
ptr1, len1 := backingArrayPtrLen(cheapExpr(slice, &nodes))
ptr2, len2 := backingArrayPtrLen(l2)
fn := typecheck.LookupRuntime("slicecopy")
fn = typecheck.SubstArgTypes(fn, ptr1.Type().Elem(), ptr2.Type().Elem())
fn := typecheck.LookupRuntime("slicecopy", ptr1.Type().Elem(), ptr2.Type().Elem())
ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, ir.NewInt(base.Pos, elemtype.Size()))
} else {
// memmove(&s[idx], &l2[0], len(l2)*sizeof(T))
@ -572,8 +569,7 @@ func appendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(base.Pos, elemtype.Size()))
// instantiate func memmove(to *any, frm *any, length uintptr)
fn := typecheck.LookupRuntime("memmove")
fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
fn := typecheck.LookupRuntime("memmove", elemtype, elemtype)
ncopy = mkcall1(fn, nil, &nodes, addr, sptr, nwid)
}
ln := append(nodes, ncopy)
@ -696,8 +692,7 @@ func extendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, nt)}
// instantiate growslice(oldPtr *any, newLen, oldCap, num int, typ *type) []any
fn := typecheck.LookupRuntime("growslice")
fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
fn := typecheck.LookupRuntime("growslice", elemtype, elemtype)
// else { s = growslice(s.ptr, n, s.cap, l2, T) }
nif.Else = []ir.Node{

View file

@ -101,8 +101,8 @@ func walkAppend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node {
ir.NewAssignStmt(base.Pos, s, slice),
}
fn := typecheck.LookupRuntime("growslice") // growslice(ptr *T, newLen, oldCap, num int, <type>) (ret []T)
fn = typecheck.SubstArgTypes(fn, s.Type().Elem(), s.Type().Elem())
// growslice(ptr *T, newLen, oldCap, num int, <type>) (ret []T)
fn := typecheck.LookupRuntime("growslice", s.Type().Elem(), s.Type().Elem())
// else { s = growslice(s.ptr, n, s.cap, a, T) }
nif.Else = []ir.Node{
@ -149,8 +149,7 @@ func walkClear(n *ir.UnaryExpr) ir.Node {
// walkClose walks an OCLOSE node.
func walkClose(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
// cannot use chanfn - closechan takes any, not chan any
fn := typecheck.LookupRuntime("closechan")
fn = typecheck.SubstArgTypes(fn, n.X.Type())
fn := typecheck.LookupRuntime("closechan", n.X.Type())
return mkcall1(fn, nil, init, n.X)
}
@ -185,8 +184,7 @@ func walkCopy(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
n.Y = cheapExpr(n.Y, init)
ptrR, lenR := backingArrayPtrLen(n.Y)
fn := typecheck.LookupRuntime("slicecopy")
fn = typecheck.SubstArgTypes(fn, ptrL.Type().Elem(), ptrR.Type().Elem())
fn := typecheck.LookupRuntime("slicecopy", ptrL.Type().Elem(), ptrR.Type().Elem())
return mkcall1(fn, n.Type(), init, ptrL, lenL, ptrR, lenR, ir.NewInt(base.Pos, n.X.Type().Elem().Size()))
}
@ -219,8 +217,7 @@ func walkCopy(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
ne.Likely = true
l = append(l, ne)
fn := typecheck.LookupRuntime("memmove")
fn = typecheck.SubstArgTypes(fn, nl.Type().Elem(), nl.Type().Elem())
fn := typecheck.LookupRuntime("memmove", nl.Type().Elem(), nl.Type().Elem())
nwid := ir.Node(typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TUINTPTR]))
setwid := ir.NewAssignStmt(base.Pos, nwid, typecheck.Conv(nlen, types.Types[types.TUINTPTR]))
ne.Body.Append(setwid)
@ -365,8 +362,7 @@ func walkMakeMap(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
}
// Call runtime.makehmap to allocate an
// hmap on the heap and initialize hmap's hash0 field.
fn := typecheck.LookupRuntime("makemap_small")
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
fn := typecheck.LookupRuntime("makemap_small", t.Key(), t.Elem())
return mkcall1(fn, n.Type(), init)
}
@ -392,8 +388,7 @@ func walkMakeMap(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
argtype = types.Types[types.TINT]
}
fn := typecheck.LookupRuntime(fnname)
fn = typecheck.SubstArgTypes(fn, hmapType, t.Key(), t.Elem())
fn := typecheck.LookupRuntime(fnname, hmapType, t.Key(), t.Elem())
return mkcall1(fn, n.Type(), init, reflectdata.MakeMapRType(base.Pos, n), typecheck.Conv(hint, argtype), h)
}
@ -503,8 +498,7 @@ func walkMakeSliceCopy(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
init.Append(r)
// instantiate memmove(to *any, frm *any, size uintptr)
fn = typecheck.LookupRuntime("memmove")
fn = typecheck.SubstArgTypes(fn, t.Elem(), t.Elem())
fn = typecheck.LookupRuntime("memmove", t.Elem(), t.Elem())
ncopy := mkcall1(fn, nil, init, ir.NewUnaryExpr(base.Pos, ir.OSPTR, s), copyptr, size)
init.Append(walkExpr(typecheck.Stmt(ncopy), init))
@ -609,11 +603,10 @@ func walkPrint(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
switch n.Type().Kind() {
case types.TINTER:
if n.Type().IsEmptyInterface() {
on = typecheck.LookupRuntime("printeface")
on = typecheck.LookupRuntime("printeface", n.Type())
} else {
on = typecheck.LookupRuntime("printiface")
on = typecheck.LookupRuntime("printiface", n.Type())
}
on = typecheck.SubstArgTypes(on, n.Type()) // any-1
case types.TPTR:
if n.Type().Elem().NotInHeap() {
on = typecheck.LookupRuntime("printuintptr")
@ -625,11 +618,9 @@ func walkPrint(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
}
fallthrough
case types.TCHAN, types.TMAP, types.TFUNC, types.TUNSAFEPTR:
on = typecheck.LookupRuntime("printpointer")
on = typecheck.SubstArgTypes(on, n.Type()) // any-1
on = typecheck.LookupRuntime("printpointer", n.Type())
case types.TSLICE:
on = typecheck.LookupRuntime("printslice")
on = typecheck.SubstArgTypes(on, n.Type()) // any-1
on = typecheck.LookupRuntime("printslice", n.Type())
case types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR:
if types.RuntimeSymName(n.Type().Sym()) == "hex" {
on = typecheck.LookupRuntime("printhex")
@ -863,9 +854,7 @@ func badtype(op ir.Op, tl, tr *types.Type) {
}
func writebarrierfn(name string, l *types.Type, r *types.Type) ir.Node {
fn := typecheck.LookupRuntime(name)
fn = typecheck.SubstArgTypes(fn, l, r)
return fn
return typecheck.LookupRuntime(name, l, r)
}
// isRuneCount reports whether n is of the form len([]rune(string)).

View file

@ -165,7 +165,7 @@ func dataWord(conv *ir.ConvExpr, init *ir.Nodes) ir.Node {
// Time to do an allocation. We'll call into the runtime for that.
fnname, argType, needsaddr := dataWordFuncName(fromType)
fn := typecheck.LookupRuntime(fnname)
var fn *ir.Name
var args []ir.Node
if needsaddr {
@ -178,11 +178,12 @@ func dataWord(conv *ir.ConvExpr, init *ir.Nodes) ir.Node {
if !ir.IsAddressable(n) {
n = copyExpr(n, fromType, init)
}
fn = typecheck.SubstArgTypes(fn, fromType)
fn = typecheck.LookupRuntime(fnname, fromType)
args = []ir.Node{reflectdata.ConvIfaceSrcRType(base.Pos, conv), typecheck.NodAddr(n)}
} else {
// Use a specialized conversion routine that takes the type being
// converted by value, not by pointer.
fn = typecheck.LookupRuntime(fnname)
var arg ir.Node
switch {
case fromType == argType:

View file

@ -231,14 +231,11 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
keysym := th.Field(0).Sym
elemsym := th.Field(1).Sym // ditto
fn := typecheck.LookupRuntime("mapiterinit")
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), th)
fn := typecheck.LookupRuntime("mapiterinit", t.Key(), t.Elem(), th)
init = append(init, mkcallstmt1(fn, reflectdata.RangeMapRType(base.Pos, nrange), ha, typecheck.NodAddr(hit)))
nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, keysym), typecheck.NodNil())
fn = typecheck.LookupRuntime("mapiternext")
fn = typecheck.SubstArgTypes(fn, th)
fn = typecheck.LookupRuntime("mapiternext", th)
nfor.Post = mkcallstmt1(fn, typecheck.NodAddr(hit))
key := ir.NewStarExpr(base.Pos, typecheck.ConvNop(ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, keysym), types.NewPtr(t.Key())))
@ -454,8 +451,7 @@ func mapClear(m, rtyp ir.Node) ir.Node {
t := m.Type()
// instantiate mapclear(typ *type, hmap map[any]any)
fn := typecheck.LookupRuntime("mapclear")
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
fn := typecheck.LookupRuntime("mapclear", t.Key(), t.Elem())
n := mkcallstmt1(fn, rtyp, m)
return walkStmt(typecheck.Stmt(n))
}

View file

@ -141,42 +141,34 @@ func chanfn(name string, n int, t *types.Type) ir.Node {
if !t.IsChan() {
base.Fatalf("chanfn %v", t)
}
fn := typecheck.LookupRuntime(name)
switch n {
default:
base.Fatalf("chanfn %d", n)
case 1:
fn = typecheck.SubstArgTypes(fn, t.Elem())
return typecheck.LookupRuntime(name, t.Elem())
case 2:
fn = typecheck.SubstArgTypes(fn, t.Elem(), t.Elem())
return typecheck.LookupRuntime(name, t.Elem(), t.Elem())
}
return fn
base.Fatalf("chanfn %d", n)
return nil
}
func mapfn(name string, t *types.Type, isfat bool) ir.Node {
if !t.IsMap() {
base.Fatalf("mapfn %v", t)
}
fn := typecheck.LookupRuntime(name)
if mapfast(t) == mapslow || isfat {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
} else {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Elem())
return typecheck.LookupRuntime(name, t.Key(), t.Elem(), t.Key(), t.Elem())
}
return fn
return typecheck.LookupRuntime(name, t.Key(), t.Elem(), t.Elem())
}
func mapfndel(name string, t *types.Type) ir.Node {
if !t.IsMap() {
base.Fatalf("mapfn %v", t)
}
fn := typecheck.LookupRuntime(name)
if mapfast(t) == mapslow {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), t.Key())
} else {
fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
return typecheck.LookupRuntime(name, t.Key(), t.Elem(), t.Key())
}
return fn
return typecheck.LookupRuntime(name, t.Key(), t.Elem())
}
const (