go/ssa: inline *ssa.selection methods

Inlines and removes *ssa.selection methods.

Change-Id: If3b30bc193a60b4aa4241431ce8cbe9c08a70587
Reviewed-on: https://go-review.googlesource.com/c/tools/+/406114
Reviewed-by: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
Run-TryBot: Tim King <taking@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Tim King 2022-05-12 17:39:34 -07:00
parent 304195cc44
commit cfd99059fd
4 changed files with 36 additions and 44 deletions

View File

@ -448,14 +448,14 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
// qualified identifier
return b.addr(fn, e.Sel, escaping)
}
if sel.Kind() != types.FieldVal {
if sel.kind != types.FieldVal {
panic(sel)
}
wantAddr := true
v := b.receiver(fn, e.X, wantAddr, escaping, sel)
last := len(sel.Index()) - 1
last := len(sel.index) - 1
return &address{
addr: emitFieldSelection(fn, v, sel.Index()[last], true, e.Sel),
addr: emitFieldSelection(fn, v, sel.index[last], true, e.Sel),
pos: e.Sel.Pos(),
expr: e.Sel,
}
@ -795,7 +795,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
// qualified identifier
return b.expr(fn, e.Sel)
}
switch sel.Kind() {
switch sel.kind {
case types.MethodExpr:
// (*T).f or T.f, the method f from the method-set of type T.
// The result is a "thunk".
@ -805,7 +805,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
case types.MethodVal:
// e.f where e is an expression and f is a method.
// The result is a "bound".
obj := sel.Obj().(*types.Func)
obj := sel.obj.(*types.Func)
rt := fn.typ(recvType(obj))
wantAddr := isPointer(rt)
escaping := true
@ -829,7 +829,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
return fn.emit(c)
case types.FieldVal:
indices := sel.Index()
indices := sel.index
last := len(indices) - 1
v := b.expr(fn, e.X)
v = emitImplicitSelections(fn, v, indices[:last], e.Pos())
@ -919,21 +919,21 @@ func (b *builder) stmtList(fn *Function, list []ast.Stmt) {
// selections of sel.
//
// wantAddr requests that the result is an an address. If
// !sel.Indirect(), this may require that e be built in addr() mode; it
// !sel.indirect, this may require that e be built in addr() mode; it
// must thus be addressable.
//
// escaping is defined as per builder.addr().
func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *selection) Value {
var v Value
if wantAddr && !sel.Indirect() && !isPointer(fn.typeOf(e)) {
if wantAddr && !sel.indirect && !isPointer(fn.typeOf(e)) {
v = b.addr(fn, e, escaping).address(fn)
} else {
v = b.expr(fn, e)
}
last := len(sel.Index()) - 1
last := len(sel.index) - 1
// The position of implicit selection is the position of the inducing receiver expression.
v = emitImplicitSelections(fn, v, sel.Index()[:last], e.Pos())
v = emitImplicitSelections(fn, v, sel.index[:last], e.Pos())
if !wantAddr && isPointer(v.Type()) {
v = emitLoad(fn, v)
}
@ -949,8 +949,8 @@ func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) {
// Is this a method call?
if selector, ok := unparen(e.Fun).(*ast.SelectorExpr); ok {
sel := fn.selection(selector)
if sel != nil && sel.Kind() == types.MethodVal {
obj := sel.Obj().(*types.Func)
if sel != nil && sel.kind == types.MethodVal {
obj := sel.obj.(*types.Func)
recv := recvType(obj)
wantAddr := isPointer(recv)
@ -972,7 +972,7 @@ func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) {
return
}
// sel.Kind()==MethodExpr indicates T.f() or (*T).f():
// sel.kind==MethodExpr indicates T.f() or (*T).f():
// a statically dispatched call to the method f in the
// method-set of T or *T. T may be an interface.
//

View File

@ -474,7 +474,7 @@ func (f *Function) RelString(from *types.Package) string {
// Thunk?
if f.method != nil {
return f.relMethod(from, f.method.Recv())
return f.relMethod(from, f.method.recv)
}
// Bound?

View File

@ -99,10 +99,10 @@ func (prog *Program) addMethod(mset *methodSet, sel *types.Selection, cr *creato
fn := mset.mapping[id]
if fn == nil {
sel := toSelection(sel)
obj := sel.Obj().(*types.Func)
obj := sel.obj.(*types.Func)
needsPromotion := len(sel.Index()) > 1
needsIndirection := !isPointer(recvType(obj)) && isPointer(sel.Recv())
needsPromotion := len(sel.index) > 1
needsIndirection := !isPointer(recvType(obj)) && isPointer(sel.recv)
if needsPromotion || needsIndirection {
fn = makeWrapper(prog, sel, cr)
} else {

View File

@ -43,14 +43,14 @@ import (
//
// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu)
func makeWrapper(prog *Program, sel *selection, cr *creator) *Function {
obj := sel.Obj().(*types.Func) // the declared function
sig := sel.Type().(*types.Signature) // type of this wrapper
obj := sel.obj.(*types.Func) // the declared function
sig := sel.typ.(*types.Signature) // type of this wrapper
var recv *types.Var // wrapper's receiver or thunk's params[0]
name := obj.Name()
var description string
var start int // first regular param
if sel.Kind() == types.MethodExpr {
if sel.kind == types.MethodExpr {
name += "$thunk"
description = "thunk"
recv = sig.Params().At(0)
@ -60,7 +60,7 @@ func makeWrapper(prog *Program, sel *selection, cr *creator) *Function {
recv = sig.Recv()
}
description = fmt.Sprintf("%s for %s", description, sel.Obj())
description = fmt.Sprintf("%s for %s", description, sel.obj)
if prog.mode&LogSource != 0 {
defer logStack("make %s to (%s)", description, recv.Type())()
}
@ -79,10 +79,10 @@ func makeWrapper(prog *Program, sel *selection, cr *creator) *Function {
fn.addSpilledParam(recv)
createParams(fn, start)
indices := sel.Index()
indices := sel.index
var v Value = fn.Locals[0] // spilled receiver
if isPointer(sel.Recv()) {
if isPointer(sel.recv) {
v = emitLoad(fn, v)
// For simple indirection wrappers, perform an informative nil-check:
@ -92,13 +92,13 @@ func makeWrapper(prog *Program, sel *selection, cr *creator) *Function {
c.Call.Value = &Builtin{
name: "ssa:wrapnilchk",
sig: types.NewSignature(nil,
types.NewTuple(anonVar(sel.Recv()), anonVar(tString), anonVar(tString)),
types.NewTuple(anonVar(sel.Recv())), false),
types.NewTuple(anonVar(sel.recv), anonVar(tString), anonVar(tString)),
types.NewTuple(anonVar(sel.recv)), false),
}
c.Call.Args = []Value{
v,
stringConst(deref(sel.Recv()).String()),
stringConst(sel.Obj().Name()),
stringConst(deref(sel.recv).String()),
stringConst(sel.obj.Name()),
}
c.setType(v.Type())
v = fn.emit(&c)
@ -234,11 +234,11 @@ func makeBound(prog *Program, obj *types.Func, cr *creator) *Function {
// -- thunks -----------------------------------------------------------
// makeThunk returns a thunk, a synthetic function that delegates to a
// concrete or interface method denoted by sel.Obj(). The resulting
// concrete or interface method denoted by sel.obj. The resulting
// function has no receiver, but has an additional (first) regular
// parameter.
//
// Precondition: sel.Kind() == types.MethodExpr.
// Precondition: sel.kind == types.MethodExpr.
//
// type T int or: type T interface { meth() }
// func (t T) meth()
@ -256,18 +256,18 @@ func makeBound(prog *Program, obj *types.Func, cr *creator) *Function {
//
// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu)
func makeThunk(prog *Program, sel *selection, cr *creator) *Function {
if sel.Kind() != types.MethodExpr {
if sel.kind != types.MethodExpr {
panic(sel)
}
// Canonicalize sel.Recv() to avoid constructing duplicate thunks.
canonRecv := prog.canon.Type(sel.Recv())
// Canonicalize sel.recv to avoid constructing duplicate thunks.
canonRecv := prog.canon.Type(sel.recv)
key := selectionKey{
kind: sel.Kind(),
kind: sel.kind,
recv: canonRecv,
obj: sel.Obj(),
index: fmt.Sprint(sel.Index()),
indirect: sel.Indirect(),
obj: sel.obj,
index: fmt.Sprint(sel.index),
indirect: sel.indirect,
}
prog.methodsMu.Lock()
@ -314,14 +314,6 @@ type selection struct {
indirect bool
}
// TODO(taking): inline and eliminate.
func (sel *selection) Kind() types.SelectionKind { return sel.kind }
func (sel *selection) Type() types.Type { return sel.typ }
func (sel *selection) Recv() types.Type { return sel.recv }
func (sel *selection) Obj() types.Object { return sel.obj }
func (sel *selection) Index() []int { return sel.index }
func (sel *selection) Indirect() bool { return sel.indirect }
func toSelection(sel *types.Selection) *selection {
return &selection{
kind: sel.Kind(),