mirror of https://github.com/golang/go.git
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:
parent
304195cc44
commit
cfd99059fd
|
|
@ -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.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue