mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: revert most of CL 349169
The method of using references to dictionaries to hold methods live during linker deadcode elimination wasn't working very well. I implemented a new scheme in the CL below this, so this CL strips out the old method. The new method has the added benefit of having 0 runtime overhead (unlike the stuff we're ripping out here, which does have a small overhead). Update #48047 Change-Id: I68ac57119792d53c58f1480f407de6ab2bb53211 Reviewed-on: https://go-review.googlesource.com/c/go/+/357836 Trust: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
0ae0d5c62e
commit
72b6a89ca5
3 changed files with 12 additions and 25 deletions
|
|
@ -183,7 +183,7 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
|
||||||
// If no type params, do the normal call transformations. This
|
// If no type params, do the normal call transformations. This
|
||||||
// will convert OCALL to OCALLFUNC.
|
// will convert OCALL to OCALLFUNC.
|
||||||
typed(typ, n)
|
typed(typ, n)
|
||||||
transformCall(n, nil)
|
transformCall(n)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ func (g *genInst) scanForGenCalls(decl ir.Node) {
|
||||||
// it before installing the instantiation, so we are
|
// it before installing the instantiation, so we are
|
||||||
// checking against non-shape param types in
|
// checking against non-shape param types in
|
||||||
// typecheckaste.
|
// typecheckaste.
|
||||||
transformCall(call, nil)
|
transformCall(call)
|
||||||
|
|
||||||
// Replace the OFUNCINST with a direct reference to the
|
// Replace the OFUNCINST with a direct reference to the
|
||||||
// new stenciled function
|
// new stenciled function
|
||||||
|
|
@ -223,7 +223,7 @@ func (g *genInst) scanForGenCalls(decl ir.Node) {
|
||||||
|
|
||||||
// Transform the Call now, which changes OCALL
|
// Transform the Call now, which changes OCALL
|
||||||
// to OCALLFUNC and does typecheckaste/assignconvfn.
|
// to OCALLFUNC and does typecheckaste/assignconvfn.
|
||||||
transformCall(call, nil)
|
transformCall(call)
|
||||||
|
|
||||||
st := g.getInstantiation(gf, targs, true).fun
|
st := g.getInstantiation(gf, targs, true).fun
|
||||||
dictValue, usingSubdict := g.getDictOrSubdict(declInfo, n, gf, targs, true)
|
dictValue, usingSubdict := g.getDictOrSubdict(declInfo, n, gf, targs, true)
|
||||||
|
|
@ -1089,14 +1089,14 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
||||||
// transform the call.
|
// transform the call.
|
||||||
call.X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
|
call.X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
|
||||||
transformDot(call.X.(*ir.SelectorExpr), true)
|
transformDot(call.X.(*ir.SelectorExpr), true)
|
||||||
transformCall(call, subst.info.dictParam)
|
transformCall(call)
|
||||||
|
|
||||||
case ir.ODOT, ir.ODOTPTR:
|
case ir.ODOT, ir.ODOTPTR:
|
||||||
// An OXDOT for a generic receiver was resolved to
|
// An OXDOT for a generic receiver was resolved to
|
||||||
// an access to a field which has a function
|
// an access to a field which has a function
|
||||||
// value. Transform the call to that function, now
|
// value. Transform the call to that function, now
|
||||||
// that the OXDOT was resolved.
|
// that the OXDOT was resolved.
|
||||||
transformCall(call, subst.info.dictParam)
|
transformCall(call)
|
||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
name := call.X.Name()
|
name := call.X.Name()
|
||||||
|
|
@ -1113,24 +1113,24 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
||||||
// This is the case of a function value that was a
|
// This is the case of a function value that was a
|
||||||
// type parameter (implied to be a function via a
|
// type parameter (implied to be a function via a
|
||||||
// structural constraint) which is now resolved.
|
// structural constraint) which is now resolved.
|
||||||
transformCall(call, subst.info.dictParam)
|
transformCall(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCLOSURE:
|
case ir.OCLOSURE:
|
||||||
transformCall(call, subst.info.dictParam)
|
transformCall(call)
|
||||||
|
|
||||||
case ir.ODEREF, ir.OINDEX, ir.OINDEXMAP, ir.ORECV:
|
case ir.ODEREF, ir.OINDEX, ir.OINDEXMAP, ir.ORECV:
|
||||||
// Transform a call that was delayed because of the
|
// Transform a call that was delayed because of the
|
||||||
// use of typeparam inside an expression that required
|
// use of typeparam inside an expression that required
|
||||||
// a pointer dereference, array indexing, map indexing,
|
// a pointer dereference, array indexing, map indexing,
|
||||||
// or channel receive to compute function value.
|
// or channel receive to compute function value.
|
||||||
transformCall(call, subst.info.dictParam)
|
transformCall(call)
|
||||||
|
|
||||||
case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
|
case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
|
||||||
transformCall(call, subst.info.dictParam)
|
transformCall(call)
|
||||||
|
|
||||||
case ir.OCONVNOP:
|
case ir.OCONVNOP:
|
||||||
transformCall(call, subst.info.dictParam)
|
transformCall(call)
|
||||||
|
|
||||||
case ir.OFUNCINST:
|
case ir.OFUNCINST:
|
||||||
// A call with an OFUNCINST will get transformed
|
// A call with an OFUNCINST will get transformed
|
||||||
|
|
@ -1276,7 +1276,7 @@ func (g *genInst) dictPass(info *instInfo) {
|
||||||
m.(*ir.CallExpr).X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
|
m.(*ir.CallExpr).X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
|
||||||
transformDot(m.(*ir.CallExpr).X.(*ir.SelectorExpr), true)
|
transformDot(m.(*ir.CallExpr).X.(*ir.SelectorExpr), true)
|
||||||
}
|
}
|
||||||
transformCall(m.(*ir.CallExpr), info.dictParam)
|
transformCall(m.(*ir.CallExpr))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCONVIFACE:
|
case ir.OCONVIFACE:
|
||||||
|
|
|
||||||
|
|
@ -132,9 +132,7 @@ func transformConvCall(n *ir.CallExpr) ir.Node {
|
||||||
// transformCall transforms a normal function/method call. Corresponds to last half
|
// transformCall transforms a normal function/method call. Corresponds to last half
|
||||||
// (non-conversion, non-builtin part) of typecheck.tcCall. This code should work even
|
// (non-conversion, non-builtin part) of typecheck.tcCall. This code should work even
|
||||||
// in the case of OCALL/OFUNCINST.
|
// in the case of OCALL/OFUNCINST.
|
||||||
// The dict parameter is used for OCALLINTER nodes to ensure that the called method
|
func transformCall(n *ir.CallExpr) {
|
||||||
// is retained by the linker.
|
|
||||||
func transformCall(n *ir.CallExpr, dict *ir.Name) {
|
|
||||||
// n.Type() can be nil for calls with no return value
|
// n.Type() can be nil for calls with no return value
|
||||||
assert(n.Typecheck() == 1)
|
assert(n.Typecheck() == 1)
|
||||||
transformArgs(n)
|
transformArgs(n)
|
||||||
|
|
@ -144,17 +142,6 @@ func transformCall(n *ir.CallExpr, dict *ir.Name) {
|
||||||
switch l.Op() {
|
switch l.Op() {
|
||||||
case ir.ODOTINTER:
|
case ir.ODOTINTER:
|
||||||
n.SetOp(ir.OCALLINTER)
|
n.SetOp(ir.OCALLINTER)
|
||||||
if n.X.(*ir.SelectorExpr).X.Type().HasShape() {
|
|
||||||
if dict == nil {
|
|
||||||
base.Fatalf("calls on shape interfaces need a dictionary reference")
|
|
||||||
}
|
|
||||||
dict.SetAddrtaken(true)
|
|
||||||
// KeepAlive isn't exactly the right thing here, as we only
|
|
||||||
// need to keep the dictionary live in the linker-deadcode
|
|
||||||
// sense, not the at-runtime sense. But the at-runtime sense
|
|
||||||
// is stronger, so it works. See issue 48047.
|
|
||||||
n.KeepAlive = append(n.KeepAlive, dict)
|
|
||||||
}
|
|
||||||
|
|
||||||
case ir.ODOTMETH:
|
case ir.ODOTMETH:
|
||||||
l := l.(*ir.SelectorExpr)
|
l := l.(*ir.SelectorExpr)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue