sig := call.X.Type()
for _, ret := range sig.Results().FieldSlice() {
- retvars = append(retvars, typecheck.TempAt(base.Pos, ir.CurFunc, ret.Type))
+ retvars = append(retvars, typecheck.TempAt(base.Pos, curfn, ret.Type))
}
sel := call.X.(*ir.SelectorExpr)
// recv must be first in the assignment list as its side effects must
// be ordered before argument side effects.
var lhs, rhs []ir.Node
- recv := typecheck.TempAt(base.Pos, ir.CurFunc, sel.X.Type())
+ recv := typecheck.TempAt(base.Pos, curfn, sel.X.Type())
lhs = append(lhs, recv)
rhs = append(rhs, sel.X)
// such as labels (possible in InlinedCall nodes).
args := call.Args.Take()
for _, arg := range args {
- argvar := typecheck.TempAt(base.Pos, ir.CurFunc, arg.Type())
+ argvar := typecheck.TempAt(base.Pos, curfn, arg.Type())
lhs = append(lhs, argvar)
rhs = append(rhs, arg)
argvars := append([]ir.Node(nil), lhs[1:]...)
call.Args = argvars
- tmpnode := typecheck.TempAt(base.Pos, ir.CurFunc, concretetyp)
- tmpok := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
+ tmpnode := typecheck.TempAt(base.Pos, curfn, concretetyp)
+ tmpok := typecheck.TempAt(base.Pos, curfn, types.Types[types.TBOOL])
assert := ir.NewTypeAssertExpr(pos, recv, concretetyp)
var inlCalls []*ir.InlinedCallExpr
var edit func(ir.Node) ir.Node
edit = func(n ir.Node) ir.Node {
- return inlnode(n, bigCaller, &inlCalls, edit, profile)
+ return inlnode(fn, n, bigCaller, &inlCalls, edit, profile)
}
ir.EditChildren(fn, edit)
// The result of inlnode MUST be assigned back to n, e.g.
//
// n.Left = inlnode(n.Left)
-func inlnode(n ir.Node, bigCaller bool, inlCalls *[]*ir.InlinedCallExpr, edit func(ir.Node) ir.Node, profile *pgo.Profile) ir.Node {
+func inlnode(callerfn *ir.Func, n ir.Node, bigCaller bool, inlCalls *[]*ir.InlinedCallExpr, edit func(ir.Node) ir.Node, profile *pgo.Profile) ir.Node {
if n == nil {
return n
}
if ir.IsIntrinsicCall(call) {
break
}
- if fn := inlCallee(ir.CurFunc, call.X, profile); fn != nil && typecheck.HaveInlineBody(fn) {
- n = mkinlcall(call, fn, bigCaller, inlCalls)
+ if fn := inlCallee(callerfn, call.X, profile); fn != nil && typecheck.HaveInlineBody(fn) {
+ n = mkinlcall(callerfn, call, fn, bigCaller, inlCalls)
}
}
// InlineCall allows the inliner implementation to be overridden.
// If it returns nil, the function will not be inlined.
-var InlineCall = func(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
+var InlineCall = func(callerfn *ir.Func, call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
base.Fatalf("inline.InlineCall not overridden")
panic("unreachable")
}
// The result of mkinlcall MUST be assigned back to n, e.g.
//
// n.Left = mkinlcall(n.Left, fn, isddd)
-func mkinlcall(n *ir.CallExpr, fn *ir.Func, bigCaller bool, inlCalls *[]*ir.InlinedCallExpr) ir.Node {
+func mkinlcall(callerfn *ir.Func, n *ir.CallExpr, fn *ir.Func, bigCaller bool, inlCalls *[]*ir.InlinedCallExpr) ir.Node {
if fn.Inl == nil {
if logopt.Enabled() {
- logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+ logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(callerfn),
fmt.Sprintf("%s cannot be inlined", ir.PkgFuncName(fn)))
}
return n
}
- if ok, maxCost := inlineCostOK(n, ir.CurFunc, fn, bigCaller); !ok {
+ if ok, maxCost := inlineCostOK(n, callerfn, fn, bigCaller); !ok {
if logopt.Enabled() {
- logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+ logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(callerfn),
fmt.Sprintf("cost %d of %s exceeds max caller cost %d", fn.Inl.Cost, ir.PkgFuncName(fn), maxCost))
}
return n
}
- if fn == ir.CurFunc {
+ if fn == callerfn {
// Can't recursively inline a function into itself.
if logopt.Enabled() {
- logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(ir.CurFunc)))
+ logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(callerfn)))
}
return n
}
for inlIndex := parent; inlIndex >= 0; inlIndex = base.Ctxt.InlTree.Parent(inlIndex) {
if base.Ctxt.InlTree.InlinedFunction(inlIndex) == sym {
if base.Flag.LowerM > 1 {
- fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(ir.CurFunc))
+ fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(callerfn))
}
return n
}
fmt.Printf("%v: Before inlining: %+v\n", ir.Line(n), n)
}
- res := InlineCall(n, fn, inlIndex)
+ res := InlineCall(callerfn, n, fn, inlIndex)
if res == nil {
base.FatalfAt(n.Pos(), "inlining call to %v failed", fn)
if base.LoopVarHash.MatchPos(n.Pos(), desc) {
// Rename the loop key, prefix body with assignment from loop key
transformed = append(transformed, VarAndLoop{n, x, lastPos})
- tk := typecheck.TempAt(base.Pos, ir.CurFunc, n.Type())
+ tk := typecheck.TempAt(base.Pos, fn, n.Type())
tk.SetTypecheck(1)
as := ir.NewAssignStmt(x.Pos(), n, tk)
as.Def = true
for _, z := range leaked {
transformed = append(transformed, VarAndLoop{z, x, lastPos})
- tz := typecheck.TempAt(base.Pos, ir.CurFunc, z.Type())
+ tz := typecheck.TempAt(base.Pos, fn, z.Type())
tz.SetTypecheck(1)
zPrimeForZ[z] = tz
// body' = prebody +
// (6) if tmp_first {tmp_first = false} else {Post} +
// if !cond {break} + ...
- tmpFirst := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
+ tmpFirst := typecheck.TempAt(base.Pos, fn, types.Types[types.TBOOL])
// tmpFirstAssign assigns val to tmpFirst
tmpFirstAssign := func(val bool) *ir.AssignStmt {