aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/inl.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/inl.go')
-rw-r--r--src/cmd/compile/internal/gc/inl.go110
1 files changed, 27 insertions, 83 deletions
diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go
index b9e19da43f..9cf23caf0e 100644
--- a/src/cmd/compile/internal/gc/inl.go
+++ b/src/cmd/compile/internal/gc/inl.go
@@ -30,6 +30,7 @@ import (
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/logopt"
+ "cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/src"
@@ -54,7 +55,7 @@ const (
func InlinePackage() {
// Find functions that can be inlined and clone them before walk expands them.
- ir.VisitFuncsBottomUp(Target.Decls, func(list []*ir.Func, recursive bool) {
+ ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
numfns := numNonClosures(list)
for _, n := range list {
if !recursive || numfns > 1 {
@@ -72,63 +73,6 @@ func InlinePackage() {
})
}
-// Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
-// the ->sym can be re-used in the local package, so peel it off the receiver's type.
-func fnpkg(fn *ir.Name) *types.Pkg {
- if ir.IsMethod(fn) {
- // method
- rcvr := fn.Type().Recv().Type
-
- if rcvr.IsPtr() {
- rcvr = rcvr.Elem()
- }
- if rcvr.Sym() == nil {
- base.Fatalf("receiver with no sym: [%v] %L (%v)", fn.Sym(), fn, rcvr)
- }
- return rcvr.Sym().Pkg
- }
-
- // non-method
- return fn.Sym().Pkg
-}
-
-// Lazy typechecking of imported bodies. For local functions, caninl will set ->typecheck
-// because they're a copy of an already checked body.
-func typecheckinl(fn *ir.Func) {
- lno := ir.SetPos(fn.Nname)
-
- expandInline(fn)
-
- // typecheckinl is only for imported functions;
- // their bodies may refer to unsafe as long as the package
- // was marked safe during import (which was checked then).
- // the ->inl of a local function has been typechecked before caninl copied it.
- pkg := fnpkg(fn.Nname)
-
- if pkg == types.LocalPkg || pkg == nil {
- return // typecheckinl on local function
- }
-
- if base.Flag.LowerM > 2 || base.Debug.Export != 0 {
- fmt.Printf("typecheck import [%v] %L { %v }\n", fn.Sym(), fn, ir.Nodes(fn.Inl.Body))
- }
-
- savefn := ir.CurFunc
- ir.CurFunc = fn
- typecheckslice(fn.Inl.Body, ctxStmt)
- ir.CurFunc = savefn
-
- // During expandInline (which imports fn.Func.Inl.Body),
- // declarations are added to fn.Func.Dcl by funcHdr(). Move them
- // to fn.Func.Inl.Dcl for consistency with how local functions
- // behave. (Append because typecheckinl may be called multiple
- // times.)
- fn.Inl.Dcl = append(fn.Inl.Dcl, fn.Dcl...)
- fn.Dcl = nil
-
- base.Pos = lno
-}
-
// Caninl determines whether fn is inlineable.
// If so, caninl saves fn->nbody in fn->inl and substitutes it with a copy.
// fn and ->nbody will already have been typechecked.
@@ -270,7 +214,7 @@ func inlFlood(n *ir.Name, exportsym func(*ir.Name)) {
}
fn.SetExportInline(true)
- typecheckinl(fn)
+ typecheck.ImportedBody(fn)
// Recursively identify all referenced functions for
// reexport. We want to include even non-called functions,
@@ -601,7 +545,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
as.Rhs.Set(inlconv2list(as.Rhs[0].(*ir.InlinedCallExpr)))
as.SetOp(ir.OAS2)
as.SetTypecheck(0)
- n = typecheck(as, ctxStmt)
+ n = typecheck.Stmt(as)
}
}
@@ -768,7 +712,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
inlMap[fn] = false
}()
if base.Debug.TypecheckInl == 0 {
- typecheckinl(fn)
+ typecheck.ImportedBody(fn)
}
// We have a function node, and it has an inlineable body.
@@ -824,21 +768,21 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
}
if v.Byval() {
- iv := typecheck(inlvar(v), ctxExpr)
+ iv := typecheck.Expr(inlvar(v))
ninit.Append(ir.NewDecl(base.Pos, ir.ODCL, iv))
- ninit.Append(typecheck(ir.NewAssignStmt(base.Pos, iv, o), ctxStmt))
+ ninit.Append(typecheck.Stmt(ir.NewAssignStmt(base.Pos, iv, o)))
inlvars[v] = iv
} else {
- addr := NewName(lookup("&" + v.Sym().Name))
+ addr := typecheck.NewName(typecheck.Lookup("&" + v.Sym().Name))
addr.SetType(types.NewPtr(v.Type()))
- ia := typecheck(inlvar(addr), ctxExpr)
+ ia := typecheck.Expr(inlvar(addr))
ninit.Append(ir.NewDecl(base.Pos, ir.ODCL, ia))
- ninit.Append(typecheck(ir.NewAssignStmt(base.Pos, ia, nodAddr(o)), ctxStmt))
+ ninit.Append(typecheck.Stmt(ir.NewAssignStmt(base.Pos, ia, typecheck.NodAddr(o))))
inlvars[addr] = ia
// When capturing by reference, all occurrence of the captured var
// must be substituted with dereference of the temporary address
- inlvars[v] = typecheck(ir.NewStarExpr(base.Pos, ia), ctxExpr)
+ inlvars[v] = typecheck.Expr(ir.NewStarExpr(base.Pos, ia))
}
}
}
@@ -857,7 +801,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
// nothing should have moved to the heap yet.
base.Fatalf("impossible: %v", ln)
}
- inlf := typecheck(inlvar(ln), ctxExpr)
+ inlf := typecheck.Expr(inlvar(ln))
inlvars[ln] = inlf
if base.Flag.GenDwarfInl > 0 {
if ln.Class_ == ir.PPARAM {
@@ -889,7 +833,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
if n := ir.AsNode(t.Nname); n != nil && !ir.IsBlank(n) && !strings.HasPrefix(n.Sym().Name, "~r") {
n := n.(*ir.Name)
m = inlvar(n)
- m = typecheck(m, ctxExpr)
+ m = typecheck.Expr(m)
inlvars[n] = m
delayretvars = false // found a named result parameter
} else {
@@ -951,7 +895,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
vas = ir.NewAssignStmt(base.Pos, nil, nil)
vas.X = inlParam(param, vas, inlvars)
if len(varargs) == 0 {
- vas.Y = nodnil()
+ vas.Y = typecheck.NodNil()
vas.Y.SetType(param.Type)
} else {
lit := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(param.Type).(ir.Ntype), nil)
@@ -961,11 +905,11 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
}
if len(as.Rhs) != 0 {
- ninit.Append(typecheck(as, ctxStmt))
+ ninit.Append(typecheck.Stmt(as))
}
if vas != nil {
- ninit.Append(typecheck(vas, ctxStmt))
+ ninit.Append(typecheck.Stmt(vas))
}
if !delayretvars {
@@ -973,11 +917,11 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
for _, n := range retvars {
ninit.Append(ir.NewDecl(base.Pos, ir.ODCL, n))
ras := ir.NewAssignStmt(base.Pos, n, nil)
- ninit.Append(typecheck(ras, ctxStmt))
+ ninit.Append(typecheck.Stmt(ras))
}
}
- retlabel := autolabel(".i")
+ retlabel := typecheck.AutoLabel(".i")
inlgen++
@@ -1021,7 +965,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
lab := ir.NewLabelStmt(base.Pos, retlabel)
body = append(body, lab)
- typecheckslice(body, ctxStmt)
+ typecheck.Stmts(body)
if base.Flag.GenDwarfInl > 0 {
for _, v := range inlfvars {
@@ -1061,7 +1005,7 @@ func inlvar(var_ ir.Node) ir.Node {
fmt.Printf("inlvar %+v\n", var_)
}
- n := NewName(var_.Sym())
+ n := typecheck.NewName(var_.Sym())
n.SetType(var_.Type())
n.Class_ = ir.PAUTO
n.SetUsed(true)
@@ -1074,7 +1018,7 @@ func inlvar(var_ ir.Node) ir.Node {
// Synthesize a variable to store the inlined function's results in.
func retvar(t *types.Field, i int) ir.Node {
- n := NewName(lookupN("~R", i))
+ n := typecheck.NewName(typecheck.LookupNum("~R", i))
n.SetType(t.Type)
n.Class_ = ir.PAUTO
n.SetUsed(true)
@@ -1086,7 +1030,7 @@ func retvar(t *types.Field, i int) ir.Node {
// Synthesize a variable to store the inlined function's arguments
// when they come from a multiple return call.
func argvar(t *types.Type, i int) ir.Node {
- n := NewName(lookupN("~arg", i))
+ n := typecheck.NewName(typecheck.LookupNum("~arg", i))
n.SetType(t.Elem())
n.Class_ = ir.PAUTO
n.SetUsed(true)
@@ -1198,10 +1142,10 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
}
}
- init = append(init, typecheck(as, ctxStmt))
+ init = append(init, typecheck.Stmt(as))
}
init = append(init, ir.NewBranchStmt(base.Pos, ir.OGOTO, subst.retlabel))
- typecheckslice(init, ctxStmt)
+ typecheck.Stmts(init)
return ir.NewBlockStmt(base.Pos, init)
case ir.OGOTO:
@@ -1210,7 +1154,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
m.SetPos(subst.updatedPos(m.Pos()))
m.PtrInit().Set(nil)
p := fmt.Sprintf("%s·%d", n.Label.Name, inlgen)
- m.Label = lookup(p)
+ m.Label = typecheck.Lookup(p)
return m
case ir.OLABEL:
@@ -1219,7 +1163,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
m.SetPos(subst.updatedPos(m.Pos()))
m.PtrInit().Set(nil)
p := fmt.Sprintf("%s·%d", n.Label.Name, inlgen)
- m.Label = lookup(p)
+ m.Label = typecheck.Lookup(p)
return m
}
@@ -1284,7 +1228,7 @@ func devirtualizeCall(call *ir.CallExpr) {
dt := ir.NewTypeAssertExpr(sel.Pos(), sel.X, nil)
dt.SetType(typ)
- x := typecheck(ir.NewSelectorExpr(sel.Pos(), ir.OXDOT, dt, sel.Sel), ctxExpr|ctxCallee)
+ x := typecheck.Callee(ir.NewSelectorExpr(sel.Pos(), ir.OXDOT, dt, sel.Sel))
switch x.Op() {
case ir.ODOTMETH:
x := x.(*ir.SelectorExpr)