}
o.free[key] = a[:len(a)-1]
} else {
- v = typecheck.Temp(t)
+ v = typecheck.TempAt(base.Pos, ir.CurFunc, t)
}
if clear {
o.append(ir.NewAssignStmt(base.Pos, v, nil))
if l == n.X {
return n
}
- a := ir.SepCopy(n).(*ir.UnaryExpr)
+ a := ir.Copy(n).(*ir.UnaryExpr)
a.X = l
return typecheck.Expr(a)
}
if l == n.X {
return n
}
- a := ir.SepCopy(n).(*ir.UnaryExpr)
+ a := ir.Copy(n).(*ir.UnaryExpr)
a.X = l
return typecheck.Expr(a)
if l == n.X {
return n
}
- a := ir.SepCopy(n).(*ir.SelectorExpr)
+ a := ir.Copy(n).(*ir.SelectorExpr)
a.X = l
return typecheck.Expr(a)
if l == n.X {
return n
}
- a := ir.SepCopy(n).(*ir.SelectorExpr)
+ a := ir.Copy(n).(*ir.SelectorExpr)
a.X = l
return typecheck.Expr(a)
if l == n.X {
return n
}
- a := ir.SepCopy(n).(*ir.StarExpr)
+ a := ir.Copy(n).(*ir.StarExpr)
a.X = l
return typecheck.Expr(a)
if l == n.X && r == n.Index {
return n
}
- a := ir.SepCopy(n).(*ir.IndexExpr)
+ a := ir.Copy(n).(*ir.IndexExpr)
a.X = l
a.Index = r
return typecheck.Expr(a)
n := nn.(*ir.CallExpr)
typecheck.AssertFixedCall(n)
- if isFuncPCIntrinsic(n) && isIfaceOfFunc(n.Args[0]) {
+ if ir.IsFuncPCIntrinsic(n) && ir.IsIfaceOfFunc(n.Args[0]) != nil {
// For internal/abi.FuncPCABIxxx(fn), if fn is a defined function,
// do not introduce temporaries here, so it is easier to rewrite it
// to symbol address reference later in walk.
return
}
- n.X = o.expr(n.X, nil)
+ n.Fun = o.expr(n.Fun, nil)
o.exprList(n.Args)
}
o.out = append(o.out, n)
o.popTemp(t)
- case ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
+ case ir.OPRINT, ir.OPRINTLN, ir.ORECOVERFP:
n := n.(*ir.CallExpr)
t := o.markTemp()
o.call(n)
orderBody := true
xt := typecheck.RangeExprType(n.X.Type())
- switch xt.Kind() {
+ switch k := xt.Kind(); {
default:
base.Fatalf("order.stmt range %v", n.Type())
- case types.TARRAY, types.TSLICE:
+ case types.IsInt[k]:
+ // Used only once, no need to copy.
+
+ case k == types.TARRAY, k == types.TSLICE:
if n.Value == nil || ir.IsBlank(n.Value) {
// for i := range x will only use x once, to compute len(x).
// No need to copy it.
}
fallthrough
- case types.TCHAN, types.TSTRING:
+ case k == types.TCHAN, k == types.TSTRING:
// chan, string, slice, array ranges use value multiple times.
// make copy.
r := n.X
n.X = o.copyExpr(r)
- case types.TMAP:
+ case k == types.TMAP:
if isMapClear(n) {
// Preserve the body of the map clear pattern so it can
// be detected during walk. The loop body will not be used
// n.Prealloc is the temp for the iterator.
// MapIterType contains pointers and needs to be zeroed.
- n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
+ n.Prealloc = o.newTemp(reflectdata.MapIterType(), true)
}
n.Key = o.exprInPlace(n.Key)
n.Value = o.exprInPlace(n.Value)
// concrete type (not interface) argument might need an addressable
// temporary to pass to the runtime conversion routine.
- case ir.OCONVIFACE, ir.OCONVIDATA:
+ case ir.OCONVIFACE:
n := n.(*ir.ConvExpr)
n.X = o.expr(n.X, nil)
if n.X.Type().IsInterface() {
if _, _, needsaddr := dataWordFuncName(n.X.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
// Need a temp if we need to pass the address to the conversion function.
// We also process static composite literal node here, making a named static global
- // whose address we can put directly in an interface (see OCONVIFACE/OCONVIDATA case in walk).
+ // whose address we can put directly in an interface (see OCONVIFACE case in walk).
n.X = o.addrTemp(n.X)
}
return n
o.out = append(o.out, n)
o.stmt(typecheck.Stmt(as))
}
-
-// isFuncPCIntrinsic returns whether n is a direct call of internal/abi.FuncPCABIxxx functions.
-func isFuncPCIntrinsic(n *ir.CallExpr) bool {
- if n.Op() != ir.OCALLFUNC || n.X.Op() != ir.ONAME {
- return false
- }
- fn := n.X.(*ir.Name).Sym()
- return (fn.Name == "FuncPCABI0" || fn.Name == "FuncPCABIInternal") &&
- (fn.Pkg.Path == "internal/abi" || fn.Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "internal/abi")
-}
-
-// isIfaceOfFunc returns whether n is an interface conversion from a direct reference of a func.
-func isIfaceOfFunc(n ir.Node) bool {
- return n.Op() == ir.OCONVIFACE && n.(*ir.ConvExpr).X.Op() == ir.ONAME && n.(*ir.ConvExpr).X.(*ir.Name).Class == ir.PFUNC
-}