aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compile/internal/gc/alg.go52
-rw-r--r--src/cmd/compile/internal/gc/builtin.go185
-rw-r--r--src/cmd/compile/internal/gc/builtin_test.go1
-rw-r--r--src/cmd/compile/internal/gc/closure.go46
-rw-r--r--src/cmd/compile/internal/gc/const.go91
-rw-r--r--src/cmd/compile/internal/gc/dcl.go141
-rw-r--r--src/cmd/compile/internal/gc/escape.go75
-rw-r--r--src/cmd/compile/internal/gc/gen.go24
-rw-r--r--src/cmd/compile/internal/gc/go.go25
-rw-r--r--src/cmd/compile/internal/gc/gsubr.go8
-rw-r--r--src/cmd/compile/internal/gc/iexport.go4
-rw-r--r--src/cmd/compile/internal/gc/iimport.go4
-rw-r--r--src/cmd/compile/internal/gc/init.go4
-rw-r--r--src/cmd/compile/internal/gc/initorder.go4
-rw-r--r--src/cmd/compile/internal/gc/inl.go163
-rw-r--r--src/cmd/compile/internal/gc/main.go12
-rw-r--r--src/cmd/compile/internal/gc/noder.go46
-rw-r--r--src/cmd/compile/internal/gc/obj.go4
-rw-r--r--src/cmd/compile/internal/gc/order.go22
-rw-r--r--src/cmd/compile/internal/gc/pgen.go12
-rw-r--r--src/cmd/compile/internal/gc/racewalk.go2
-rw-r--r--src/cmd/compile/internal/gc/range.go32
-rw-r--r--src/cmd/compile/internal/gc/reflect.go14
-rw-r--r--src/cmd/compile/internal/gc/select.go34
-rw-r--r--src/cmd/compile/internal/gc/sinit.go92
-rw-r--r--src/cmd/compile/internal/gc/ssa.go32
-rw-r--r--src/cmd/compile/internal/gc/subr.go113
-rw-r--r--src/cmd/compile/internal/gc/swt.go14
-rw-r--r--src/cmd/compile/internal/gc/typecheck.go213
-rw-r--r--src/cmd/compile/internal/gc/universe.go8
-rw-r--r--src/cmd/compile/internal/gc/walk.go332
-rw-r--r--src/cmd/compile/internal/ir/cfg.go26
-rw-r--r--src/cmd/compile/internal/ir/const.go99
-rw-r--r--src/cmd/compile/internal/ir/expr.go371
-rw-r--r--src/cmd/compile/internal/ir/func.go27
-rw-r--r--src/cmd/compile/internal/ir/name.go22
-rw-r--r--src/cmd/compile/internal/ir/node.go96
-rw-r--r--src/cmd/compile/internal/ir/scc.go (renamed from src/cmd/compile/internal/gc/scc.go)66
38 files changed, 1255 insertions, 1261 deletions
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go
index bcf992ba4b..d21b0d492c 100644
--- a/src/cmd/compile/internal/gc/alg.go
+++ b/src/cmd/compile/internal/gc/alg.go
@@ -147,10 +147,10 @@ func genhash(t *types.Type) *obj.LSym {
// func sym(p *T, h uintptr) uintptr
args := []*ir.Field{
- namedfield("p", types.NewPtr(t)),
- namedfield("h", types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, lookup("p"), nil, types.NewPtr(t)),
+ ir.NewField(base.Pos, lookup("h"), nil, types.Types[types.TUINTPTR]),
}
- results := []*ir.Field{anonfield(types.Types[types.TUINTPTR])}
+ results := []*ir.Field{ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR])}
tfn := ir.NewFuncType(base.Pos, nil, args, results)
fn := dclfunc(sym, tfn)
@@ -166,9 +166,9 @@ func genhash(t *types.Type) *obj.LSym {
// for i := 0; i < nelem; i++
ni := temp(types.Types[types.TINT])
- init := ir.NewAssignStmt(base.Pos, ni, nodintconst(0))
- cond := ir.NewBinaryExpr(base.Pos, ir.OLT, ni, nodintconst(t.NumElem()))
- post := ir.NewAssignStmt(base.Pos, ni, ir.NewBinaryExpr(base.Pos, ir.OADD, ni, nodintconst(1)))
+ init := ir.NewAssignStmt(base.Pos, ni, ir.NewInt(0))
+ cond := ir.NewBinaryExpr(base.Pos, ir.OLT, ni, ir.NewInt(t.NumElem()))
+ post := ir.NewAssignStmt(base.Pos, ni, ir.NewBinaryExpr(base.Pos, ir.OADD, ni, ir.NewInt(1)))
loop := ir.NewForStmt(base.Pos, nil, cond, post, nil)
loop.PtrInit().Append(init)
@@ -219,7 +219,7 @@ func genhash(t *types.Type) *obj.LSym {
na := nodAddr(nx)
call.Args.Append(na)
call.Args.Append(nh)
- call.Args.Append(nodintconst(size))
+ call.Args.Append(ir.NewInt(size))
fn.Body.Append(ir.NewAssignStmt(base.Pos, nh, call))
i = next
@@ -239,9 +239,9 @@ func genhash(t *types.Type) *obj.LSym {
fn.SetDupok(true)
typecheckFunc(fn)
- Curfn = fn
+ ir.CurFunc = fn
typecheckslice(fn.Body, ctxStmt)
- Curfn = nil
+ ir.CurFunc = nil
if base.Debug.DclStack != 0 {
types.CheckDclstack()
@@ -285,12 +285,12 @@ func hashfor(t *types.Type) ir.Node {
}
n := NewName(sym)
- setNodeNameFunc(n)
+ ir.MarkFunc(n)
n.SetType(functype(nil, []*ir.Field{
- anonfield(types.NewPtr(t)),
- anonfield(types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, nil, nil, types.NewPtr(t)),
+ ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]),
}, []*ir.Field{
- anonfield(types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]),
}))
return n
}
@@ -376,8 +376,8 @@ func geneq(t *types.Type) *obj.LSym {
// func sym(p, q *T) bool
tfn := ir.NewFuncType(base.Pos, nil,
- []*ir.Field{namedfield("p", types.NewPtr(t)), namedfield("q", types.NewPtr(t))},
- []*ir.Field{namedfield("r", types.Types[types.TBOOL])})
+ []*ir.Field{ir.NewField(base.Pos, lookup("p"), nil, types.NewPtr(t)), ir.NewField(base.Pos, lookup("q"), nil, types.NewPtr(t))},
+ []*ir.Field{ir.NewField(base.Pos, lookup("r"), nil, types.Types[types.TBOOL])})
fn := dclfunc(sym, tfn)
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
@@ -440,20 +440,20 @@ func geneq(t *types.Type) *obj.LSym {
// Generate a series of checks.
for i := int64(0); i < nelem; i++ {
// if check {} else { goto neq }
- nif := ir.NewIfStmt(base.Pos, checkIdx(nodintconst(i)), nil, nil)
+ nif := ir.NewIfStmt(base.Pos, checkIdx(ir.NewInt(i)), nil, nil)
nif.Else.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, neq))
fn.Body.Append(nif)
}
if last {
- fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, checkIdx(nodintconst(nelem))))
+ fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, checkIdx(ir.NewInt(nelem))))
}
} else {
// Generate a for loop.
// for i := 0; i < nelem; i++
i := temp(types.Types[types.TINT])
- init := ir.NewAssignStmt(base.Pos, i, nodintconst(0))
- cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, nodintconst(nelem))
- post := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, nodintconst(1)))
+ init := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0))
+ cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(nelem))
+ post := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1)))
loop := ir.NewForStmt(base.Pos, nil, cond, post, nil)
loop.PtrInit().Append(init)
// if eq(pi, qi) {} else { goto neq }
@@ -462,7 +462,7 @@ func geneq(t *types.Type) *obj.LSym {
loop.Body.Append(nif)
fn.Body.Append(loop)
if last {
- fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, nodbool(true)))
+ fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(true)))
}
}
}
@@ -572,7 +572,7 @@ func geneq(t *types.Type) *obj.LSym {
}
if len(flatConds) == 0 {
- fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, nodbool(true)))
+ fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(true)))
} else {
for _, c := range flatConds[:len(flatConds)-1] {
// if cond {} else { goto neq }
@@ -594,7 +594,7 @@ func geneq(t *types.Type) *obj.LSym {
// r = false
// return (or goto ret)
fn.Body.Append(ir.NewLabelStmt(base.Pos, neq))
- fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, nodbool(false)))
+ fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(false)))
if EqCanPanic(t) || anyCall(fn) {
// Epilogue is large, so share it with the equal case.
fn.Body.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, ret))
@@ -615,9 +615,9 @@ func geneq(t *types.Type) *obj.LSym {
fn.SetDupok(true)
typecheckFunc(fn)
- Curfn = fn
+ ir.CurFunc = fn
typecheckslice(fn.Body, ctxStmt)
- Curfn = nil
+ ir.CurFunc = nil
if base.Debug.DclStack != 0 {
types.CheckDclstack()
@@ -726,7 +726,7 @@ func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node {
call.Args.Append(nx)
call.Args.Append(ny)
if needsize {
- call.Args.Append(nodintconst(size))
+ call.Args.Append(ir.NewInt(size))
}
return call
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index d3e3f9ade6..12c70fb6d4 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -3,6 +3,7 @@
package gc
import (
+ "cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/types"
)
@@ -211,133 +212,133 @@ func runtimeTypes() []*types.Type {
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[types.TANY]
typs[3] = types.NewPtr(typs[2])
- typs[4] = functype(nil, []*ir.Field{anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])})
+ typs[4] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])})
typs[5] = types.Types[types.TUINTPTR]
typs[6] = types.Types[types.TBOOL]
typs[7] = types.Types[types.TUNSAFEPTR]
- typs[8] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[7])})
+ typs[8] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[6])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])})
typs[9] = functype(nil, nil, nil)
typs[10] = types.Types[types.TINTER]
- typs[11] = functype(nil, []*ir.Field{anonfield(typs[10])}, nil)
+ typs[11] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[10])}, nil)
typs[12] = types.Types[types.TINT32]
typs[13] = types.NewPtr(typs[12])
- typs[14] = functype(nil, []*ir.Field{anonfield(typs[13])}, []*ir.Field{anonfield(typs[10])})
+ typs[14] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[13])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[10])})
typs[15] = types.Types[types.TINT]
- typs[16] = functype(nil, []*ir.Field{anonfield(typs[15]), anonfield(typs[15])}, nil)
+ typs[16] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15])}, nil)
typs[17] = types.Types[types.TUINT]
- typs[18] = functype(nil, []*ir.Field{anonfield(typs[17]), anonfield(typs[15])}, nil)
- typs[19] = functype(nil, []*ir.Field{anonfield(typs[6])}, nil)
+ typs[18] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[17]), ir.NewField(base.Pos, nil, nil, typs[15])}, nil)
+ typs[19] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}, nil)
typs[20] = types.Types[types.TFLOAT64]
- typs[21] = functype(nil, []*ir.Field{anonfield(typs[20])}, nil)
+ typs[21] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, nil)
typs[22] = types.Types[types.TINT64]
- typs[23] = functype(nil, []*ir.Field{anonfield(typs[22])}, nil)
+ typs[23] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])}, nil)
typs[24] = types.Types[types.TUINT64]
- typs[25] = functype(nil, []*ir.Field{anonfield(typs[24])}, nil)
+ typs[25] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])}, nil)
typs[26] = types.Types[types.TCOMPLEX128]
- typs[27] = functype(nil, []*ir.Field{anonfield(typs[26])}, nil)
+ typs[27] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[26])}, nil)
typs[28] = types.Types[types.TSTRING]
- typs[29] = functype(nil, []*ir.Field{anonfield(typs[28])}, nil)
- typs[30] = functype(nil, []*ir.Field{anonfield(typs[2])}, nil)
- typs[31] = functype(nil, []*ir.Field{anonfield(typs[5])}, nil)
+ typs[29] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}, nil)
+ typs[30] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])}, nil)
+ typs[31] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5])}, nil)
typs[32] = types.NewArray(typs[0], 32)
typs[33] = types.NewPtr(typs[32])
- typs[34] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
- typs[35] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
- typs[36] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
- typs[37] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
+ typs[34] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
+ typs[35] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
+ typs[36] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
+ typs[37] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
typs[38] = types.NewSlice(typs[28])
- typs[39] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[38])}, []*ir.Field{anonfield(typs[28])})
- typs[40] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])})
+ typs[39] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[38])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
+ typs[40] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])})
typs[41] = types.NewArray(typs[0], 4)
typs[42] = types.NewPtr(typs[41])
- typs[43] = functype(nil, []*ir.Field{anonfield(typs[42]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[28])})
- typs[44] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])})
- typs[45] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])})
+ typs[43] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[42]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
+ typs[44] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
+ typs[45] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
typs[46] = types.RuneType
typs[47] = types.NewSlice(typs[46])
- typs[48] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[47])}, []*ir.Field{anonfield(typs[28])})
+ typs[48] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[47])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])})
typs[49] = types.NewSlice(typs[0])
- typs[50] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[49])})
+ typs[50] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[49])})
typs[51] = types.NewArray(typs[46], 32)
typs[52] = types.NewPtr(typs[51])
- typs[53] = functype(nil, []*ir.Field{anonfield(typs[52]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[47])})
- typs[54] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[15])})
- typs[55] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[46]), anonfield(typs[15])})
- typs[56] = functype(nil, []*ir.Field{anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])})
- typs[57] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2])})
- typs[58] = functype(nil, []*ir.Field{anonfield(typs[2])}, []*ir.Field{anonfield(typs[7])})
- typs[59] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[2])})
- typs[60] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2]), anonfield(typs[6])})
- typs[61] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
- typs[62] = functype(nil, []*ir.Field{anonfield(typs[1])}, nil)
+ typs[53] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[52]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[47])})
+ typs[54] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])})
+ typs[55] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[46]), ir.NewField(base.Pos, nil, nil, typs[15])})
+ typs[56] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])})
+ typs[57] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])})
+ typs[58] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])})
+ typs[59] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])})
+ typs[60] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2]), ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[61] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[1])}, nil)
+ typs[62] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1])}, nil)
typs[63] = types.NewPtr(typs[5])
- typs[64] = functype(nil, []*ir.Field{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])})
+ typs[64] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[63]), ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[7])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
typs[65] = types.Types[types.TUINT32]
- typs[66] = functype(nil, nil, []*ir.Field{anonfield(typs[65])})
+ typs[66] = functype(nil, nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65])})
typs[67] = types.NewMap(typs[2], typs[2])
- typs[68] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])})
- typs[69] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])})
- typs[70] = functype(nil, nil, []*ir.Field{anonfield(typs[67])})
- typs[71] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3])})
- typs[72] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3])})
- typs[73] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])})
- typs[74] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
- typs[75] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
- typs[76] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
- typs[77] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
- typs[78] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
- typs[79] = functype(nil, []*ir.Field{anonfield(typs[3])}, nil)
- typs[80] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67])}, nil)
+ typs[68] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[22]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[67])})
+ typs[69] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[67])})
+ typs[70] = functype(nil, nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[67])})
+ typs[71] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])})
+ typs[72] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])})
+ typs[73] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[1])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])})
+ typs[74] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[75] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[76] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[1])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[77] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil)
+ typs[78] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[2])}, nil)
+ typs[79] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])}, nil)
+ typs[80] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67])}, nil)
typs[81] = types.NewChan(typs[2], types.Cboth)
- typs[82] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[81])})
- typs[83] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[81])})
+ typs[82] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[81])})
+ typs[83] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[81])})
typs[84] = types.NewChan(typs[2], types.Crecv)
- typs[85] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, nil)
- typs[86] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
+ typs[85] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[84]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil)
+ typs[86] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[84]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
typs[87] = types.NewChan(typs[2], types.Csend)
- typs[88] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, nil)
+ typs[88] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[87]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil)
typs[89] = types.NewArray(typs[0], 3)
- typs[90] = tostruct([]*ir.Field{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
- typs[91] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
- typs[92] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, nil)
- typs[93] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[15])})
- typs[94] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
- typs[95] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])})
+ typs[90] = tostruct([]*ir.Field{ir.NewField(base.Pos, lookup("enabled"), nil, typs[6]), ir.NewField(base.Pos, lookup("pad"), nil, typs[89]), ir.NewField(base.Pos, lookup("needed"), nil, typs[6]), ir.NewField(base.Pos, lookup("cgo"), nil, typs[6]), ir.NewField(base.Pos, lookup("alignme"), nil, typs[24])})
+ typs[91] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil)
+ typs[92] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil)
+ typs[93] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])})
+ typs[94] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[87]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[95] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[84])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
typs[96] = types.NewPtr(typs[6])
- typs[97] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])})
- typs[98] = functype(nil, []*ir.Field{anonfield(typs[63])}, nil)
- typs[99] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[15]), anonfield(typs[6])})
- typs[100] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[7])})
- typs[101] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[7])})
- typs[102] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[7])})
+ typs[97] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[96]), ir.NewField(base.Pos, nil, nil, typs[84])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[98] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[63])}, nil)
+ typs[99] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[63]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[6])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[100] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])})
+ typs[101] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[22]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])})
+ typs[102] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[7])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])})
typs[103] = types.NewSlice(typs[2])
- typs[104] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[103])})
- typs[105] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
- typs[106] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, nil)
- typs[107] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[6])})
- typs[108] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
- typs[109] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])})
- typs[110] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])})
- typs[111] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])})
- typs[112] = functype(nil, []*ir.Field{anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[22])})
- typs[113] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, []*ir.Field{anonfield(typs[24])})
- typs[114] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[22])})
- typs[115] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[24])})
- typs[116] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[65])})
- typs[117] = functype(nil, []*ir.Field{anonfield(typs[22])}, []*ir.Field{anonfield(typs[20])})
- typs[118] = functype(nil, []*ir.Field{anonfield(typs[24])}, []*ir.Field{anonfield(typs[20])})
- typs[119] = functype(nil, []*ir.Field{anonfield(typs[65])}, []*ir.Field{anonfield(typs[20])})
- typs[120] = functype(nil, []*ir.Field{anonfield(typs[26]), anonfield(typs[26])}, []*ir.Field{anonfield(typs[26])})
- typs[121] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5])}, nil)
- typs[122] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5]), anonfield(typs[5])}, nil)
- typs[123] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
+ typs[104] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[103]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[103])})
+ typs[105] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil)
+ typs[106] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil)
+ typs[107] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[108] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[109] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[7])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])})
+ typs[110] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5])})
+ typs[111] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5])})
+ typs[112] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])})
+ typs[113] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24]), ir.NewField(base.Pos, nil, nil, typs[24])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])})
+ typs[114] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])})
+ typs[115] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])})
+ typs[116] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65])})
+ typs[117] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])})
+ typs[118] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])})
+ typs[119] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])})
+ typs[120] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[26]), ir.NewField(base.Pos, nil, nil, typs[26])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[26])})
+ typs[121] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil)
+ typs[122] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil)
+ typs[123] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil)
typs[124] = types.NewSlice(typs[7])
- typs[125] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[124])}, nil)
+ typs[125] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[124])}, nil)
typs[126] = types.Types[types.TUINT8]
- typs[127] = functype(nil, []*ir.Field{anonfield(typs[126]), anonfield(typs[126])}, nil)
+ typs[127] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[126]), ir.NewField(base.Pos, nil, nil, typs[126])}, nil)
typs[128] = types.Types[types.TUINT16]
- typs[129] = functype(nil, []*ir.Field{anonfield(typs[128]), anonfield(typs[128])}, nil)
- typs[130] = functype(nil, []*ir.Field{anonfield(typs[65]), anonfield(typs[65])}, nil)
- typs[131] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, nil)
+ typs[129] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[128]), ir.NewField(base.Pos, nil, nil, typs[128])}, nil)
+ typs[130] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65]), ir.NewField(base.Pos, nil, nil, typs[65])}, nil)
+ typs[131] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24]), ir.NewField(base.Pos, nil, nil, typs[24])}, nil)
return typs[:]
}
diff --git a/src/cmd/compile/internal/gc/builtin_test.go b/src/cmd/compile/internal/gc/builtin_test.go
index 57f24b2287..df15ca5c7d 100644
--- a/src/cmd/compile/internal/gc/builtin_test.go
+++ b/src/cmd/compile/internal/gc/builtin_test.go
@@ -13,6 +13,7 @@ import (
)
func TestBuiltin(t *testing.T) {
+ t.Skip("mkbuiltin needs fixing")
testenv.MustHaveGoRun(t)
t.Parallel()
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go
index 27a9bc7cf8..e758cf86d4 100644
--- a/src/cmd/compile/internal/gc/closure.go
+++ b/src/cmd/compile/internal/gc/closure.go
@@ -18,8 +18,8 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
ntype := p.typeExpr(expr.Type)
fn := ir.NewFunc(p.pos(expr))
- fn.SetIsHiddenClosure(Curfn != nil)
- fn.Nname = newFuncNameAt(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure
+ fn.SetIsHiddenClosure(ir.CurFunc != nil)
+ fn.Nname = ir.NewFuncNameAt(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure
fn.Nname.Ntype = xtype
fn.Nname.Defn = fn
@@ -111,22 +111,22 @@ func typecheckclosure(clo *ir.ClosureExpr, top int) {
}
}
- fn.Nname.SetSym(closurename(Curfn))
- setNodeNameFunc(fn.Nname)
+ fn.Nname.SetSym(closurename(ir.CurFunc))
+ ir.MarkFunc(fn.Nname)
typecheckFunc(fn)
// Type check the body now, but only if we're inside a function.
// At top level (in a variable initialization: curfn==nil) we're not
// ready to type check code yet; we'll check it later, because the
// underlying closure function we create is added to Target.Decls.
- if Curfn != nil && clo.Type() != nil {
- oldfn := Curfn
- Curfn = fn
+ if ir.CurFunc != nil && clo.Type() != nil {
+ oldfn := ir.CurFunc
+ ir.CurFunc = fn
olddd := decldepth
decldepth = 1
typecheckslice(fn.Body, ctxStmt)
decldepth = olddd
- Curfn = oldfn
+ ir.CurFunc = oldfn
}
Target.Decls = append(Target.Decls, fn)
@@ -335,13 +335,13 @@ func hasemptycvars(clo *ir.ClosureExpr) bool {
// and compiling runtime
func closuredebugruntimecheck(clo *ir.ClosureExpr) {
if base.Debug.Closure > 0 {
- if clo.Esc() == EscHeap {
+ if clo.Esc() == ir.EscHeap {
base.WarnfAt(clo.Pos(), "heap closure, captured vars = %v", clo.Func.ClosureVars)
} else {
base.WarnfAt(clo.Pos(), "stack closure, captured vars = %v", clo.Func.ClosureVars)
}
}
- if base.Flag.CompilingRuntime && clo.Esc() == EscHeap {
+ if base.Flag.CompilingRuntime && clo.Esc() == ir.EscHeap {
base.ErrorfAt(clo.Pos(), "heap-allocated closure, not allowed in runtime")
}
}
@@ -364,14 +364,14 @@ func closureType(clo *ir.ClosureExpr) *types.Type {
// the struct is unnamed so that closures in multiple packages with the
// same struct type can share the descriptor.
fields := []*ir.Field{
- namedfield(".F", types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, lookup(".F"), nil, types.Types[types.TUINTPTR]),
}
for _, v := range clo.Func.ClosureVars {
typ := v.Type()
if !v.Byval() {
typ = types.NewPtr(typ)
}
- fields = append(fields, symfield(v.Sym(), typ))
+ fields = append(fields, ir.NewField(base.Pos, v.Sym(), nil, typ))
}
typ := tostruct(fields)
typ.SetNoalg(true)
@@ -435,16 +435,16 @@ func typecheckpartialcall(n ir.Node, sym *types.Sym) *ir.CallPartExpr {
// for partial calls.
func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.Func {
rcvrtype := dot.X.Type()
- sym := methodSymSuffix(rcvrtype, meth, "-fm")
+ sym := ir.MethodSymSuffix(rcvrtype, meth, "-fm")
if sym.Uniq() {
return sym.Def.(*ir.Func)
}
sym.SetUniq(true)
- savecurfn := Curfn
+ savecurfn := ir.CurFunc
saveLineNo := base.Pos
- Curfn = nil
+ ir.CurFunc = nil
// Set line number equal to the line number where the method is declared.
var m *types.Field
@@ -480,7 +480,7 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.
}
call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil)
- call.Args.Set(paramNnames(tfn.Type()))
+ call.Args.Set(ir.ParamNames(tfn.Type()))
call.IsDDD = tfn.Type().IsVariadic()
if t0.NumResults() != 0 {
ret := ir.NewReturnStmt(base.Pos, nil)
@@ -496,11 +496,11 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.
typecheckFunc(fn)
// Need to typecheck the body of the just-generated wrapper.
// typecheckslice() requires that Curfn is set when processing an ORETURN.
- Curfn = fn
+ ir.CurFunc = fn
typecheckslice(fn.Body, ctxStmt)
sym.Def = fn
Target.Decls = append(Target.Decls, fn)
- Curfn = savecurfn
+ ir.CurFunc = savecurfn
base.Pos = saveLineNo
return fn
@@ -511,8 +511,8 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.
// The address of a variable of the returned type can be cast to a func.
func partialCallType(n *ir.CallPartExpr) *types.Type {
t := tostruct([]*ir.Field{
- namedfield("F", types.Types[types.TUINTPTR]),
- namedfield("R", n.X.Type()),
+ ir.NewField(base.Pos, lookup("F"), nil, types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, lookup("R"), nil, n.X.Type()),
})
t.SetNoalg(true)
return t
@@ -562,9 +562,3 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
return walkexpr(cfn, init)
}
-
-// callpartMethod returns the *types.Field representing the method
-// referenced by method value n.
-func callpartMethod(n ir.Node) *types.Field {
- return n.(*ir.CallPartExpr).Method
-}
diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go
index 553f06757f..ad27f3ea44 100644
--- a/src/cmd/compile/internal/gc/const.go
+++ b/src/cmd/compile/internal/gc/const.go
@@ -18,30 +18,6 @@ import (
"unicode"
)
-const (
- // Maximum size in bits for big.Ints before signalling
- // overflow and also mantissa precision for big.Floats.
- Mpprec = 512
-)
-
-func bigFloatVal(v constant.Value) *big.Float {
- f := new(big.Float)
- f.SetPrec(Mpprec)
- switch u := constant.Val(v).(type) {
- case int64:
- f.SetInt64(u)
- case *big.Int:
- f.SetInt(u)
- case *big.Float:
- f.Set(u)
- case *big.Rat:
- f.SetRat(u)
- default:
- base.Fatalf("unexpected: %v", u)
- }
- return f
-}
-
func roundFloat(v constant.Value, sz int64) constant.Value {
switch sz {
case 4:
@@ -334,8 +310,8 @@ func toint(v constant.Value) constant.Value {
// something that looks like an integer we omit the
// value from the error message.
// (See issue #11371).
- f := bigFloatVal(v)
- if f.MantExp(nil) > 2*Mpprec {
+ f := ir.BigFloat(v)
+ if f.MantExp(nil) > 2*ir.ConstPrec {
base.Errorf("integer too large")
} else {
var t big.Float
@@ -352,38 +328,6 @@ func toint(v constant.Value) constant.Value {
return constant.MakeInt64(1)
}
-// doesoverflow reports whether constant value v is too large
-// to represent with type t.
-func doesoverflow(v constant.Value, t *types.Type) bool {
- switch {
- case t.IsInteger():
- bits := uint(8 * t.Size())
- if t.IsUnsigned() {
- x, ok := constant.Uint64Val(v)
- return !ok || x>>bits != 0
- }
- x, ok := constant.Int64Val(v)
- if x < 0 {
- x = ^x
- }
- return !ok || x>>(bits-1) != 0
- case t.IsFloat():
- switch t.Size() {
- case 4:
- f, _ := constant.Float32Val(v)
- return math.IsInf(float64(f), 0)
- case 8:
- f, _ := constant.Float64Val(v)
- return math.IsInf(f, 0)
- }
- case t.IsComplex():
- ft := types.FloatForComplex(t)
- return doesoverflow(constant.Real(v), ft) || doesoverflow(constant.Imag(v), ft)
- }
- base.Fatalf("doesoverflow: %v, %v", v, t)
- panic("unreachable")
-}
-
// overflow reports whether constant value v is too large
// to represent with type t, and emits an error message if so.
func overflow(v constant.Value, t *types.Type) bool {
@@ -392,11 +336,11 @@ func overflow(v constant.Value, t *types.Type) bool {
if t.IsUntyped() {
return false
}
- if v.Kind() == constant.Int && constant.BitLen(v) > Mpprec {
+ if v.Kind() == constant.Int && constant.BitLen(v) > ir.ConstPrec {
base.Errorf("integer too large")
return true
}
- if doesoverflow(v, t) {
+ if ir.ConstOverflow(v, t) {
base.Errorf("constant %v overflows %v", types.FmtConst(v, false), t)
return true
}
@@ -656,13 +600,13 @@ var overflowNames = [...]string{
// origConst returns an OLITERAL with orig n and value v.
func origConst(n ir.Node, v constant.Value) ir.Node {
- lno := setlineno(n)
+ lno := ir.SetPos(n)
v = convertVal(v, n.Type(), false)
base.Pos = lno
switch v.Kind() {
case constant.Int:
- if constant.BitLen(v) <= Mpprec {
+ if constant.BitLen(v) <= ir.ConstPrec {
break
}
fallthrough
@@ -778,14 +722,6 @@ func defaultType(t *types.Type) *types.Type {
return nil
}
-func smallintconst(n ir.Node) bool {
- if n.Op() == ir.OLITERAL {
- v, ok := constant.Int64Val(n.Val())
- return ok && int64(int32(v)) == v
- }
- return false
-}
-
// indexconst checks if Node n contains a constant expression
// representable as a non-negative int and returns its value.
// If n is not a constant expression, not representable as an
@@ -803,21 +739,12 @@ func indexconst(n ir.Node) int64 {
if v.Kind() != constant.Int || constant.Sign(v) < 0 {
return -1
}
- if doesoverflow(v, types.Types[types.TINT]) {
+ if ir.ConstOverflow(v, types.Types[types.TINT]) {
return -2
}
return ir.IntVal(types.Types[types.TINT], v)
}
-// isGoConst reports whether n is a Go language constant (as opposed to a
-// compile-time constant).
-//
-// Expressions derived from nil, like string([]byte(nil)), while they
-// may be known at compile time, are not Go language constants.
-func isGoConst(n ir.Node) bool {
- return n.Op() == ir.OLITERAL
-}
-
// anyCallOrChan reports whether n contains any calls or channel operations.
func anyCallOrChan(n ir.Node) bool {
return ir.Any(n, func(n ir.Node) bool {
@@ -875,7 +802,7 @@ func (s *constSet) add(pos src.XPos, n ir.Node, what, where string) {
}
}
- if !isGoConst(n) {
+ if !ir.IsConstNode(n) {
return
}
if n.Type().IsUntyped() {
@@ -906,7 +833,7 @@ func (s *constSet) add(pos src.XPos, n ir.Node, what, where string) {
}
k := constSetKey{typ, ir.ConstValue(n)}
- if hasUniquePos(n) {
+ if ir.HasUniquePos(n) {
pos = n.Pos()
}
diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go
index c084565f3d..1189d0ec12 100644
--- a/src/cmd/compile/internal/gc/dcl.go
+++ b/src/cmd/compile/internal/gc/dcl.go
@@ -80,12 +80,12 @@ func declare(n *ir.Name, ctxt ir.Class) {
}
Target.Externs = append(Target.Externs, n)
} else {
- if Curfn == nil && ctxt == ir.PAUTO {
+ if ir.CurFunc == nil && ctxt == ir.PAUTO {
base.Pos = n.Pos()
base.Fatalf("automatic outside function")
}
- if Curfn != nil && ctxt != ir.PFUNC && n.Op() == ir.ONAME {
- Curfn.Dcl = append(Curfn.Dcl, n)
+ if ir.CurFunc != nil && ctxt != ir.PFUNC && n.Op() == ir.ONAME {
+ ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
}
if n.Op() == ir.OTYPE {
declare_typegen++
@@ -95,7 +95,7 @@ func declare(n *ir.Name, ctxt ir.Class) {
gen = vargen
}
types.Pushdcl(s)
- n.Curfn = Curfn
+ n.Curfn = ir.CurFunc
}
if ctxt == ir.PAUTO {
@@ -137,7 +137,7 @@ func variter(vl []*ir.Name, t ir.Ntype, el []ir.Node) []ir.Node {
declare(v, dclcontext)
v.Ntype = t
v.Defn = as2
- if Curfn != nil {
+ if ir.CurFunc != nil {
init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
}
}
@@ -158,8 +158,8 @@ func variter(vl []*ir.Name, t ir.Ntype, el []ir.Node) []ir.Node {
declare(v, dclcontext)
v.Ntype = t
- if e != nil || Curfn != nil || ir.IsBlank(v) {
- if Curfn != nil {
+ if e != nil || ir.CurFunc != nil || ir.IsBlank(v) {
+ if ir.CurFunc != nil {
init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
}
as := ir.NewAssignStmt(base.Pos, v, e)
@@ -176,29 +176,6 @@ func variter(vl []*ir.Name, t ir.Ntype, el []ir.Node) []ir.Node {
return init
}
-// newFuncNameAt generates a new name node for a function or method.
-func newFuncNameAt(pos src.XPos, s *types.Sym, fn *ir.Func) *ir.Name {
- if fn.Nname != nil {
- base.Fatalf("newFuncName - already have name")
- }
- n := ir.NewNameAt(pos, s)
- n.SetFunc(fn)
- fn.Nname = n
- return n
-}
-
-func anonfield(typ *types.Type) *ir.Field {
- return symfield(nil, typ)
-}
-
-func namedfield(s string, typ *types.Type) *ir.Field {
- return symfield(lookup(s), typ)
-}
-
-func symfield(s *types.Sym, typ *types.Type) *ir.Field {
- return ir.NewField(base.Pos, s, nil, typ)
-}
-
// oldname returns the Node that declares symbol s in the current scope.
// If no such Node currently exists, an ONONAME Node is returned instead.
// Automatically creates a new closure variable if the referenced symbol was
@@ -216,7 +193,7 @@ func oldname(s *types.Sym) ir.Node {
return ir.NewIdent(base.Pos, s)
}
- if Curfn != nil && n.Op() == ir.ONAME && n.Name().Curfn != nil && n.Name().Curfn != Curfn {
+ if ir.CurFunc != nil && n.Op() == ir.ONAME && n.Name().Curfn != nil && n.Name().Curfn != ir.CurFunc {
// Inner func is referring to var in outer func.
//
// TODO(rsc): If there is an outer variable x and we
@@ -225,7 +202,7 @@ func oldname(s *types.Sym) ir.Node {
// make x a closure variable unnecessarily.
n := n.(*ir.Name)
c := n.Name().Innermost
- if c == nil || c.Curfn != Curfn {
+ if c == nil || c.Curfn != ir.CurFunc {
// Do not have a closure var for the active closure yet; make one.
c = NewName(s)
c.Class_ = ir.PAUTOHEAP
@@ -238,7 +215,7 @@ func oldname(s *types.Sym) ir.Node {
c.Outer = n.Name().Innermost
n.Name().Innermost = c
- Curfn.ClosureVars = append(Curfn.ClosureVars, c)
+ ir.CurFunc.ClosureVars = append(ir.CurFunc.ClosureVars, c)
}
// return ref to closure var, not original
@@ -322,8 +299,8 @@ func colasdefn(left []ir.Node, defn ir.Node) {
// returns in auto-declaration context.
func funchdr(fn *ir.Func) {
// change the declaration context from extern to auto
- funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext})
- Curfn = fn
+ funcStack = append(funcStack, funcStackEnt{ir.CurFunc, dclcontext})
+ ir.CurFunc = fn
dclcontext = ir.PAUTO
types.Markdcl()
@@ -451,7 +428,7 @@ func funcbody() {
types.Popdcl()
var e funcStackEnt
funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1]
- Curfn, dclcontext = e.curfn, e.dclcontext
+ ir.CurFunc, dclcontext = e.curfn, e.dclcontext
}
// structs, functions, and methods.
@@ -542,7 +519,7 @@ func tointerface(nmethods []*ir.Field) *types.Type {
}
func fakeRecv() *ir.Field {
- return anonfield(types.FakeRecvType())
+ return ir.NewField(base.Pos, nil, nil, types.FakeRecvType())
}
func fakeRecvField() *types.Field {
@@ -588,74 +565,6 @@ func functype(nrecv *ir.Field, nparams, nresults []*ir.Field) *types.Type {
return t
}
-func hasNamedResults(fn *ir.Func) bool {
- typ := fn.Type()
- return typ.NumResults() > 0 && types.OrigSym(typ.Results().Field(0).Sym) != nil
-}
-
-// methodSym returns the method symbol representing a method name
-// associated with a specific receiver type.
-//
-// Method symbols can be used to distinguish the same method appearing
-// in different method sets. For example, T.M and (*T).M have distinct
-// method symbols.
-//
-// The returned symbol will be marked as a function.
-func methodSym(recv *types.Type, msym *types.Sym) *types.Sym {
- sym := methodSymSuffix(recv, msym, "")
- sym.SetFunc(true)
- return sym
-}
-
-// methodSymSuffix is like methodsym, but allows attaching a
-// distinguisher suffix. To avoid collisions, the suffix must not
-// start with a letter, number, or period.
-func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
- if msym.IsBlank() {
- base.Fatalf("blank method name")
- }
-
- rsym := recv.Sym()
- if recv.IsPtr() {
- if rsym != nil {
- base.Fatalf("declared pointer receiver type: %v", recv)
- }
- rsym = recv.Elem().Sym()
- }
-
- // Find the package the receiver type appeared in. For
- // anonymous receiver types (i.e., anonymous structs with
- // embedded fields), use the "go" pseudo-package instead.
- rpkg := ir.Pkgs.Go
- if rsym != nil {
- rpkg = rsym.Pkg
- }
-
- var b bytes.Buffer
- if recv.IsPtr() {
- // The parentheses aren't really necessary, but
- // they're pretty traditional at this point.
- fmt.Fprintf(&b, "(%-S)", recv)
- } else {
- fmt.Fprintf(&b, "%-S", recv)
- }
-
- // A particular receiver type may have multiple non-exported
- // methods with the same name. To disambiguate them, include a
- // package qualifier for names that came from a different
- // package than the receiver type.
- if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
- b.WriteString(".")
- b.WriteString(msym.Pkg.Prefix)
- }
-
- b.WriteString(".")
- b.WriteString(msym.Name)
- b.WriteString(suffix)
-
- return rpkg.LookupBytes(b.Bytes())
-}
-
// Add a method, declared as a function.
// - msym is the method symbol
// - t is function type (with receiver)
@@ -740,10 +649,6 @@ func addmethod(n *ir.Func, msym *types.Sym, t *types.Type, local, nointerface bo
return f
}
-func funcsymname(s *types.Sym) string {
- return s.Name + "·f"
-}
-
// funcsym returns s·f.
func funcsym(s *types.Sym) *types.Sym {
// funcsymsmu here serves to protect not just mutations of funcsyms (below),
@@ -756,7 +661,7 @@ func funcsym(s *types.Sym) *types.Sym {
// Note makefuncsym also does package look-up of func sym names,
// but that it is only called serially, from the front end.
funcsymsmu.Lock()
- sf, existed := s.Pkg.LookupOK(funcsymname(s))
+ sf, existed := s.Pkg.LookupOK(ir.FuncSymName(s))
// Don't export s·f when compiling for dynamic linking.
// When dynamically linking, the necessary function
// symbols will be created explicitly with makefuncsym.
@@ -790,31 +695,21 @@ func makefuncsym(s *types.Sym) {
// get funcsyms.
return
}
- if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed {
+ if _, existed := s.Pkg.LookupOK(ir.FuncSymName(s)); !existed {
funcsyms = append(funcsyms, s)
}
}
-// setNodeNameFunc marks a node as a function.
-func setNodeNameFunc(n *ir.Name) {
- if n.Op() != ir.ONAME || n.Class_ != ir.Pxxx {
- base.Fatalf("expected ONAME/Pxxx node, got %v", n)
- }
-
- n.Class_ = ir.PFUNC
- n.Sym().SetFunc(true)
-}
-
func dclfunc(sym *types.Sym, tfn ir.Ntype) *ir.Func {
if tfn.Op() != ir.OTFUNC {
base.Fatalf("expected OTFUNC node, got %v", tfn)
}
fn := ir.NewFunc(base.Pos)
- fn.Nname = newFuncNameAt(base.Pos, sym, fn)
+ fn.Nname = ir.NewFuncNameAt(base.Pos, sym, fn)
fn.Nname.Defn = fn
fn.Nname.Ntype = tfn
- setNodeNameFunc(fn.Nname)
+ ir.MarkFunc(fn.Nname)
funchdr(fn)
fn.Nname.Ntype = typecheckNtype(fn.Nname.Ntype)
return fn
diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go
index 4366a5cc2c..6843d8b00e 100644
--- a/src/cmd/compile/internal/gc/escape.go
+++ b/src/cmd/compile/internal/gc/escape.go
@@ -147,16 +147,16 @@ type EscEdge struct {
func escFmt(n ir.Node) string {
text := ""
switch n.Esc() {
- case EscUnknown:
+ case ir.EscUnknown:
break
- case EscHeap:
+ case ir.EscHeap:
text = "esc(h)"
- case EscNone:
+ case ir.EscNone:
text = "esc(no)"
- case EscNever:
+ case ir.EscNever:
text = "esc(N)"
default:
@@ -281,7 +281,7 @@ func (e *Escape) stmt(n ir.Node) {
return
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
defer func() {
base.Pos = lno
}()
@@ -483,7 +483,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) {
return
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
defer func() {
base.Pos = lno
}()
@@ -564,7 +564,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) {
case ir.OCONV, ir.OCONVNOP:
n := n.(*ir.ConvExpr)
- if checkPtr(e.curfn, 2) && n.Type().IsUnsafePtr() && n.X.Type().IsPtr() {
+ if ir.ShouldCheckPtr(e.curfn, 2) && n.Type().IsUnsafePtr() && n.X.Type().IsPtr() {
// When -d=checkptr=2 is enabled, treat
// conversions to unsafe.Pointer as an
// escaping operation. This allows better
@@ -618,7 +618,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) {
n := n.(*ir.CallPartExpr)
closureK := e.spill(k, n)
- m := callpartMethod(n)
+ m := n.Method
// We don't know how the method value will be called
// later, so conservatively assume the result
@@ -725,7 +725,7 @@ func (e *Escape) unsafeValue(k EscHole, n ir.Node) {
}
case ir.ODOTPTR:
n := n.(*ir.SelectorExpr)
- if isReflectHeaderDataField(n) {
+ if ir.IsReflectHeaderDataField(n) {
e.expr(k.deref(n, "reflect.Header.Data"), n.X)
} else {
e.discard(n.X)
@@ -825,7 +825,7 @@ func (e *Escape) assign(dst, src ir.Node, why string, where ir.Node) {
}
k := e.addr(dst)
- if dst != nil && dst.Op() == ir.ODOTPTR && isReflectHeaderDataField(dst) {
+ if dst != nil && dst.Op() == ir.ODOTPTR && ir.IsReflectHeaderDataField(dst) {
e.unsafeValue(e.heapHole().note(where, why), src)
} else {
if ignore {
@@ -847,7 +847,7 @@ func (e *Escape) call(ks []EscHole, call, where ir.Node) {
if topLevelDefer {
// force stack allocation of defer record, unless
// open-coded defers are used (see ssa.go)
- where.SetEsc(EscNever)
+ where.SetEsc(ir.EscNever)
}
argument := func(k EscHole, arg ir.Node) {
@@ -876,14 +876,14 @@ func (e *Escape) call(ks []EscHole, call, where ir.Node) {
var fn *ir.Name
switch call.Op() {
case ir.OCALLFUNC:
- switch v := staticValue(call.X); {
+ switch v := ir.StaticValue(call.X); {
case v.Op() == ir.ONAME && v.(*ir.Name).Class_ == ir.PFUNC:
fn = v.(*ir.Name)
case v.Op() == ir.OCLOSURE:
fn = v.(*ir.ClosureExpr).Func.Nname
}
case ir.OCALLMETH:
- fn = methodExprName(call.X)
+ fn = ir.MethodExprName(call.X)
}
fntype := call.X.Type()
@@ -1532,13 +1532,13 @@ func (e *Escape) finish(fns []*ir.Func) {
logopt.LogOpt(n.Pos(), "escape", "escape", ir.FuncName(e.curfn))
}
}
- n.SetEsc(EscHeap)
+ n.SetEsc(ir.EscHeap)
addrescapes(n)
} else {
if base.Flag.LowerM != 0 && n.Op() != ir.ONAME {
base.WarnfAt(n.Pos(), "%v does not escape", n)
}
- n.SetEsc(EscNone)
+ n.SetEsc(ir.EscNone)
if loc.transient {
switch n.Op() {
case ir.OCLOSURE:
@@ -1656,7 +1656,7 @@ func ParseLeaks(s string) EscLeaks {
}
func escapes(all []ir.Node) {
- visitBottomUp(all, escapeFuncs)
+ ir.VisitFuncsBottomUp(all, escapeFuncs)
}
const (
@@ -1680,13 +1680,6 @@ func max8(a, b int8) int8 {
return b
}
-const (
- EscUnknown = iota
- EscNone // Does not escape to heap, result, or parameters.
- EscHeap // Reachable from the heap
- EscNever // By construction will not escape.
-)
-
// funcSym returns fn.Nname.Sym if no nils are encountered along the way.
func funcSym(fn *ir.Func) *types.Sym {
if fn == nil || fn.Nname == nil {
@@ -1801,14 +1794,14 @@ func isSelfAssign(dst, src ir.Node) bool {
// Safe trailing accessors that are permitted to differ.
dst := dst.(*ir.SelectorExpr)
src := src.(*ir.SelectorExpr)
- return samesafeexpr(dst.X, src.X)
+ return ir.SameSafeExpr(dst.X, src.X)
case ir.OINDEX:
dst := dst.(*ir.IndexExpr)
src := src.(*ir.IndexExpr)
if mayAffectMemory(dst.Index) || mayAffectMemory(src.Index) {
return false
}
- return samesafeexpr(dst.X, src.X)
+ return ir.SameSafeExpr(dst.X, src.X)
default:
return false
}
@@ -1876,18 +1869,18 @@ func heapAllocReason(n ir.Node) string {
}
}
- if n.Type().Width > maxStackVarSize {
+ if n.Type().Width > ir.MaxStackVarSize {
return "too large for stack"
}
- if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= maxImplicitStackVarSize {
+ if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= ir.MaxImplicitStackVarSize {
return "too large for stack"
}
- if n.Op() == ir.OCLOSURE && closureType(n.(*ir.ClosureExpr)).Size() >= maxImplicitStackVarSize {
+ if n.Op() == ir.OCLOSURE && closureType(n.(*ir.ClosureExpr)).Size() >= ir.MaxImplicitStackVarSize {
return "too large for stack"
}
- if n.Op() == ir.OCALLPART && partialCallType(n.(*ir.CallPartExpr)).Size() >= maxImplicitStackVarSize {
+ if n.Op() == ir.OCALLPART && partialCallType(n.(*ir.CallPartExpr)).Size() >= ir.MaxImplicitStackVarSize {
return "too large for stack"
}
@@ -1897,10 +1890,10 @@ func heapAllocReason(n ir.Node) string {
if r == nil {
r = n.Len
}
- if !smallintconst(r) {
+ if !ir.IsSmallIntConst(r) {
return "non-constant size"
}
- if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) >= maxImplicitStackVarSize/t.Elem().Width {
+ if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) >= ir.MaxImplicitStackVarSize/t.Elem().Width {
return "too large for stack"
}
}
@@ -1922,13 +1915,13 @@ func addrescapes(n ir.Node) {
case ir.ONAME:
n := n.(*ir.Name)
- if n == nodfp {
+ if n == ir.RegFP {
break
}
// if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
// on PPARAM it means something different.
- if n.Class_ == ir.PAUTO && n.Esc() == EscNever {
+ if n.Class_ == ir.PAUTO && n.Esc() == ir.EscNever {
break
}
@@ -1954,12 +1947,12 @@ func addrescapes(n ir.Node) {
//
// then we're analyzing the inner closure but we need to move x to the
// heap in f, not in the inner closure. Flip over to f before calling moveToHeap.
- oldfn := Curfn
- Curfn = n.Curfn
+ oldfn := ir.CurFunc
+ ir.CurFunc = n.Curfn
ln := base.Pos
- base.Pos = Curfn.Pos()
+ base.Pos = ir.CurFunc.Pos()
moveToHeap(n)
- Curfn = oldfn
+ ir.CurFunc = oldfn
base.Pos = ln
// ODOTPTR has already been introduced,
@@ -2039,9 +2032,9 @@ func moveToHeap(n *ir.Name) {
// liveness and other analyses use the underlying stack slot
// and not the now-pseudo-variable n.
found := false
- for i, d := range Curfn.Dcl {
+ for i, d := range ir.CurFunc.Dcl {
if d == n {
- Curfn.Dcl[i] = stackcopy
+ ir.CurFunc.Dcl[i] = stackcopy
found = true
break
}
@@ -2054,14 +2047,14 @@ func moveToHeap(n *ir.Name) {
if !found {
base.Fatalf("cannot find %v in local variable list", n)
}
- Curfn.Dcl = append(Curfn.Dcl, n)
+ ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
}
// Modify n in place so that uses of n now mean indirection of the heapaddr.
n.Class_ = ir.PAUTOHEAP
n.SetFrameOffset(0)
n.Heapaddr = heapaddr
- n.SetEsc(EscHeap)
+ n.SetEsc(ir.EscHeap)
if base.Flag.LowerM != 0 {
base.WarnfAt(n.Pos(), "moved to heap: %v", n)
}
diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go
index bcd58fd2c5..53298c878d 100644
--- a/src/cmd/compile/internal/gc/gen.go
+++ b/src/cmd/compile/internal/gc/gen.go
@@ -28,26 +28,6 @@ func sysvar(name string) *obj.LSym {
return ir.Pkgs.Runtime.Lookup(name).Linksym()
}
-// isParamStackCopy reports whether this is the on-stack copy of a
-// function parameter that moved to the heap.
-func isParamStackCopy(n ir.Node) bool {
- if n.Op() != ir.ONAME {
- return false
- }
- name := n.(*ir.Name)
- return (name.Class_ == ir.PPARAM || name.Class_ == ir.PPARAMOUT) && name.Heapaddr != nil
-}
-
-// isParamHeapCopy reports whether this is the on-heap copy of
-// a function parameter that moved to the heap.
-func isParamHeapCopy(n ir.Node) bool {
- if n.Op() != ir.ONAME {
- return false
- }
- name := n.(*ir.Name)
- return name.Class_ == ir.PAUTOHEAP && name.Name().Stackcopy != nil
-}
-
// autotmpname returns the name for an autotmp variable numbered n.
func autotmpname(n int) string {
// Give each tmp a different name so that they can be registerized.
@@ -80,7 +60,7 @@ func tempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name {
s.Def = n
n.SetType(t)
n.Class_ = ir.PAUTO
- n.SetEsc(EscNever)
+ n.SetEsc(ir.EscNever)
n.Curfn = curfn
n.SetUsed(true)
n.SetAutoTemp(true)
@@ -92,5 +72,5 @@ func tempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name {
}
func temp(t *types.Type) *ir.Name {
- return tempAt(base.Pos, Curfn, t)
+ return tempAt(base.Pos, ir.CurFunc, t)
}
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 4b6ffe58d1..4370a06839 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -12,27 +12,6 @@ import (
"sync"
)
-var (
- // maximum size variable which we will allocate on the stack.
- // This limit is for explicit variable declarations like "var x T" or "x := ...".
- // Note: the flag smallframes can update this value.
- maxStackVarSize = int64(10 * 1024 * 1024)
-
- // maximum size of implicit variables that we will allocate on the stack.
- // p := new(T) allocating T on the stack
- // p := &T{} allocating T on the stack
- // s := make([]T, n) allocating [n]T on the stack
- // s := []byte("...") allocating [n]byte on the stack
- // Note: the flag smallframes can update this value.
- maxImplicitStackVarSize = int64(64 * 1024)
-
- // smallArrayBytes is the maximum size of an array which is considered small.
- // Small arrays will be initialized directly with a sequence of constant stores.
- // Large arrays will be initialized by copying from a static temp.
- // 256 bytes was chosen to minimize generated code + statictmp size.
- smallArrayBytes = int64(256)
-)
-
// Slices in the runtime are represented by three components:
//
// type slice struct {
@@ -89,16 +68,12 @@ var (
var dclcontext ir.Class // PEXTERN/PAUTO
-var Curfn *ir.Func
-
var Widthptr int
var Widthreg int
var typecheckok bool
-var nodfp *ir.Name
-
// interface to back end
type Arch struct {
diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go
index da2345c289..6ea9b354ab 100644
--- a/src/cmd/compile/internal/gc/gsubr.go
+++ b/src/cmd/compile/internal/gc/gsubr.go
@@ -197,7 +197,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) {
// Q: is this needed?
savepos := base.Pos
savedclcontext := dclcontext
- savedcurfn := Curfn
+ savedcurfn := ir.CurFunc
base.Pos = base.AutogeneratedPos
dclcontext = ir.PEXTERN
@@ -270,7 +270,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) {
tail = ir.NewBranchStmt(base.Pos, ir.ORETJMP, f.Nname.Sym())
} else {
call := ir.NewCallExpr(base.Pos, ir.OCALL, f.Nname, nil)
- call.Args.Set(paramNnames(tfn.Type()))
+ call.Args.Set(ir.ParamNames(tfn.Type()))
call.IsDDD = tfn.Type().IsVariadic()
tail = call
if tfn.Type().NumResults() > 0 {
@@ -287,7 +287,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) {
}
typecheckFunc(fn)
- Curfn = fn
+ ir.CurFunc = fn
typecheckslice(fn.Body, ctxStmt)
escapeFuncs([]*ir.Func{fn}, false)
@@ -297,7 +297,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) {
// Restore previous context.
base.Pos = savepos
dclcontext = savedclcontext
- Curfn = savedcurfn
+ ir.CurFunc = savedcurfn
}
// initLSym defines f's obj.LSym and initializes it based on the
diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go
index 56d2e81df1..fd64b69077 100644
--- a/src/cmd/compile/internal/gc/iexport.go
+++ b/src/cmd/compile/internal/gc/iexport.go
@@ -816,7 +816,7 @@ func (w *exportWriter) value(typ *types.Type, v constant.Value) {
func intSize(typ *types.Type) (signed bool, maxBytes uint) {
if typ.IsUntyped() {
- return true, Mpprec / 8
+ return true, ir.ConstPrec / 8
}
switch typ.Kind() {
@@ -927,7 +927,7 @@ func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
// multi-precision integer) and then the exponent, except exponent is
// omitted if mantissa is zero.
func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) {
- f := bigFloatVal(v)
+ f := ir.BigFloat(v)
if f.IsInf() {
base.Fatalf("infinite constant")
}
diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go
index 90a909d2a3..d04c432e5e 100644
--- a/src/cmd/compile/internal/gc/iimport.go
+++ b/src/cmd/compile/internal/gc/iimport.go
@@ -327,7 +327,7 @@ func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
fn := ir.NewFunc(mpos)
fn.SetType(mtyp)
- m := newFuncNameAt(mpos, methodSym(recv.Type, msym), fn)
+ m := ir.NewFuncNameAt(mpos, ir.MethodSym(recv.Type, msym), fn)
m.SetType(mtyp)
m.Class_ = ir.PFUNC
// methodSym already marked m.Sym as a function.
@@ -1009,7 +1009,7 @@ func (r *importReader) node() ir.Node {
n.AsOp = r.op()
n.X = r.expr()
if !r.bool() {
- n.Y = nodintconst(1)
+ n.Y = ir.NewInt(1)
n.IncDec = true
} else {
n.Y = r.expr()
diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go
index 4495284a07..f22e49efba 100644
--- a/src/cmd/compile/internal/gc/init.go
+++ b/src/cmd/compile/internal/gc/init.go
@@ -66,9 +66,9 @@ func fninit() *ir.Name {
funcbody()
typecheckFunc(fn)
- Curfn = fn
+ ir.CurFunc = fn
typecheckslice(nf, ctxStmt)
- Curfn = nil
+ ir.CurFunc = nil
Target.Decls = append(Target.Decls, fn)
fns = append(fns, initializers.Linksym())
}
diff --git a/src/cmd/compile/internal/gc/initorder.go b/src/cmd/compile/internal/gc/initorder.go
index fe131c32a6..5caa2e769f 100644
--- a/src/cmd/compile/internal/gc/initorder.go
+++ b/src/cmd/compile/internal/gc/initorder.go
@@ -290,7 +290,7 @@ func (d *initDeps) visit(n ir.Node) {
switch n.Op() {
case ir.OMETHEXPR:
n := n.(*ir.MethodExpr)
- d.foundDep(methodExprName(n))
+ d.foundDep(ir.MethodExprName(n))
case ir.ONAME:
n := n.(*ir.Name)
@@ -304,7 +304,7 @@ func (d *initDeps) visit(n ir.Node) {
d.inspectList(n.Func.Body)
case ir.ODOTMETH, ir.OCALLPART:
- d.foundDep(methodExprName(n))
+ d.foundDep(ir.MethodExprName(n))
}
}
diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go
index 47fdc7b9b7..f21494b291 100644
--- a/src/cmd/compile/internal/gc/inl.go
+++ b/src/cmd/compile/internal/gc/inl.go
@@ -39,9 +39,6 @@ import (
"strings"
)
-// IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
-var IsIntrinsicCall = func(*ir.CallExpr) bool { return false }
-
// Inlining budget parameters, gathered in one place
const (
inlineMaxBudget = 80
@@ -57,7 +54,7 @@ const (
func InlinePackage() {
// Find functions that can be inlined and clone them before walk expands them.
- visitBottomUp(Target.Decls, func(list []*ir.Func, recursive bool) {
+ ir.VisitFuncsBottomUp(Target.Decls, func(list []*ir.Func, recursive bool) {
numfns := numNonClosures(list)
for _, n := range list {
if !recursive || numfns > 1 {
@@ -98,7 +95,7 @@ func fnpkg(fn *ir.Name) *types.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 := setlineno(fn.Nname)
+ lno := ir.SetPos(fn.Nname)
expandInline(fn)
@@ -116,10 +113,10 @@ func typecheckinl(fn *ir.Func) {
fmt.Printf("typecheck import [%v] %L { %v }\n", fn.Sym(), fn, ir.Nodes(fn.Inl.Body))
}
- savefn := Curfn
- Curfn = fn
+ savefn := ir.CurFunc
+ ir.CurFunc = fn
typecheckslice(fn.Inl.Body, ctxStmt)
- Curfn = savefn
+ ir.CurFunc = savefn
// During expandInline (which imports fn.Func.Inl.Body),
// declarations are added to fn.Func.Dcl by funcHdr(). Move them
@@ -281,7 +278,7 @@ func inlFlood(n *ir.Name, exportsym func(*ir.Name)) {
ir.VisitList(ir.Nodes(fn.Inl.Body), func(n ir.Node) {
switch n.Op() {
case ir.OMETHEXPR, ir.ODOTMETH:
- inlFlood(methodExprName(n), exportsym)
+ inlFlood(ir.MethodExprName(n), exportsym)
case ir.ONAME:
n := n.(*ir.Name)
@@ -362,7 +359,7 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
}
}
- if IsIntrinsicCall(n) {
+ if ir.IsIntrinsicCall(n) {
// Treat like any other node.
break
}
@@ -393,7 +390,7 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
break
}
}
- if inlfn := methodExprName(n.X).Func; inlfn.Inl != nil {
+ if inlfn := ir.MethodExprName(n.X).Func; inlfn.Inl != nil {
v.budget -= inlfn.Inl.Cost
break
}
@@ -502,8 +499,8 @@ func isBigFunc(fn *ir.Func) bool {
// Inlcalls/nodelist/node walks fn's statements and expressions and substitutes any
// calls made to inlineable functions. This is the external entry point.
func inlcalls(fn *ir.Func) {
- savefn := Curfn
- Curfn = fn
+ savefn := ir.CurFunc
+ ir.CurFunc = fn
maxCost := int32(inlineMaxBudget)
if isBigFunc(fn) {
maxCost = inlineBigFunctionMaxCost
@@ -520,7 +517,7 @@ func inlcalls(fn *ir.Func) {
return inlnode(n, maxCost, inlMap, edit)
}
ir.EditChildren(fn, edit)
- Curfn = savefn
+ ir.CurFunc = savefn
}
// Turn an OINLCALL into a statement.
@@ -536,7 +533,7 @@ func inlconv2stmt(inlcall *ir.InlinedCallExpr) ir.Node {
// n.Left = inlconv2expr(n.Left)
func inlconv2expr(n *ir.InlinedCallExpr) ir.Node {
r := n.ReturnVars[0]
- return initExpr(append(n.Init(), n.Body...), r)
+ return ir.InitExpr(append(n.Init(), n.Body...), r)
}
// Turn the rlist (with the return values) of the OINLCALL in
@@ -550,7 +547,7 @@ func inlconv2list(n *ir.InlinedCallExpr) []ir.Node {
}
s := n.ReturnVars
- s[0] = initExpr(append(n.Init(), n.Body...), s[0])
+ s[0] = ir.InitExpr(append(n.Init(), n.Body...), s[0])
return s
}
@@ -594,7 +591,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
}
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
ir.EditChildren(n, edit)
@@ -626,7 +623,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
if base.Flag.LowerM > 3 {
fmt.Printf("%v:call to func %+v\n", ir.Line(n), call.X)
}
- if IsIntrinsicCall(call) {
+ if ir.IsIntrinsicCall(call) {
break
}
if fn := inlCallee(call.X); fn != nil && fn.Inl != nil {
@@ -644,7 +641,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
base.Fatalf("no function type for [%p] %+v\n", call.X, call.X)
}
- n = mkinlcall(call, methodExprName(call.X).Func, maxCost, inlMap, edit)
+ n = mkinlcall(call, ir.MethodExprName(call.X).Func, maxCost, inlMap, edit)
}
base.Pos = lno
@@ -670,11 +667,11 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
// inlCallee takes a function-typed expression and returns the underlying function ONAME
// that it refers to if statically known. Otherwise, it returns nil.
func inlCallee(fn ir.Node) *ir.Func {
- fn = staticValue(fn)
+ fn = ir.StaticValue(fn)
switch fn.Op() {
case ir.OMETHEXPR:
fn := fn.(*ir.MethodExpr)
- n := methodExprName(fn)
+ n := ir.MethodExprName(fn)
// Check that receiver type matches fn.Left.
// TODO(mdempsky): Handle implicit dereference
// of pointer receiver argument?
@@ -696,100 +693,6 @@ func inlCallee(fn ir.Node) *ir.Func {
return nil
}
-func staticValue(n ir.Node) ir.Node {
- for {
- if n.Op() == ir.OCONVNOP {
- n = n.(*ir.ConvExpr).X
- continue
- }
-
- n1 := staticValue1(n)
- if n1 == nil {
- return n
- }
- n = n1
- }
-}
-
-// staticValue1 implements a simple SSA-like optimization. If n is a local variable
-// that is initialized and never reassigned, staticValue1 returns the initializer
-// expression. Otherwise, it returns nil.
-func staticValue1(nn ir.Node) ir.Node {
- if nn.Op() != ir.ONAME {
- return nil
- }
- n := nn.(*ir.Name)
- if n.Class_ != ir.PAUTO || n.Name().Addrtaken() {
- return nil
- }
-
- defn := n.Name().Defn
- if defn == nil {
- return nil
- }
-
- var rhs ir.Node
-FindRHS:
- switch defn.Op() {
- case ir.OAS:
- defn := defn.(*ir.AssignStmt)
- rhs = defn.Y
- case ir.OAS2:
- defn := defn.(*ir.AssignListStmt)
- for i, lhs := range defn.Lhs {
- if lhs == n {
- rhs = defn.Rhs[i]
- break FindRHS
- }
- }
- base.Fatalf("%v missing from LHS of %v", n, defn)
- default:
- return nil
- }
- if rhs == nil {
- base.Fatalf("RHS is nil: %v", defn)
- }
-
- if reassigned(n) {
- return nil
- }
-
- return rhs
-}
-
-// reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean
-// indicating whether the name has any assignments other than its declaration.
-// The second return value is the first such assignment encountered in the walk, if any. It is mostly
-// useful for -m output documenting the reason for inhibited optimizations.
-// NB: global variables are always considered to be re-assigned.
-// TODO: handle initial declaration not including an assignment and followed by a single assignment?
-func reassigned(name *ir.Name) bool {
- if name.Op() != ir.ONAME {
- base.Fatalf("reassigned %v", name)
- }
- // no way to reliably check for no-reassignment of globals, assume it can be
- if name.Curfn == nil {
- return true
- }
- return ir.Any(name.Curfn, func(n ir.Node) bool {
- switch n.Op() {
- case ir.OAS:
- n := n.(*ir.AssignStmt)
- if n.X == name && n != name.Defn {
- return true
- }
- case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OSELRECV2:
- n := n.(*ir.AssignListStmt)
- for _, p := range n.Lhs {
- if p == name && n != name.Defn {
- return true
- }
- }
- }
- return false
- })
-}
-
func inlParam(t *types.Field, as ir.Node, inlvars map[*ir.Name]ir.Node) ir.Node {
n := ir.AsNode(t.Nname)
if n == nil || ir.IsBlank(n) {
@@ -821,7 +724,7 @@ var SSADumpInline = func(*ir.Func) {}
func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.Node) ir.Node) ir.Node {
if fn.Inl == nil {
if logopt.Enabled() {
- logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(Curfn),
+ logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
fmt.Sprintf("%s cannot be inlined", ir.PkgFuncName(fn)))
}
return n
@@ -830,16 +733,16 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
// The inlined function body is too big. Typically we use this check to restrict
// inlining into very big functions. See issue 26546 and 17566.
if logopt.Enabled() {
- logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(Curfn),
+ logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Inl.Cost, ir.PkgFuncName(fn), maxCost))
}
return n
}
- if fn == Curfn {
+ if fn == ir.CurFunc {
// 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(Curfn)))
+ logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(ir.CurFunc)))
}
return n
}
@@ -856,7 +759,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
if inlMap[fn] {
if base.Flag.LowerM > 1 {
- fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(Curfn))
+ fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(ir.CurFunc))
}
return n
}
@@ -916,7 +819,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
// NB: if we enabled inlining of functions containing OCLOSURE or refined
// the reassigned check via some sort of copy propagation this would most
// likely need to be changed to a loop to walk up to the correct Param
- if o == nil || o.Curfn != Curfn {
+ if o == nil || o.Curfn != ir.CurFunc {
base.Fatalf("%v: unresolvable capture %v %v\n", ir.Line(n), fn, v)
}
@@ -947,7 +850,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
if ln.Class_ == ir.PPARAMOUT { // return values handled below.
continue
}
- if isParamStackCopy(ln) { // ignore the on-stack copy of a parameter that moved to the heap
+ if ir.IsParamStackCopy(ln) { // ignore the on-stack copy of a parameter that moved to the heap
// TODO(mdempsky): Remove once I'm confident
// this never actually happens. We currently
// perform inlining before escape analysis, so
@@ -1162,10 +1065,10 @@ func inlvar(var_ ir.Node) ir.Node {
n.SetType(var_.Type())
n.Class_ = ir.PAUTO
n.SetUsed(true)
- n.Curfn = Curfn // the calling function, not the called one
+ n.Curfn = ir.CurFunc // the calling function, not the called one
n.SetAddrtaken(var_.Name().Addrtaken())
- Curfn.Dcl = append(Curfn.Dcl, n)
+ ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
return n
}
@@ -1175,8 +1078,8 @@ func retvar(t *types.Field, i int) ir.Node {
n.SetType(t.Type)
n.Class_ = ir.PAUTO
n.SetUsed(true)
- n.Curfn = Curfn // the calling function, not the called one
- Curfn.Dcl = append(Curfn.Dcl, n)
+ n.Curfn = ir.CurFunc // the calling function, not the called one
+ ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
return n
}
@@ -1187,8 +1090,8 @@ func argvar(t *types.Type, i int) ir.Node {
n.SetType(t.Elem())
n.Class_ = ir.PAUTO
n.SetUsed(true)
- n.Curfn = Curfn // the calling function, not the called one
- Curfn.Dcl = append(Curfn.Dcl, n)
+ n.Curfn = ir.CurFunc // the calling function, not the called one
+ ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
return n
}
@@ -1358,7 +1261,7 @@ func pruneUnusedAutos(ll []*ir.Name, vis *hairyVisitor) []*ir.Name {
// devirtualize replaces interface method calls within fn with direct
// concrete-type method calls where applicable.
func devirtualize(fn *ir.Func) {
- Curfn = fn
+ ir.CurFunc = fn
ir.VisitList(fn.Body, func(n ir.Node) {
if n.Op() == ir.OCALLINTER {
devirtualizeCall(n.(*ir.CallExpr))
@@ -1368,7 +1271,7 @@ func devirtualize(fn *ir.Func) {
func devirtualizeCall(call *ir.CallExpr) {
sel := call.X.(*ir.SelectorExpr)
- r := staticValue(sel.X)
+ r := ir.StaticValue(sel.X)
if r.Op() != ir.OCONVIFACE {
return
}
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index 1c52426802..d55a8b0a7c 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -134,8 +134,8 @@ func Main(archInit func(*Arch)) {
}
if base.Flag.SmallFrames {
- maxStackVarSize = 128 * 1024
- maxImplicitStackVarSize = 16 * 1024
+ ir.MaxStackVarSize = 128 * 1024
+ ir.MaxImplicitStackVarSize = 16 * 1024
}
if base.Flag.Dwarf {
@@ -185,7 +185,7 @@ func Main(archInit func(*Arch)) {
}
ir.EscFmt = escFmt
- IsIntrinsicCall = isIntrinsicCall
+ ir.IsIntrinsicCall = isIntrinsicCall
SSADumpInline = ssaDumpInline
initSSAEnv()
initSSATables()
@@ -242,7 +242,7 @@ func Main(archInit func(*Arch)) {
devirtualize(n.(*ir.Func))
}
}
- Curfn = nil
+ ir.CurFunc = nil
// Escape analysis.
// Required for moving heap allocations onto stack,
@@ -271,7 +271,7 @@ func Main(archInit func(*Arch)) {
if n.Op() == ir.ODCLFUNC {
n := n.(*ir.Func)
if n.OClosure != nil {
- Curfn = n
+ ir.CurFunc = n
transformclosure(n)
}
}
@@ -285,7 +285,7 @@ func Main(archInit func(*Arch)) {
// Just before compilation, compile itabs found on
// the right side of OCONVIFACE so that methods
// can be de-virtualized during compilation.
- Curfn = nil
+ ir.CurFunc = nil
peekitabs()
// Compile top level functions.
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
index 799887d6b8..c83b60dcd4 100644
--- a/src/cmd/compile/internal/gc/noder.go
+++ b/src/cmd/compile/internal/gc/noder.go
@@ -181,9 +181,9 @@ func (p *noder) openScope(pos syntax.Pos) {
types.Markdcl()
if p.trackScopes {
- Curfn.Parents = append(Curfn.Parents, p.scope)
- p.scopeVars = append(p.scopeVars, len(Curfn.Dcl))
- p.scope = ir.ScopeID(len(Curfn.Parents))
+ ir.CurFunc.Parents = append(ir.CurFunc.Parents, p.scope)
+ p.scopeVars = append(p.scopeVars, len(ir.CurFunc.Dcl))
+ p.scope = ir.ScopeID(len(ir.CurFunc.Parents))
p.markScope(pos)
}
@@ -196,29 +196,29 @@ func (p *noder) closeScope(pos syntax.Pos) {
if p.trackScopes {
scopeVars := p.scopeVars[len(p.scopeVars)-1]
p.scopeVars = p.scopeVars[:len(p.scopeVars)-1]
- if scopeVars == len(Curfn.Dcl) {
+ if scopeVars == len(ir.CurFunc.Dcl) {
// no variables were declared in this scope, so we can retract it.
- if int(p.scope) != len(Curfn.Parents) {
+ if int(p.scope) != len(ir.CurFunc.Parents) {
base.Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted")
}
- p.scope = Curfn.Parents[p.scope-1]
- Curfn.Parents = Curfn.Parents[:len(Curfn.Parents)-1]
+ p.scope = ir.CurFunc.Parents[p.scope-1]
+ ir.CurFunc.Parents = ir.CurFunc.Parents[:len(ir.CurFunc.Parents)-1]
- nmarks := len(Curfn.Marks)
- Curfn.Marks[nmarks-1].Scope = p.scope
+ nmarks := len(ir.CurFunc.Marks)
+ ir.CurFunc.Marks[nmarks-1].Scope = p.scope
prevScope := ir.ScopeID(0)
if nmarks >= 2 {
- prevScope = Curfn.Marks[nmarks-2].Scope
+ prevScope = ir.CurFunc.Marks[nmarks-2].Scope
}
- if Curfn.Marks[nmarks-1].Scope == prevScope {
- Curfn.Marks = Curfn.Marks[:nmarks-1]
+ if ir.CurFunc.Marks[nmarks-1].Scope == prevScope {
+ ir.CurFunc.Marks = ir.CurFunc.Marks[:nmarks-1]
}
return
}
- p.scope = Curfn.Parents[p.scope-1]
+ p.scope = ir.CurFunc.Parents[p.scope-1]
p.markScope(pos)
}
@@ -226,10 +226,10 @@ func (p *noder) closeScope(pos syntax.Pos) {
func (p *noder) markScope(pos syntax.Pos) {
xpos := p.makeXPos(pos)
- if i := len(Curfn.Marks); i > 0 && Curfn.Marks[i-1].Pos == xpos {
- Curfn.Marks[i-1].Scope = p.scope
+ if i := len(ir.CurFunc.Marks); i > 0 && ir.CurFunc.Marks[i-1].Pos == xpos {
+ ir.CurFunc.Marks[i-1].Scope = p.scope
} else {
- Curfn.Marks = append(Curfn.Marks, ir.Mark{Pos: xpos, Scope: p.scope})
+ ir.CurFunc.Marks = append(ir.CurFunc.Marks, ir.Mark{Pos: xpos, Scope: p.scope})
}
}
@@ -527,7 +527,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
name = ir.BlankNode.Sym() // filled in by typecheckfunc
}
- f.Nname = newFuncNameAt(p.pos(fun.Name), name, f)
+ f.Nname = ir.NewFuncNameAt(p.pos(fun.Name), name, f)
f.Nname.Defn = f
f.Nname.Ntype = t
@@ -996,13 +996,13 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
// TODO(mdempsky): Line number?
return ir.NewBlockStmt(base.Pos, nil)
}
- return liststmt(l)
+ return ir.NewBlockStmt(src.NoXPos, l)
case *syntax.ExprStmt:
return p.wrapname(stmt, p.expr(stmt.X))
case *syntax.SendStmt:
return ir.NewSendStmt(p.pos(stmt), p.expr(stmt.Chan), p.expr(stmt.Value))
case *syntax.DeclStmt:
- return liststmt(p.decls(stmt.DeclList))
+ return ir.NewBlockStmt(src.NoXPos, p.decls(stmt.DeclList))
case *syntax.AssignStmt:
if stmt.Op != 0 && stmt.Op != syntax.Def {
n := ir.NewAssignOpStmt(p.pos(stmt), p.binOp(stmt.Op), p.expr(stmt.Lhs), p.expr(stmt.Rhs))
@@ -1065,8 +1065,8 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
}
n := ir.NewReturnStmt(p.pos(stmt), nil)
n.Results.Set(results)
- if len(n.Results) == 0 && Curfn != nil {
- for _, ln := range Curfn.Dcl {
+ if len(n.Results) == 0 && ir.CurFunc != nil {
+ for _, ln := range ir.CurFunc.Dcl {
if ln.Class_ == ir.PPARAM {
continue
}
@@ -1344,7 +1344,7 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) ir.Node {
l = append(l, ls)
}
}
- return liststmt(l)
+ return ir.NewBlockStmt(src.NoXPos, l)
}
var unOps = [...]ir.Op{
@@ -1451,7 +1451,7 @@ func (p *noder) basicLit(lit *syntax.BasicLit) constant.Value {
// to big.Float to match cmd/compile's historical precision.
// TODO(mdempsky): Remove.
if v.Kind() == constant.Float {
- v = constant.Make(bigFloatVal(v))
+ v = constant.Make(ir.BigFloat(v))
}
return v
diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go
index 897bcce36f..e56e34a7a1 100644
--- a/src/cmd/compile/internal/gc/obj.go
+++ b/src/cmd/compile/internal/gc/obj.go
@@ -255,7 +255,7 @@ func dumpGlobalConst(n ir.Node) {
if t.IsUntyped() {
// Export untyped integers as int (if they fit).
t = types.Types[types.TINT]
- if doesoverflow(v, t) {
+ if ir.ConstOverflow(v, t) {
return
}
}
@@ -279,7 +279,7 @@ func dumpfuncsyms() {
return funcsyms[i].LinksymName() < funcsyms[j].LinksymName()
})
for _, s := range funcsyms {
- sf := s.Pkg.Lookup(funcsymname(s)).Linksym()
+ sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym()
dsymptr(sf, 0, s.Linksym(), 0)
ggloblsym(sf, int32(Widthptr), obj.DUPOK|obj.RODATA)
}
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index 9e792d153c..1cd33b2cb5 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -230,7 +230,7 @@ func (o *Order) safeExpr(n ir.Node) ir.Node {
// because we emit explicit VARKILL instructions marking the end of those
// temporaries' lifetimes.
func isaddrokay(n ir.Node) bool {
- return islvalue(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class_ == ir.PEXTERN || ir.IsAutoTmp(n))
+ return ir.IsAssignable(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class_ == ir.PEXTERN || ir.IsAutoTmp(n))
}
// addrTemp ensures that n is okay to pass by address to runtime routines.
@@ -381,13 +381,13 @@ func orderMakeSliceCopy(s []ir.Node) {
}
mk := as.Y.(*ir.MakeExpr)
- if mk.Esc() == EscNone || mk.Len == nil || mk.Cap != nil {
+ if mk.Esc() == ir.EscNone || mk.Len == nil || mk.Cap != nil {
return
}
mk.SetOp(ir.OMAKESLICECOPY)
mk.Cap = cp.Y
// Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
- mk.SetBounded(mk.Len.Op() == ir.OLEN && samesafeexpr(mk.Len.(*ir.UnaryExpr).X, cp.Y))
+ mk.SetBounded(mk.Len.Op() == ir.OLEN && ir.SameSafeExpr(mk.Len.(*ir.UnaryExpr).X, cp.Y))
as.Y = typecheck(mk, ctxExpr)
s[1] = nil // remove separate copy call
}
@@ -404,7 +404,7 @@ func (o *Order) edge() {
counter.Name().SetLibfuzzerExtraCounter(true)
// counter += 1
- incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, nodintconst(1))
+ incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))
o.append(incr)
}
@@ -429,7 +429,7 @@ func (o *Order) exprInPlace(n ir.Node) ir.Node {
var order Order
order.free = o.free
n = order.expr(n, nil)
- n = initExpr(order.out, n)
+ n = ir.InitExpr(order.out, n)
// insert new temporaries from order
// at head of outer list.
@@ -448,7 +448,7 @@ func orderStmtInPlace(n ir.Node, free map[string][]*ir.Name) ir.Node {
mark := order.markTemp()
order.stmt(n)
order.cleanTemp(mark)
- return liststmt(order.out)
+ return ir.NewBlockStmt(src.NoXPos, order.out)
}
// init moves n's init list to o.out.
@@ -615,7 +615,7 @@ func (o *Order) stmt(n ir.Node) {
return
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
o.init(n)
switch n.Op() {
@@ -909,7 +909,7 @@ func (o *Order) stmt(n ir.Node) {
for _, ncas := range n.Cases {
ncas := ncas.(*ir.CaseStmt)
r := ncas.Comm
- setlineno(ncas)
+ ir.SetPos(ncas)
// Append any new body prologue to ninit.
// The next loop will insert ninit into nbody.
@@ -1089,7 +1089,7 @@ func (o *Order) expr(n, lhs ir.Node) ir.Node {
if n == nil {
return n
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
n = o.expr1(n, lhs)
base.Pos = lno
return n
@@ -1283,7 +1283,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
o.exprList(n.Args)
}
- if lhs == nil || lhs.Op() != ir.ONAME && !samesafeexpr(lhs, n.Args[0]) {
+ if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) {
return o.copyExpr(n)
}
return n
@@ -1299,7 +1299,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
max = o.expr(max, nil)
max = o.cheapExpr(max)
n.SetSliceBounds(low, high, max)
- if lhs == nil || lhs.Op() != ir.ONAME && !samesafeexpr(lhs, n.X) {
+ if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) {
return o.copyExpr(n)
}
return n
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index d6c15f113b..44b614ba70 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -131,7 +131,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
switch n.Class_ {
case ir.PPARAM, ir.PPARAMOUT:
// Don't modify nodfp; it is a global.
- if n != nodfp {
+ if n != ir.RegFP {
n.Name().SetUsed(true)
}
case ir.PAUTO:
@@ -193,8 +193,8 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
}
func funccompile(fn *ir.Func) {
- if Curfn != nil {
- base.Fatalf("funccompile %v inside %v", fn.Sym(), Curfn.Sym())
+ if ir.CurFunc != nil {
+ base.Fatalf("funccompile %v inside %v", fn.Sym(), ir.CurFunc.Sym())
}
if fn.Type() == nil {
@@ -215,9 +215,9 @@ func funccompile(fn *ir.Func) {
}
dclcontext = ir.PAUTO
- Curfn = fn
+ ir.CurFunc = fn
compile(fn)
- Curfn = nil
+ ir.CurFunc = nil
dclcontext = ir.PEXTERN
}
@@ -234,7 +234,7 @@ func compile(fn *ir.Func) {
}
// From this point, there should be no uses of Curfn. Enforce that.
- Curfn = nil
+ ir.CurFunc = nil
if ir.FuncName(fn) == "_" {
// We don't need to generate code for this function, just report errors in its body.
diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go
index 67802fe917..e73e7fbbe1 100644
--- a/src/cmd/compile/internal/gc/racewalk.go
+++ b/src/cmd/compile/internal/gc/racewalk.go
@@ -35,7 +35,7 @@ func instrument(fn *ir.Func) {
// This only works for amd64. This will not
// work on arm or others that might support
// race in the future.
- nodpc := nodfp.CloneName()
+ nodpc := ir.RegFP.CloneName()
nodpc.SetType(types.Types[types.TUINTPTR])
nodpc.SetFrameOffset(int64(-Widthptr))
fn.Dcl = append(fn.Dcl, nodpc)
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
index 463d0c55bd..a9447189c2 100644
--- a/src/cmd/compile/internal/gc/range.go
+++ b/src/cmd/compile/internal/gc/range.go
@@ -160,7 +160,7 @@ func cheapComputableIndex(width int64) bool {
func walkrange(nrange *ir.RangeStmt) ir.Node {
if isMapClear(nrange) {
m := nrange.X
- lno := setlineno(m)
+ lno := ir.SetPos(m)
n := mapClear(m)
base.Pos = lno
return n
@@ -180,7 +180,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node {
t := nrange.Type()
a := nrange.X
- lno := setlineno(a)
+ lno := ir.SetPos(a)
var v1, v2 ir.Node
l := len(nrange.Vars)
@@ -228,7 +228,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node {
init = append(init, ir.NewAssignStmt(base.Pos, hn, ir.NewUnaryExpr(base.Pos, ir.OLEN, ha)))
nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv1, hn)
- nfor.Post = ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, nodintconst(1)))
+ nfor.Post = ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, ir.NewInt(1)))
// for range ha { body }
if v1 == nil {
@@ -272,7 +272,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node {
nfor.SetOp(ir.OFORUNTIL)
hp := temp(types.NewPtr(nrange.Type().Elem()))
- tmp := ir.NewIndexExpr(base.Pos, ha, nodintconst(0))
+ tmp := ir.NewIndexExpr(base.Pos, ha, ir.NewInt(0))
tmp.SetBounded(true)
init = append(init, ir.NewAssignStmt(base.Pos, hp, nodAddr(tmp)))
@@ -335,7 +335,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node {
}
hb := temp(types.Types[types.TBOOL])
- nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, hb, nodbool(false))
+ nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, hb, ir.NewBool(false))
a := ir.NewAssignListStmt(base.Pos, ir.OAS2RECV, nil, nil)
a.SetTypecheck(1)
a.Lhs = []ir.Node{hv1, hb}
@@ -392,10 +392,10 @@ func walkrange(nrange *ir.RangeStmt) ir.Node {
// if hv2 < utf8.RuneSelf
nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
- nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv2, nodintconst(utf8.RuneSelf))
+ nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv2, ir.NewInt(utf8.RuneSelf))
// hv1++
- nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, nodintconst(1)))}
+ nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, ir.NewInt(1)))}
// } else {
eif := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
@@ -488,7 +488,7 @@ func isMapClear(n *ir.RangeStmt) bool {
}
m := n.X
- if delete := stmt.(*ir.CallExpr); !samesafeexpr(delete.Args[0], m) || !samesafeexpr(delete.Args[1], k) {
+ if delete := stmt.(*ir.CallExpr); !ir.SameSafeExpr(delete.Args[0], m) || !ir.SameSafeExpr(delete.Args[1], k) {
return false
}
@@ -545,12 +545,12 @@ func arrayClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node {
}
lhs := stmt.X.(*ir.IndexExpr)
- if !samesafeexpr(lhs.X, a) || !samesafeexpr(lhs.Index, v1) {
+ if !ir.SameSafeExpr(lhs.X, a) || !ir.SameSafeExpr(lhs.Index, v1) {
return nil
}
elemsize := loop.Type().Elem().Width
- if elemsize <= 0 || !isZero(stmt.Y) {
+ if elemsize <= 0 || !ir.IsZero(stmt.Y) {
return nil
}
@@ -563,25 +563,25 @@ func arrayClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node {
// }
n := ir.NewIfStmt(base.Pos, nil, nil, nil)
n.Body.Set(nil)
- n.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), nodintconst(0))
+ n.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(0))
// hp = &a[0]
hp := temp(types.Types[types.TUNSAFEPTR])
- ix := ir.NewIndexExpr(base.Pos, a, nodintconst(0))
+ ix := ir.NewIndexExpr(base.Pos, a, ir.NewInt(0))
ix.SetBounded(true)
addr := convnop(nodAddr(ix), types.Types[types.TUNSAFEPTR])
n.Body.Append(ir.NewAssignStmt(base.Pos, hp, addr))
// hn = len(a) * sizeof(elem(a))
hn := temp(types.Types[types.TUINTPTR])
- mul := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), nodintconst(elemsize)), types.Types[types.TUINTPTR])
+ mul := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(elemsize)), types.Types[types.TUINTPTR])
n.Body.Append(ir.NewAssignStmt(base.Pos, hn, mul))
var fn ir.Node
if a.Type().Elem().HasPointers() {
// memclrHasPointers(hp, hn)
- Curfn.SetWBPos(stmt.Pos())
+ ir.CurFunc.SetWBPos(stmt.Pos())
fn = mkcall("memclrHasPointers", nil, nil, hp, hn)
} else {
// memclrNoHeapPointers(hp, hn)
@@ -591,7 +591,7 @@ func arrayClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node {
n.Body.Append(fn)
// i = len(a) - 1
- v1 = ir.NewAssignStmt(base.Pos, v1, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), nodintconst(1)))
+ v1 = ir.NewAssignStmt(base.Pos, v1, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(1)))
n.Body.Append(v1)
@@ -608,7 +608,7 @@ func addptr(p ir.Node, n int64) ir.Node {
p = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, p)
p.SetType(types.Types[types.TUINTPTR])
- p = ir.NewBinaryExpr(base.Pos, ir.OADD, p, nodintconst(n))
+ p = ir.NewBinaryExpr(base.Pos, ir.OADD, p, ir.NewInt(n))
p = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, p)
p.SetType(t)
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
index 41c9f93bf0..8b393a8979 100644
--- a/src/cmd/compile/internal/gc/reflect.go
+++ b/src/cmd/compile/internal/gc/reflect.go
@@ -349,12 +349,12 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
in := make([]*ir.Field, 0, inLen)
if receiver != nil {
- d := anonfield(receiver)
+ d := ir.NewField(base.Pos, nil, nil, receiver)
in = append(in, d)
}
for _, t := range f.Params().Fields().Slice() {
- d := anonfield(t.Type)
+ d := ir.NewField(base.Pos, nil, nil, t.Type)
d.IsDDD = t.IsDDD()
in = append(in, d)
}
@@ -362,7 +362,7 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
outLen := f.Results().Fields().Len()
out := make([]*ir.Field, 0, outLen)
for _, t := range f.Results().Fields().Slice() {
- d := anonfield(t.Type)
+ d := ir.NewField(base.Pos, nil, nil, t.Type)
out = append(out, d)
}
@@ -416,8 +416,8 @@ func methods(t *types.Type) []*Sig {
sig := &Sig{
name: method,
- isym: methodSym(it, method),
- tsym: methodSym(t, method),
+ isym: ir.MethodSym(it, method),
+ tsym: ir.MethodSym(t, method),
type_: methodfunc(f.Type, t),
mtype: methodfunc(f.Type, nil),
}
@@ -471,7 +471,7 @@ func imethods(t *types.Type) []*Sig {
// IfaceType.Method is not in the reflect data.
// Generate the method body, so that compiled
// code can refer to it.
- isym := methodSym(t, f.Sym)
+ isym := ir.MethodSym(t, f.Sym)
if !isym.Siggen() {
isym.SetSiggen(true)
genwrapper(t, f, isym)
@@ -1541,7 +1541,7 @@ func dumpbasictypes() {
// The latter is the type of an auto-generated wrapper.
dtypesym(types.NewPtr(types.ErrorType))
- dtypesym(functype(nil, []*ir.Field{anonfield(types.ErrorType)}, []*ir.Field{anonfield(types.Types[types.TSTRING])}))
+ dtypesym(functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, types.ErrorType)}, []*ir.Field{ir.NewField(base.Pos, nil, nil, types.Types[types.TSTRING])}))
// add paths for runtime and main, which 6l imports implicitly.
dimportpath(ir.Pkgs.Runtime)
diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go
index 0bf070aa87..67a2cfd312 100644
--- a/src/cmd/compile/internal/gc/select.go
+++ b/src/cmd/compile/internal/gc/select.go
@@ -13,7 +13,7 @@ import (
// select
func typecheckselect(sel *ir.SelectStmt) {
var def ir.Node
- lno := setlineno(sel)
+ lno := ir.SetPos(sel)
typecheckslice(sel.Init(), ctxStmt)
for _, ncase := range sel.Cases {
ncase := ncase.(*ir.CaseStmt)
@@ -94,7 +94,7 @@ func typecheckselect(sel *ir.SelectStmt) {
}
func walkselect(sel *ir.SelectStmt) {
- lno := setlineno(sel)
+ lno := ir.SetPos(sel)
if len(sel.Compiled) != 0 {
base.Fatalf("double walkselect")
}
@@ -123,7 +123,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
// optimization: one-case select: single op.
if ncas == 1 {
cas := cases[0].(*ir.CaseStmt)
- setlineno(cas)
+ ir.SetPos(cas)
l := cas.Init()
if cas.Comm != nil { // not default:
n := cas.Comm
@@ -158,7 +158,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
var dflt *ir.CaseStmt
for _, cas := range cases {
cas := cas.(*ir.CaseStmt)
- setlineno(cas)
+ ir.SetPos(cas)
n := cas.Comm
if n == nil {
dflt = cas
@@ -187,7 +187,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
}
n := cas.Comm
- setlineno(n)
+ ir.SetPos(n)
r := ir.NewIfStmt(base.Pos, nil, nil, nil)
r.PtrInit().Set(cas.Init())
var call ir.Node
@@ -245,7 +245,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
var pc0, pcs ir.Node
if base.Flag.Race {
pcs = temp(types.NewArray(types.Types[types.TUINTPTR], int64(ncas)))
- pc0 = typecheck(nodAddr(ir.NewIndexExpr(base.Pos, pcs, nodintconst(0))), ctxExpr)
+ pc0 = typecheck(nodAddr(ir.NewIndexExpr(base.Pos, pcs, ir.NewInt(0))), ctxExpr)
} else {
pc0 = nodnil()
}
@@ -253,7 +253,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
// register cases
for _, cas := range cases {
cas := cas.(*ir.CaseStmt)
- setlineno(cas)
+ ir.SetPos(cas)
init = append(init, cas.Init()...)
cas.PtrInit().Set(nil)
@@ -286,7 +286,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
casorder[i] = cas
setField := func(f string, val ir.Node) {
- r := ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, ir.NewIndexExpr(base.Pos, selv, nodintconst(int64(i))), lookup(f)), val)
+ r := ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, ir.NewIndexExpr(base.Pos, selv, ir.NewInt(int64(i))), lookup(f)), val)
init = append(init, typecheck(r, ctxStmt))
}
@@ -300,7 +300,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
// TODO(mdempsky): There should be a cleaner way to
// handle this.
if base.Flag.Race {
- r := mkcall("selectsetpc", nil, nil, nodAddr(ir.NewIndexExpr(base.Pos, pcs, nodintconst(int64(i)))))
+ r := mkcall("selectsetpc", nil, nil, nodAddr(ir.NewIndexExpr(base.Pos, pcs, ir.NewInt(int64(i)))))
init = append(init, r)
}
}
@@ -315,7 +315,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
r := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
r.Lhs = []ir.Node{chosen, recvOK}
fn := syslook("selectgo")
- r.Rhs = []ir.Node{mkcall1(fn, fn.Type().Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil))}
+ r.Rhs = []ir.Node{mkcall1(fn, fn.Type().Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, ir.NewInt(int64(nsends)), ir.NewInt(int64(nrecvs)), ir.NewBool(dflt == nil))}
init = append(init, typecheck(r, ctxStmt))
// selv and order are no longer alive after selectgo.
@@ -346,12 +346,12 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
}
if dflt != nil {
- setlineno(dflt)
- dispatch(ir.NewBinaryExpr(base.Pos, ir.OLT, chosen, nodintconst(0)), dflt)
+ ir.SetPos(dflt)
+ dispatch(ir.NewBinaryExpr(base.Pos, ir.OLT, chosen, ir.NewInt(0)), dflt)
}
for i, cas := range casorder {
- setlineno(cas)
- dispatch(ir.NewBinaryExpr(base.Pos, ir.OEQ, chosen, nodintconst(int64(i))), cas)
+ ir.SetPos(cas)
+ dispatch(ir.NewBinaryExpr(base.Pos, ir.OEQ, chosen, ir.NewInt(int64(i))), cas)
}
return init
@@ -359,7 +359,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node {
// bytePtrToIndex returns a Node representing "(*byte)(&n[i])".
func bytePtrToIndex(n ir.Node, i int64) ir.Node {
- s := nodAddr(ir.NewIndexExpr(base.Pos, n, nodintconst(i)))
+ s := nodAddr(ir.NewIndexExpr(base.Pos, n, ir.NewInt(i)))
t := types.NewPtr(types.Types[types.TUINT8])
return convnop(s, t)
}
@@ -370,8 +370,8 @@ var scase *types.Type
func scasetype() *types.Type {
if scase == nil {
scase = tostruct([]*ir.Field{
- namedfield("c", types.Types[types.TUNSAFEPTR]),
- namedfield("elem", types.Types[types.TUNSAFEPTR]),
+ ir.NewField(base.Pos, lookup("c"), nil, types.Types[types.TUNSAFEPTR]),
+ ir.NewField(base.Pos, lookup("elem"), nil, types.Types[types.TUNSAFEPTR]),
})
scase.SetNoalg(true)
}
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
index c9a554079d..936edb3d70 100644
--- a/src/cmd/compile/internal/gc/sinit.go
+++ b/src/cmd/compile/internal/gc/sinit.go
@@ -10,7 +10,6 @@ import (
"cmd/compile/internal/types"
"cmd/internal/obj"
"fmt"
- "go/constant"
)
type InitEntry struct {
@@ -65,7 +64,7 @@ func (s *InitSchedule) tryStaticInit(nn ir.Node) bool {
// Discard.
return true
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
defer func() { base.Pos = lno }()
nam := n.X.(*ir.Name)
return s.staticassign(nam, 0, n.Y, nam.Type())
@@ -120,7 +119,7 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type
return true
case ir.OLITERAL:
- if isZero(r) {
+ if ir.IsZero(r) {
return true
}
litsym(l, loff, r, int(typ.Width))
@@ -170,7 +169,7 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type
// copying someone else's computation.
ll := ir.NewNameOffsetExpr(base.Pos, l, loff+e.Xoffset, typ)
rr := ir.NewNameOffsetExpr(base.Pos, orig, e.Xoffset, typ)
- setlineno(rr)
+ ir.SetPos(rr)
s.append(ir.NewAssignStmt(base.Pos, ll, rr))
}
@@ -198,7 +197,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
return true
case ir.OLITERAL:
- if isZero(r) {
+ if ir.IsZero(r) {
return true
}
litsym(l, loff, r, int(typ.Width))
@@ -263,7 +262,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
litsym(l, loff+e.Xoffset, e.Expr, int(e.Expr.Type().Width))
continue
}
- setlineno(e.Expr)
+ ir.SetPos(e.Expr)
if !s.staticassign(l, loff+e.Xoffset, e.Expr, e.Expr.Type()) {
a := ir.NewNameOffsetExpr(base.Pos, l, loff+e.Xoffset, e.Expr.Type())
s.append(ir.NewAssignStmt(base.Pos, a, e.Expr))
@@ -330,7 +329,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
return true
}
// Copy val directly into n.
- setlineno(val)
+ ir.SetPos(val)
if !s.staticassign(l, loff+int64(Widthptr), val, val.Type()) {
a := ir.NewNameOffsetExpr(base.Pos, l, loff+int64(Widthptr), val.Type())
s.append(ir.NewAssignStmt(base.Pos, a, val))
@@ -429,7 +428,7 @@ const (
func getdyn(n ir.Node, top bool) initGenType {
switch n.Op() {
default:
- if isGoConst(n) {
+ if ir.IsConstNode(n) {
return initConst
}
return initDynamic
@@ -548,7 +547,7 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.CompLitExpr, var_ ir.Node,
}
r = kv.Value
}
- a := ir.NewIndexExpr(base.Pos, var_, nodintconst(k))
+ a := ir.NewIndexExpr(base.Pos, var_, ir.NewInt(k))
k++
if isBlank {
return ir.BlankNode, r
@@ -561,7 +560,7 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.CompLitExpr, var_ ir.Node,
if r.Field.IsBlank() || isBlank {
return ir.BlankNode, r.Value
}
- setlineno(r)
+ ir.SetPos(r)
return ir.NewSelectorExpr(base.Pos, ir.ODOT, var_, r.Field), r.Value
}
default:
@@ -589,13 +588,13 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.CompLitExpr, var_ ir.Node,
continue
}
- islit := isGoConst(value)
+ islit := ir.IsConstNode(value)
if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {
continue
}
// build list of assignments: var[index] = expr
- setlineno(a)
+ ir.SetPos(a)
as := ir.NewAssignStmt(base.Pos, a, value)
as = typecheck(as, ctxStmt).(*ir.AssignStmt)
switch kind {
@@ -617,7 +616,7 @@ func isSmallSliceLit(n *ir.CompLitExpr) bool {
return false
}
- return n.Type().Elem().Width == 0 || n.Len <= smallArrayBytes/n.Type().Elem().Width
+ return n.Type().Elem().Width == 0 || n.Len <= ir.MaxSmallArraySize/n.Type().Elem().Width
}
func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) {
@@ -697,7 +696,7 @@ func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes)
}
a = nodAddr(x)
- } else if n.Esc() == EscNone {
+ } else if n.Esc() == ir.EscNone {
a = temp(t)
if vstat == nil {
a = ir.NewAssignStmt(base.Pos, temp(t), nil)
@@ -731,7 +730,7 @@ func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes)
}
value = kv.Value
}
- a := ir.NewIndexExpr(base.Pos, vauto, nodintconst(index))
+ a := ir.NewIndexExpr(base.Pos, vauto, ir.NewInt(index))
a.SetBounded(true)
index++
@@ -753,12 +752,12 @@ func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes)
continue
}
- if vstat != nil && isGoConst(value) { // already set by copy from static value
+ if vstat != nil && ir.IsConstNode(value) { // already set by copy from static value
continue
}
// build list of vauto[c] = expr
- setlineno(value)
+ ir.SetPos(value)
as := typecheck(ir.NewAssignStmt(base.Pos, a, value), ctxStmt)
as = orderStmtInPlace(as, map[string][]*ir.Name{})
as = walkstmt(as)
@@ -778,7 +777,7 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) {
// make the map var
a := ir.NewCallExpr(base.Pos, ir.OMAKE, nil, nil)
a.SetEsc(n.Esc())
- a.Args = []ir.Node{ir.TypeNode(n.Type()), nodintconst(int64(len(n.List)))}
+ a.Args = []ir.Node{ir.TypeNode(n.Type()), ir.NewInt(int64(len(n.List)))}
litas(m, a, init)
entries := n.List
@@ -831,9 +830,9 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) {
kidx.SetBounded(true)
lhs := ir.NewIndexExpr(base.Pos, m, kidx)
- zero := ir.NewAssignStmt(base.Pos, i, nodintconst(0))
- cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, nodintconst(tk.NumElem()))
- incr := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, nodintconst(1)))
+ zero := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0))
+ cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(tk.NumElem()))
+ incr := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1)))
body := ir.NewAssignStmt(base.Pos, lhs, rhs)
loop := ir.NewForStmt(base.Pos, nil, cond, incr, nil)
@@ -855,13 +854,13 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) {
r := r.(*ir.KeyExpr)
index, elem := r.Key, r.Value
- setlineno(index)
+ ir.SetPos(index)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpkey, index))
- setlineno(elem)
+ ir.SetPos(elem)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpelem, elem))
- setlineno(tmpelem)
+ ir.SetPos(tmpelem)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, tmpkey), tmpelem))
}
@@ -992,7 +991,7 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
}
func getlit(lit ir.Node) int {
- if smallintconst(lit) {
+ if ir.IsSmallIntConst(lit) {
return int(ir.Int64Val(lit))
}
return -1
@@ -1098,7 +1097,7 @@ func (s *InitSchedule) initplan(n ir.Node) {
func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n ir.Node) {
// special case: zero can be dropped entirely
- if isZero(n) {
+ if ir.IsZero(n) {
return
}
@@ -1118,47 +1117,6 @@ func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n ir.Node) {
p.E = append(p.E, InitEntry{Xoffset: xoffset, Expr: n})
}
-func isZero(n ir.Node) bool {
- switch n.Op() {
- case ir.ONIL:
- return true
-
- case ir.OLITERAL:
- switch u := n.Val(); u.Kind() {
- case constant.String:
- return constant.StringVal(u) == ""
- case constant.Bool:
- return !constant.BoolVal(u)
- default:
- return constant.Sign(u) == 0
- }
-
- case ir.OARRAYLIT:
- n := n.(*ir.CompLitExpr)
- for _, n1 := range n.List {
- if n1.Op() == ir.OKEY {
- n1 = n1.(*ir.KeyExpr).Value
- }
- if !isZero(n1) {
- return false
- }
- }
- return true
-
- case ir.OSTRUCTLIT:
- n := n.(*ir.CompLitExpr)
- for _, n1 := range n.List {
- n1 := n1.(*ir.StructKeyExpr)
- if !isZero(n1.Value) {
- return false
- }
- }
- return true
- }
-
- return false
-}
-
func isvaluelit(n ir.Node) bool {
return n.Op() == ir.OARRAYLIT || n.Op() == ir.OSTRUCTLIT
}
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 22cc868f36..f879d8b86d 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -1159,7 +1159,7 @@ func (s *state) stmt(n ir.Node) {
// Expression statements
case ir.OCALLFUNC:
n := n.(*ir.CallExpr)
- if IsIntrinsicCall(n) {
+ if ir.IsIntrinsicCall(n) {
s.intrinsicCall(n)
return
}
@@ -1186,7 +1186,7 @@ func (s *state) stmt(n ir.Node) {
var defertype string
if s.hasOpenDefers {
defertype = "open-coded"
- } else if n.Esc() == EscNever {
+ } else if n.Esc() == ir.EscNever {
defertype = "stack-allocated"
} else {
defertype = "heap-allocated"
@@ -1197,7 +1197,7 @@ func (s *state) stmt(n ir.Node) {
s.openDeferRecord(n.Call.(*ir.CallExpr))
} else {
d := callDefer
- if n.Esc() == EscNever {
+ if n.Esc() == ir.EscNever {
d = callDeferStack
}
s.callResult(n.Call.(*ir.CallExpr), d)
@@ -1232,7 +1232,7 @@ func (s *state) stmt(n ir.Node) {
// We come here only when it is an intrinsic call returning two values.
n := n.(*ir.AssignListStmt)
call := n.Rhs[0].(*ir.CallExpr)
- if !IsIntrinsicCall(call) {
+ if !ir.IsIntrinsicCall(call) {
s.Fatalf("non-intrinsic AS2FUNC not expanded %v", call)
}
v := s.intrinsicCall(call)
@@ -1300,7 +1300,7 @@ func (s *state) stmt(n ir.Node) {
// All literals with nonzero fields have already been
// rewritten during walk. Any that remain are just T{}
// or equivalents. Use the zero value.
- if !isZero(rhs) {
+ if !ir.IsZero(rhs) {
s.Fatalf("literal with nonzero value in SSA: %v", rhs)
}
rhs = nil
@@ -1309,7 +1309,7 @@ func (s *state) stmt(n ir.Node) {
// Check whether we're writing the result of an append back to the same slice.
// If so, we handle it specially to avoid write barriers on the fast
// (non-growth) path.
- if !samesafeexpr(n.X, rhs.Args[0]) || base.Flag.N != 0 {
+ if !ir.SameSafeExpr(n.X, rhs.Args[0]) || base.Flag.N != 0 {
break
}
// If the slice can be SSA'd, it'll be on the stack,
@@ -1362,7 +1362,7 @@ func (s *state) stmt(n ir.Node) {
}
var skip skipMask
- if rhs != nil && (rhs.Op() == ir.OSLICE || rhs.Op() == ir.OSLICE3 || rhs.Op() == ir.OSLICESTR) && samesafeexpr(rhs.(*ir.SliceExpr).X, n.X) {
+ if rhs != nil && (rhs.Op() == ir.OSLICE || rhs.Op() == ir.OSLICE3 || rhs.Op() == ir.OSLICESTR) && ir.SameSafeExpr(rhs.(*ir.SliceExpr).X, n.X) {
// We're assigning a slicing operation back to its source.
// Don't write back fields we aren't changing. See issue #14855.
rhs := rhs.(*ir.SliceExpr)
@@ -2085,7 +2085,7 @@ func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op {
// expr converts the expression n to ssa, adds it to s and returns the ssa result.
func (s *state) expr(n ir.Node) *ssa.Value {
- if hasUniquePos(n) {
+ if ir.HasUniquePos(n) {
// ONAMEs and named OLITERALs have the line number
// of the decl, not the use. See issue 14742.
s.pushLine(n.Pos())
@@ -2726,7 +2726,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
// All literals with nonzero fields have already been
// rewritten during walk. Any that remain are just T{}
// or equivalents. Use the zero value.
- if !isZero(n.X) {
+ if !ir.IsZero(n.X) {
s.Fatalf("literal with nonzero value in SSA: %v", n.X)
}
return s.zeroVal(n.Type())
@@ -2735,7 +2735,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
// SSA, then load just the selected field. This
// prevents false memory dependencies in race/msan
// instrumentation.
- if islvalue(n) && !s.canSSA(n) {
+ if ir.IsAssignable(n) && !s.canSSA(n) {
p := s.addr(n)
return s.load(n.Type(), p)
}
@@ -2880,7 +2880,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
case ir.OCALLFUNC:
n := n.(*ir.CallExpr)
- if IsIntrinsicCall(n) {
+ if ir.IsIntrinsicCall(n) {
return s.intrinsicCall(n)
}
fallthrough
@@ -2901,7 +2901,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
// rewritten during walk. Any that remain are just T{}
// or equivalents. Use the zero value.
n := n.(*ir.CompLitExpr)
- if !isZero(n) {
+ if !ir.IsZero(n) {
s.Fatalf("literal with nonzero value in SSA: %v", n)
}
return s.zeroVal(n.Type())
@@ -3236,7 +3236,7 @@ func (s *state) assign(left ir.Node, right *ssa.Value, deref bool, skip skipMask
// Left is not ssa-able. Compute its address.
addr := s.addr(left)
- if isReflectHeaderDataField(left) {
+ if ir.IsReflectHeaderDataField(left) {
// Package unsafe's documentation says storing pointers into
// reflect.SliceHeader and reflect.StringHeader's Data fields
// is valid, even though they have type uintptr (#19168).
@@ -5021,7 +5021,7 @@ func (s *state) addr(n ir.Node) *ssa.Value {
if v != nil {
return v
}
- if n == nodfp {
+ if n == ir.RegFP {
// Special arg that points to the frame pointer (Used by ORECOVER).
return s.entryNewValue2A(ssa.OpLocalAddr, t, n, s.sp, s.startmem)
}
@@ -5141,7 +5141,7 @@ func (s *state) canSSAName(name *ir.Name) bool {
if name.Addrtaken() {
return false
}
- if isParamHeapCopy(name) {
+ if ir.IsParamHeapCopy(name) {
return false
}
if name.Class_ == ir.PAUTOHEAP {
@@ -7271,7 +7271,7 @@ func (e *ssafn) SplitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t
ir.AsNode(s.Def).Name().SetUsed(true)
n.SetType(t)
n.Class_ = ir.PAUTO
- n.SetEsc(EscNever)
+ n.SetEsc(ir.EscNever)
n.Curfn = e.curfn
e.curfn.Dcl = append(e.curfn.Dcl, n)
dowidth(t)
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index a845abeb3a..bcf17e42d6 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -10,7 +10,6 @@ import (
"cmd/compile/internal/types"
"cmd/internal/src"
"fmt"
- "go/constant"
"sort"
"strconv"
"strings"
@@ -32,40 +31,6 @@ var (
largeStackFrames []largeStack
)
-// hasUniquePos reports whether n has a unique position that can be
-// used for reporting error messages.
-//
-// It's primarily used to distinguish references to named objects,
-// whose Pos will point back to their declaration position rather than
-// their usage position.
-func hasUniquePos(n ir.Node) bool {
- switch n.Op() {
- case ir.ONAME, ir.OPACK:
- return false
- case ir.OLITERAL, ir.ONIL, ir.OTYPE:
- if n.Sym() != nil {
- return false
- }
- }
-
- if !n.Pos().IsKnown() {
- if base.Flag.K != 0 {
- base.Warn("setlineno: unknown position (line 0)")
- }
- return false
- }
-
- return true
-}
-
-func setlineno(n ir.Node) src.XPos {
- lno := base.Pos
- if n != nil && hasUniquePos(n) {
- base.Pos = n.Pos()
- }
- return lno
-}
-
func lookup(name string) *types.Sym {
return types.LocalPkg.Lookup(name)
}
@@ -89,8 +54,8 @@ func autolabel(prefix string) *types.Sym {
if prefix[0] != '.' {
base.Fatalf("autolabel prefix must start with '.', have %q", prefix)
}
- fn := Curfn
- if Curfn == nil {
+ fn := ir.CurFunc
+ if ir.CurFunc == nil {
base.Fatalf("autolabel outside function")
}
n := fn.Label
@@ -164,28 +129,16 @@ func nodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr {
// newname returns a new ONAME Node associated with symbol s.
func NewName(s *types.Sym) *ir.Name {
n := ir.NewNameAt(base.Pos, s)
- n.Curfn = Curfn
+ n.Curfn = ir.CurFunc
return n
}
-func nodintconst(v int64) ir.Node {
- return ir.NewLiteral(constant.MakeInt64(v))
-}
-
func nodnil() ir.Node {
n := ir.NewNilExpr(base.Pos)
n.SetType(types.Types[types.TNIL])
return n
}
-func nodbool(b bool) ir.Node {
- return ir.NewLiteral(constant.MakeBool(b))
-}
-
-func nodstr(s string) ir.Node {
- return ir.NewLiteral(constant.MakeString(s))
-}
-
func isptrto(t *types.Type, et types.Kind) bool {
if t == nil {
return false
@@ -778,7 +731,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node {
}
// make a copy; must not be used as an lvalue
- if islvalue(n) {
+ if ir.IsAssignable(n) {
base.Fatalf("missing lvalue case in safeexpr: %v", n)
}
return cheapexpr(n, init)
@@ -1109,7 +1062,7 @@ func structargs(tl *types.Type, mustname bool) []*ir.Field {
s = lookupN(".anon", gen)
gen++
}
- a := symfield(s, t.Type)
+ a := ir.NewField(base.Pos, s, nil, t.Type)
a.Pos = t.Pos
a.IsDDD = t.IsDDD()
args = append(args, a)
@@ -1160,7 +1113,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
dclcontext = ir.PEXTERN
tfn := ir.NewFuncType(base.Pos,
- namedfield(".this", rcvr),
+ ir.NewField(base.Pos, lookup(".this"), nil, rcvr),
structargs(method.Type.Params(), true),
structargs(method.Type.Results(), false))
@@ -1198,11 +1151,11 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
}
as := ir.NewAssignStmt(base.Pos, nthis, convnop(left, rcvr))
fn.Body.Append(as)
- fn.Body.Append(ir.NewBranchStmt(base.Pos, ir.ORETJMP, methodSym(methodrcvr, method.Sym)))
+ fn.Body.Append(ir.NewBranchStmt(base.Pos, ir.ORETJMP, ir.MethodSym(methodrcvr, method.Sym)))
} else {
fn.SetWrapper(true) // ignore frame for panic+recover matching
call := ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil)
- call.Args.Set(paramNnames(tfn.Type()))
+ call.Args.Set(ir.ParamNames(tfn.Type()))
call.IsDDD = tfn.Type().IsVariadic()
if method.Type.NumResults() > 0 {
ret := ir.NewReturnStmt(base.Pos, nil)
@@ -1223,7 +1176,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
}
typecheckFunc(fn)
- Curfn = fn
+ ir.CurFunc = fn
typecheckslice(fn.Body, ctxStmt)
// Inline calls within (*T).M wrappers. This is safe because we only
@@ -1234,29 +1187,21 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
}
escapeFuncs([]*ir.Func{fn}, false)
- Curfn = nil
+ ir.CurFunc = nil
Target.Decls = append(Target.Decls, fn)
}
-func paramNnames(ft *types.Type) []ir.Node {
- args := make([]ir.Node, ft.NumParams())
- for i, f := range ft.Params().FieldSlice() {
- args[i] = ir.AsNode(f.Nname)
- }
- return args
-}
-
func hashmem(t *types.Type) ir.Node {
sym := ir.Pkgs.Runtime.Lookup("memhash")
n := NewName(sym)
- setNodeNameFunc(n)
+ ir.MarkFunc(n)
n.SetType(functype(nil, []*ir.Field{
- anonfield(types.NewPtr(t)),
- anonfield(types.Types[types.TUINTPTR]),
- anonfield(types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, nil, nil, types.NewPtr(t)),
+ ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]),
}, []*ir.Field{
- anonfield(types.Types[types.TUINTPTR]),
+ ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]),
}))
return n
}
@@ -1367,15 +1312,6 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool
return true
}
-func liststmt(l []ir.Node) ir.Node {
- n := ir.NewBlockStmt(base.Pos, nil)
- n.List.Set(l)
- if len(l) != 0 {
- n.SetPos(l[0].Pos())
- }
- return n
-}
-
func ngotype(n ir.Node) *types.Sym {
if n.Type() != nil {
return typenamesym(n.Type())
@@ -1383,25 +1319,6 @@ func ngotype(n ir.Node) *types.Sym {
return nil
}
-// The result of initExpr MUST be assigned back to n, e.g.
-// n.Left = initExpr(init, n.Left)
-func initExpr(init []ir.Node, n ir.Node) ir.Node {
- if len(init) == 0 {
- return n
- }
- if ir.MayBeShared(n) {
- // Introduce OCONVNOP to hold init list.
- old := n
- n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, old)
- n.SetType(old.Type())
- n.SetTypecheck(1)
- }
-
- n.PtrInit().Prepend(init...)
- n.SetHasCall(true)
- return n
-}
-
// The linker uses the magic symbol prefixes "go." and "type."
// Avoid potential confusion between import paths and symbols
// by rejecting these reserved imports for now. Also, people
diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go
index 513b890355..5bbc91fcc1 100644
--- a/src/cmd/compile/internal/gc/swt.go
+++ b/src/cmd/compile/internal/gc/swt.go
@@ -190,7 +190,7 @@ func typecheckExprSwitch(n *ir.SwitchStmt) {
}
for i := range ls {
- setlineno(ncase)
+ ir.SetPos(ncase)
ls[i] = typecheck(ls[i], ctxExpr)
ls[i] = defaultlit(ls[i], t)
n1 := ls[i]
@@ -246,14 +246,14 @@ func walkswitch(sw *ir.SwitchStmt) {
// walkExprSwitch generates an AST implementing sw. sw is an
// expression switch.
func walkExprSwitch(sw *ir.SwitchStmt) {
- lno := setlineno(sw)
+ lno := ir.SetPos(sw)
cond := sw.Tag
sw.Tag = nil
// convert switch {...} to switch true {...}
if cond == nil {
- cond = nodbool(true)
+ cond = ir.NewBool(true)
cond = typecheck(cond, ctxExpr)
cond = defaultlit(cond, nil)
}
@@ -398,11 +398,11 @@ func (s *exprSwitch) flush() {
// Perform two-level binary search.
binarySearch(len(runs), &s.done,
func(i int) ir.Node {
- return ir.NewBinaryExpr(base.Pos, ir.OLE, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), nodintconst(runLen(runs[i-1])))
+ return ir.NewBinaryExpr(base.Pos, ir.OLE, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), ir.NewInt(runLen(runs[i-1])))
},
func(i int, nif *ir.IfStmt) {
run := runs[i]
- nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), nodintconst(runLen(run)))
+ nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), ir.NewInt(runLen(run)))
s.search(run, &nif.Body)
},
)
@@ -708,13 +708,13 @@ func (s *typeSwitch) flush() {
binarySearch(len(cc), &s.done,
func(i int) ir.Node {
- return ir.NewBinaryExpr(base.Pos, ir.OLE, s.hashname, nodintconst(int64(cc[i-1].hash)))
+ return ir.NewBinaryExpr(base.Pos, ir.OLE, s.hashname, ir.NewInt(int64(cc[i-1].hash)))
},
func(i int, nif *ir.IfStmt) {
// TODO(mdempsky): Omit hash equality check if
// there's only one type.
c := cc[i]
- nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, s.hashname, nodintconst(int64(c.hash)))
+ nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, s.hashname, ir.NewInt(int64(c.hash)))
nif.Body.Append(c.body.Take()...)
},
)
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index 5e13facc4f..0beb5712d4 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -98,13 +98,13 @@ func TypecheckPackage() {
if n.Op() == ir.ODCLFUNC {
n := n.(*ir.Func)
if n.OClosure != nil {
- Curfn = n
+ ir.CurFunc = n
capturevars(n)
}
}
}
capturevarscomplete = true
- Curfn = nil
+ ir.CurFunc = nil
if base.Debug.TypecheckInl != 0 {
// Typecheck imported function bodies if Debug.l > 1,
@@ -139,7 +139,7 @@ func TypecheckCallee(n ir.Node) ir.Node {
}
func TypecheckFuncBody(n *ir.Func) {
- Curfn = n
+ ir.CurFunc = n
decldepth = 1
errorsBefore := base.Errors()
typecheckslice(n.Body, ctxStmt)
@@ -259,7 +259,7 @@ func resolve(n ir.Node) (res ir.Node) {
if r.Op() == ir.OIOTA {
if x := getIotaValue(); x >= 0 {
- return nodintconst(x)
+ return ir.NewInt(x)
}
return n
}
@@ -380,7 +380,7 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
defer tracePrint("typecheck", n)(&res)
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
// Skip over parens.
for n.Op() == ir.OPAREN {
@@ -682,7 +682,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
}
v := size.Val()
- if doesoverflow(v, types.Types[types.TINT]) {
+ if ir.ConstOverflow(v, types.Types[types.TINT]) {
base.Errorf("array bound is too large")
return n
}
@@ -1076,7 +1076,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
default:
checklvalue(n.X, "take the address of")
- r := outervalue(n.X)
+ r := ir.OuterValue(n.X)
if r.Op() == ir.ONAME {
r := r.(*ir.Name)
if ir.Orig(r) != r {
@@ -1270,7 +1270,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Index, t.NumElem())
} else if ir.IsConst(n.X, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(ir.StringVal(n.X))))) {
base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Index, len(ir.StringVal(n.X)))
- } else if doesoverflow(x, types.Types[types.TINT]) {
+ } else if ir.ConstOverflow(x, types.Types[types.TINT]) {
base.Errorf("invalid %s index %v (index too large)", why, n.Index)
}
}
@@ -1412,7 +1412,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
}
if ir.IsConst(n.Len, constant.Int) {
- if doesoverflow(n.Len.Val(), types.Types[types.TINT]) {
+ if ir.ConstOverflow(n.Len.Val(), types.Types[types.TINT]) {
base.Fatalf("len for OMAKESLICECOPY too large")
}
if constant.Sign(n.Len.Val()) < 0 {
@@ -1440,7 +1440,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
return n
}
if l.Type().IsArray() {
- if !islvalue(n.X) {
+ if !ir.IsAssignable(n.X) {
base.Errorf("invalid operation %v (slice of unaddressable value)", n)
n.SetType(nil)
return n
@@ -1538,7 +1538,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
return n
}
u := ir.NewUnaryExpr(n.Pos(), l.BuiltinOp, arg)
- return typecheck(initExpr(n.Init(), u), top) // typecheckargs can add to old.Init
+ return typecheck(ir.InitExpr(n.Init(), u), top) // typecheckargs can add to old.Init
case ir.OCOMPLEX, ir.OCOPY:
typecheckargs(n)
@@ -1548,7 +1548,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
return n
}
b := ir.NewBinaryExpr(n.Pos(), l.BuiltinOp, arg1, arg2)
- return typecheck(initExpr(n.Init(), b), top) // typecheckargs can add to old.Init
+ return typecheck(ir.InitExpr(n.Init(), b), top) // typecheckargs can add to old.Init
}
panic("unreachable")
}
@@ -2023,7 +2023,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
return n
}
} else {
- l = nodintconst(0)
+ l = ir.NewInt(0)
}
nn = ir.NewMakeExpr(n.Pos(), ir.OMAKEMAP, l, nil)
nn.SetEsc(n.Esc())
@@ -2044,7 +2044,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
return n
}
} else {
- l = nodintconst(0)
+ l = ir.NewInt(0)
}
nn = ir.NewMakeExpr(n.Pos(), ir.OMAKECHAN, l, nil)
}
@@ -2257,16 +2257,16 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
case ir.ORETURN:
n := n.(*ir.ReturnStmt)
typecheckargs(n)
- if Curfn == nil {
+ if ir.CurFunc == nil {
base.Errorf("return outside function")
n.SetType(nil)
return n
}
- if hasNamedResults(Curfn) && len(n.Results) == 0 {
+ if ir.HasNamedResults(ir.CurFunc) && len(n.Results) == 0 {
return n
}
- typecheckaste(ir.ORETURN, nil, false, Curfn.Type().Results(), n.Results, func() string { return "return argument" })
+ typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), n.Results, func() string { return "return argument" })
return n
case ir.ORETJMP:
@@ -2352,9 +2352,9 @@ func typecheckargs(n ir.Node) {
// init.go hasn't yet created it. Instead, associate the
// temporary variables with initTodo for now, and init.go
// will reassociate them later when it's appropriate.
- static := Curfn == nil
+ static := ir.CurFunc == nil
if static {
- Curfn = initTodo
+ ir.CurFunc = initTodo
}
list = nil
for _, f := range t.FieldSlice() {
@@ -2364,7 +2364,7 @@ func typecheckargs(n ir.Node) {
list = append(list, t)
}
if static {
- Curfn = nil
+ ir.CurFunc = nil
}
switch n := n.(type) {
@@ -2398,7 +2398,7 @@ func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {
} else if ir.IsConst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(ir.StringVal(l))))) {
base.Errorf("invalid slice index %v (out of bounds for %d-byte string)", r, len(ir.StringVal(l)))
return false
- } else if doesoverflow(x, types.Types[types.TINT]) {
+ } else if ir.ConstOverflow(x, types.Types[types.TINT]) {
base.Errorf("invalid slice index %v (index too large)", r)
return false
}
@@ -2603,7 +2603,7 @@ func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) {
me := ir.NewMethodExpr(n.Pos(), n.X.Type(), m)
me.SetType(methodfunc(m.Type, n.X.Type()))
- f := NewName(methodSym(t, m.Sym))
+ f := NewName(ir.MethodSym(t, m.Sym))
f.Class_ = ir.PFUNC
f.SetType(me.Type())
me.FuncName_ = f
@@ -2717,7 +2717,7 @@ func lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field {
return nil
}
- n.Sel = methodSym(n.X.Type(), f2.Sym)
+ n.Sel = ir.MethodSym(n.X.Type(), f2.Sym)
n.Offset = f2.Offset
n.SetType(f2.Type)
n.SetOp(ir.ODOTMETH)
@@ -2801,7 +2801,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i
goto toomany
}
n = nl[i]
- setlineno(n)
+ ir.SetPos(n)
if n.Type() != nil {
nl[i] = assignconvfn(n, t, desc)
}
@@ -2811,7 +2811,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i
// TODO(mdempsky): Make into ... call with implicit slice.
for ; i < len(nl); i++ {
n = nl[i]
- setlineno(n)
+ ir.SetPos(n)
if n.Type() != nil {
nl[i] = assignconvfn(n, t.Elem(), desc)
}
@@ -2823,7 +2823,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i
goto notenough
}
n = nl[i]
- setlineno(n)
+ ir.SetPos(n)
if n.Type() != nil {
nl[i] = assignconvfn(n, t, desc)
}
@@ -2998,7 +2998,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) {
// Save original node (including n.Right)
n.SetOrig(ir.Copy(n))
- setlineno(n.Ntype)
+ ir.SetPos(n.Ntype)
// Need to handle [...]T arrays specially.
if array, ok := n.Ntype.(*ir.ArrayType); ok && array.Elem != nil && array.Len == nil {
@@ -3042,7 +3042,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) {
case types.TMAP:
var cs constSet
for i3, l := range n.List {
- setlineno(l)
+ ir.SetPos(l)
if l.Op() != ir.OKEY {
n.List[i3] = typecheck(l, ctxExpr)
base.Errorf("missing key in map literal")
@@ -3074,7 +3074,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) {
// simple list of variables
ls := n.List
for i, n1 := range ls {
- setlineno(n1)
+ ir.SetPos(n1)
n1 = typecheck(n1, ctxExpr)
ls[i] = n1
if i >= t.NumFields() {
@@ -3105,7 +3105,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) {
// keyed list
ls := n.List
for i, l := range ls {
- setlineno(l)
+ ir.SetPos(l)
if l.Op() == ir.OKEY {
kv := l.(*ir.KeyExpr)
@@ -3199,7 +3199,7 @@ func typecheckarraylit(elemType *types.Type, bound int64, elts []ir.Node, ctx st
var key, length int64
for i, elt := range elts {
- setlineno(elt)
+ ir.SetPos(elt)
r := elts[i]
var kv *ir.KeyExpr
if elt.Op() == ir.OKEY {
@@ -3264,41 +3264,8 @@ func nonexported(sym *types.Sym) bool {
return sym != nil && !types.IsExported(sym.Name)
}
-// lvalue etc
-func islvalue(n ir.Node) bool {
- switch n.Op() {
- case ir.OINDEX:
- n := n.(*ir.IndexExpr)
- if n.X.Type() != nil && n.X.Type().IsArray() {
- return islvalue(n.X)
- }
- if n.X.Type() != nil && n.X.Type().IsString() {
- return false
- }
- fallthrough
- case ir.ODEREF, ir.ODOTPTR, ir.OCLOSUREREAD:
- return true
-
- case ir.ODOT:
- n := n.(*ir.SelectorExpr)
- return islvalue(n.X)
-
- case ir.ONAME:
- n := n.(*ir.Name)
- if n.Class_ == ir.PFUNC {
- return false
- }
- return true
-
- case ir.ONAMEOFFSET:
- return true
- }
-
- return false
-}
-
func checklvalue(n ir.Node, verb string) {
- if !islvalue(n) {
+ if !ir.IsAssignable(n) {
base.Errorf("cannot %s %v", verb, n)
}
}
@@ -3306,7 +3273,7 @@ func checklvalue(n ir.Node, verb string) {
func checkassign(stmt ir.Node, n ir.Node) {
// Variables declared in ORANGE are assigned on every iteration.
if !ir.DeclaredBy(n, stmt) || stmt.Op() == ir.ORANGE {
- r := outervalue(n)
+ r := ir.OuterValue(n)
if r.Op() == ir.ONAME {
r := r.(*ir.Name)
r.Name().SetAssigned(true)
@@ -3316,7 +3283,7 @@ func checkassign(stmt ir.Node, n ir.Node) {
}
}
- if islvalue(n) {
+ if ir.IsAssignable(n) {
return
}
if n.Op() == ir.OINDEXMAP {
@@ -3335,7 +3302,7 @@ func checkassign(stmt ir.Node, n ir.Node) {
base.Errorf("cannot assign to struct field %v in map", n)
case (n.Op() == ir.OINDEX && n.(*ir.IndexExpr).X.Type().IsString()) || n.Op() == ir.OSLICESTR:
base.Errorf("cannot assign to %v (strings are immutable)", n)
- case n.Op() == ir.OLITERAL && n.Sym() != nil && isGoConst(n):
+ case n.Op() == ir.OLITERAL && n.Sym() != nil && ir.IsConstNode(n):
base.Errorf("cannot assign to %v (declared const)", n)
default:
base.Errorf("cannot assign to %v", n)
@@ -3349,77 +3316,6 @@ func checkassignlist(stmt ir.Node, l ir.Nodes) {
}
}
-// samesafeexpr checks whether it is safe to reuse one of l and r
-// instead of computing both. samesafeexpr assumes that l and r are
-// used in the same statement or expression. In order for it to be
-// safe to reuse l or r, they must:
-// * be the same expression
-// * not have side-effects (no function calls, no channel ops);
-// however, panics are ok
-// * not cause inappropriate aliasing; e.g. two string to []byte
-// conversions, must result in two distinct slices
-//
-// The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
-// as an lvalue (map assignment) and an rvalue (map access). This is
-// currently OK, since the only place samesafeexpr gets used on an
-// lvalue expression is for OSLICE and OAPPEND optimizations, and it
-// is correct in those settings.
-func samesafeexpr(l ir.Node, r ir.Node) bool {
- if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
- return false
- }
-
- switch l.Op() {
- case ir.ONAME, ir.OCLOSUREREAD:
- return l == r
-
- case ir.ODOT, ir.ODOTPTR:
- l := l.(*ir.SelectorExpr)
- r := r.(*ir.SelectorExpr)
- return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && samesafeexpr(l.X, r.X)
-
- case ir.ODEREF:
- l := l.(*ir.StarExpr)
- r := r.(*ir.StarExpr)
- return samesafeexpr(l.X, r.X)
-
- case ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG:
- l := l.(*ir.UnaryExpr)
- r := r.(*ir.UnaryExpr)
- return samesafeexpr(l.X, r.X)
-
- case ir.OCONVNOP:
- l := l.(*ir.ConvExpr)
- r := r.(*ir.ConvExpr)
- return samesafeexpr(l.X, r.X)
-
- case ir.OCONV:
- l := l.(*ir.ConvExpr)
- r := r.(*ir.ConvExpr)
- // Some conversions can't be reused, such as []byte(str).
- // Allow only numeric-ish types. This is a bit conservative.
- return types.IsSimple[l.Type().Kind()] && samesafeexpr(l.X, r.X)
-
- case ir.OINDEX, ir.OINDEXMAP:
- l := l.(*ir.IndexExpr)
- r := r.(*ir.IndexExpr)
- return samesafeexpr(l.X, r.X) && samesafeexpr(l.Index, r.Index)
-
- case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD:
- l := l.(*ir.BinaryExpr)
- r := r.(*ir.BinaryExpr)
- return samesafeexpr(l.X, r.X) && samesafeexpr(l.Y, r.Y)
-
- case ir.OLITERAL:
- return constant.Compare(l.Val(), token.EQL, r.Val())
-
- case ir.ONIL:
- return true
- }
-
- return false
-}
-
// type check assignment.
// if this assignment is the definition of a var on the left side,
// fill in the var's type.
@@ -3639,7 +3535,7 @@ func typecheckfunc(n *ir.Func) {
return
}
- n.Nname.SetSym(methodSym(rcvr.Type, n.Shortname))
+ n.Nname.SetSym(ir.MethodSym(rcvr.Type, n.Shortname))
declare(n.Nname, ir.PFUNC)
}
@@ -3658,7 +3554,7 @@ func stringtoruneslit(n *ir.ConvExpr) ir.Node {
var l []ir.Node
i := 0
for _, r := range ir.StringVal(n.X) {
- l = append(l, ir.NewKeyExpr(base.Pos, nodintconst(int64(i)), nodintconst(int64(r))))
+ l = append(l, ir.NewKeyExpr(base.Pos, ir.NewInt(int64(i)), ir.NewInt(int64(r))))
i++
}
@@ -3716,7 +3612,7 @@ func typecheckdef(n ir.Node) {
defer tracePrint("typecheckdef", n)(nil)
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
if n.Op() == ir.ONONAME {
if !n.Diag() {
@@ -3779,7 +3675,7 @@ func typecheckdef(n ir.Node) {
if e.Type() == nil {
goto ret
}
- if !isGoConst(e) {
+ if !ir.IsConstNode(e) {
if !e.Diag() {
if e.Op() == ir.ONIL {
base.ErrorfAt(n.Pos(), "const initializer cannot be nil")
@@ -3904,7 +3800,7 @@ func checkmake(t *types.Type, arg string, np *ir.Node) bool {
base.Errorf("negative %s argument in make(%v)", arg, t)
return false
}
- if doesoverflow(v, types.Types[types.TINT]) {
+ if ir.ConstOverflow(v, types.Types[types.TINT]) {
base.Errorf("%s argument too large in make(%v)", arg, t)
return false
}
@@ -4236,8 +4132,8 @@ func getIotaValue() int64 {
}
}
- if Curfn != nil && Curfn.Iota >= 0 {
- return Curfn.Iota
+ if ir.CurFunc != nil && ir.CurFunc.Iota >= 0 {
+ return ir.CurFunc.Iota
}
return -1
@@ -4245,33 +4141,10 @@ func getIotaValue() int64 {
// curpkg returns the current package, based on Curfn.
func curpkg() *types.Pkg {
- fn := Curfn
+ fn := ir.CurFunc
if fn == nil {
// Initialization expressions for package-scope variables.
return types.LocalPkg
}
return fnpkg(fn.Nname)
}
-
-// MethodName returns the ONAME representing the method
-// referenced by expression n, which must be a method selector,
-// method expression, or method value.
-func methodExprName(n ir.Node) *ir.Name {
- name, _ := methodExprFunc(n).Nname.(*ir.Name)
- return name
-}
-
-// MethodFunc is like MethodName, but returns the types.Field instead.
-func methodExprFunc(n ir.Node) *types.Field {
- switch n.Op() {
- case ir.ODOTMETH:
- return n.(*ir.SelectorExpr).Selection
- case ir.OMETHEXPR:
- return n.(*ir.MethodExpr).Method
- case ir.OCALLPART:
- n := n.(*ir.CallPartExpr)
- return callpartMethod(n)
- }
- base.Fatalf("unexpected node: %v (%v)", n, n.Op())
- panic("unreachable")
-}
diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go
index c9cce4b488..b7472ede0f 100644
--- a/src/cmd/compile/internal/gc/universe.go
+++ b/src/cmd/compile/internal/gc/universe.go
@@ -340,8 +340,8 @@ func finishUniverse() {
s1.Block = s.Block
}
- nodfp = NewName(lookup(".fp"))
- nodfp.SetType(types.Types[types.TINT32])
- nodfp.Class_ = ir.PPARAM
- nodfp.SetUsed(true)
+ ir.RegFP = NewName(lookup(".fp"))
+ ir.RegFP.SetType(types.Types[types.TINT32])
+ ir.RegFP.Class_ = ir.PPARAM
+ ir.RegFP.SetUsed(true)
}
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 5d812064b6..dd376a8835 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -10,6 +10,7 @@ import (
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/objabi"
+ "cmd/internal/src"
"cmd/internal/sys"
"encoding/binary"
"errors"
@@ -24,7 +25,7 @@ const tmpstringbufsize = 32
const zeroValSize = 1024 // must match value of runtime/map.go:maxZero
func walk(fn *ir.Func) {
- Curfn = fn
+ ir.CurFunc = fn
errorsBefore := base.Errors()
order(fn)
if base.Errors() > errorsBefore {
@@ -32,8 +33,8 @@ func walk(fn *ir.Func) {
}
if base.Flag.W != 0 {
- s := fmt.Sprintf("\nbefore walk %v", Curfn.Sym())
- ir.DumpList(s, Curfn.Body)
+ s := fmt.Sprintf("\nbefore walk %v", ir.CurFunc.Sym())
+ ir.DumpList(s, ir.CurFunc.Body)
}
lno := base.Pos
@@ -72,17 +73,17 @@ func walk(fn *ir.Func) {
if base.Errors() > errorsBefore {
return
}
- walkstmtlist(Curfn.Body)
+ walkstmtlist(ir.CurFunc.Body)
if base.Flag.W != 0 {
- s := fmt.Sprintf("after walk %v", Curfn.Sym())
- ir.DumpList(s, Curfn.Body)
+ s := fmt.Sprintf("after walk %v", ir.CurFunc.Sym())
+ ir.DumpList(s, ir.CurFunc.Body)
}
zeroResults()
heapmoves()
- if base.Flag.W != 0 && len(Curfn.Enter) > 0 {
- s := fmt.Sprintf("enter %v", Curfn.Sym())
- ir.DumpList(s, Curfn.Enter)
+ if base.Flag.W != 0 && len(ir.CurFunc.Enter) > 0 {
+ s := fmt.Sprintf("enter %v", ir.CurFunc.Sym())
+ ir.DumpList(s, ir.CurFunc.Enter)
}
if base.Flag.Cfg.Instrumenting {
@@ -100,7 +101,7 @@ func paramoutheap(fn *ir.Func) bool {
for _, ln := range fn.Dcl {
switch ln.Class_ {
case ir.PPARAMOUT:
- if isParamStackCopy(ln) || ln.Addrtaken() {
+ if ir.IsParamStackCopy(ln) || ln.Addrtaken() {
return true
}
@@ -120,7 +121,7 @@ func walkstmt(n ir.Node) ir.Node {
return n
}
- setlineno(n)
+ ir.SetPos(n)
walkstmtlist(n.Init())
@@ -191,7 +192,7 @@ func walkstmt(n ir.Node) ir.Node {
n.X = walkexpr(n.X, &init)
call := walkexpr(mkcall1(chanfn("chanrecv1", 2, n.X.Type()), nil, &init, n.X, nodnil()), &init)
- return initExpr(init, call)
+ return ir.InitExpr(init, call)
case ir.OBREAK,
ir.OCONTINUE,
@@ -230,18 +231,18 @@ func walkstmt(n ir.Node) ir.Node {
case ir.ODEFER:
n := n.(*ir.GoDeferStmt)
- Curfn.SetHasDefer(true)
- Curfn.NumDefers++
- if Curfn.NumDefers > maxOpenDefers {
+ ir.CurFunc.SetHasDefer(true)
+ ir.CurFunc.NumDefers++
+ if ir.CurFunc.NumDefers > maxOpenDefers {
// Don't allow open-coded defers if there are more than
// 8 defers in the function, since we use a single
// byte to record active defers.
- Curfn.SetOpenCodedDeferDisallowed(true)
+ ir.CurFunc.SetOpenCodedDeferDisallowed(true)
}
- if n.Esc() != EscNever {
+ if n.Esc() != ir.EscNever {
// If n.Esc is not EscNever, then this defer occurs in a loop,
// so open-coded defers cannot be used in this function.
- Curfn.SetOpenCodedDeferDisallowed(true)
+ ir.CurFunc.SetOpenCodedDeferDisallowed(true)
}
fallthrough
case ir.OGO:
@@ -288,7 +289,7 @@ func walkstmt(n ir.Node) ir.Node {
init := n.Cond.Init()
n.Cond.PtrInit().Set(nil)
n.Cond = walkexpr(n.Cond, &init)
- n.Cond = initExpr(init, n.Cond)
+ n.Cond = ir.InitExpr(init, n.Cond)
}
n.Post = walkstmt(n.Post)
@@ -307,23 +308,23 @@ func walkstmt(n ir.Node) ir.Node {
case ir.ORETURN:
n := n.(*ir.ReturnStmt)
- Curfn.NumReturns++
+ ir.CurFunc.NumReturns++
if len(n.Results) == 0 {
return n
}
- if (hasNamedResults(Curfn) && len(n.Results) > 1) || paramoutheap(Curfn) {
+ if (ir.HasNamedResults(ir.CurFunc) && len(n.Results) > 1) || paramoutheap(ir.CurFunc) {
// assign to the function out parameters,
// so that ascompatee can fix up conflicts
var rl []ir.Node
- for _, ln := range Curfn.Dcl {
+ for _, ln := range ir.CurFunc.Dcl {
cl := ln.Class_
if cl == ir.PAUTO || cl == ir.PAUTOHEAP {
break
}
if cl == ir.PPARAMOUT {
var ln ir.Node = ln
- if isParamStackCopy(ln) {
+ if ir.IsParamStackCopy(ln) {
ln = walkexpr(typecheck(ir.NewStarExpr(base.Pos, ln.Name().Heapaddr), ctxExpr), nil)
}
rl = append(rl, ln)
@@ -345,12 +346,12 @@ func walkstmt(n ir.Node) ir.Node {
walkexprlist(n.Results, n.PtrInit())
// For each return parameter (lhs), assign the corresponding result (rhs).
- lhs := Curfn.Type().Results()
+ lhs := ir.CurFunc.Type().Results()
rhs := n.Results
res := make([]ir.Node, lhs.NumFields())
for i, nl := range lhs.FieldSlice() {
nname := ir.AsNode(nl.Nname)
- if isParamHeapCopy(nname) {
+ if ir.IsParamHeapCopy(nname) {
nname = nname.Name().Stackcopy
}
a := ir.NewAssignStmt(base.Pos, nname, rhs[i])
@@ -485,7 +486,7 @@ func walkexpr(n ir.Node, init *ir.Nodes) ir.Node {
init.Append(n.PtrInit().Take()...)
}
- lno := setlineno(n)
+ lno := ir.SetPos(n)
if base.Flag.LowerW > 1 {
ir.Dump("before walk expr", n)
@@ -643,7 +644,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
var ll ir.Nodes
n.Y = walkexpr(n.Y, &ll)
- n.Y = initExpr(ll, n.Y)
+ n.Y = ir.InitExpr(ll, n.Y)
return n
case ir.OPRINT, ir.OPRINTN:
@@ -655,7 +656,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.ORECOVER:
n := n.(*ir.CallExpr)
- return mkcall("gorecover", n.Type(), init, nodAddr(nodfp))
+ return mkcall("gorecover", n.Type(), init, nodAddr(ir.RegFP))
case ir.OCLOSUREREAD, ir.OCFUNC:
return n
@@ -710,7 +711,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if left.Op() == ir.OINDEXMAP && right.Op() == ir.OAPPEND {
left := left.(*ir.IndexExpr)
mapAppend = right.(*ir.CallExpr)
- if !samesafeexpr(left, mapAppend.Args[0]) {
+ if !ir.SameSafeExpr(left, mapAppend.Args[0]) {
base.Fatalf("not same expressions: %v != %v", left, mapAppend.Args[0])
}
}
@@ -738,7 +739,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
return as
}
- if !base.Flag.Cfg.Instrumenting && isZero(as.Y) {
+ if !base.Flag.Cfg.Instrumenting && ir.IsZero(as.Y) {
return as
}
@@ -794,7 +795,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
init.Append(n.PtrInit().Take()...)
walkexprlistsafe(n.Lhs, init)
walkexprlistsafe(n.Rhs, init)
- return liststmt(ascompatee(ir.OAS, n.Lhs, n.Rhs, init))
+ return ir.NewBlockStmt(src.NoXPos, ascompatee(ir.OAS, n.Lhs, n.Rhs, init))
// a,b,... = fn()
case ir.OAS2FUNC:
@@ -805,14 +806,14 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
walkexprlistsafe(n.Lhs, init)
r = walkexpr(r, init)
- if IsIntrinsicCall(r.(*ir.CallExpr)) {
+ if ir.IsIntrinsicCall(r.(*ir.CallExpr)) {
n.Rhs = []ir.Node{r}
return n
}
init.Append(r)
ll := ascompatet(n.Lhs, r.Type())
- return liststmt(ll)
+ return ir.NewBlockStmt(src.NoXPos, ll)
// x, y = <-c
// order.stmt made sure x is addressable or blank.
@@ -926,8 +927,8 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
fromType := n.X.Type()
toType := n.Type()
- if !fromType.IsInterface() && !ir.IsBlank(Curfn.Nname) { // skip unnamed functions (func _())
- markTypeUsedInInterface(fromType, Curfn.LSym)
+ if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) { // skip unnamed functions (func _())
+ markTypeUsedInInterface(fromType, ir.CurFunc.LSym)
}
// typeword generates the type word of the interface value.
@@ -971,9 +972,9 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// and staticuint64s[n.Left * 8 + 7] on big-endian.
n.X = cheapexpr(n.X, init)
// byteindex widens n.Left so that the multiplication doesn't overflow.
- index := ir.NewBinaryExpr(base.Pos, ir.OLSH, byteindex(n.X), nodintconst(3))
+ index := ir.NewBinaryExpr(base.Pos, ir.OLSH, byteindex(n.X), ir.NewInt(3))
if thearch.LinkArch.ByteOrder == binary.BigEndian {
- index = ir.NewBinaryExpr(base.Pos, ir.OADD, index, nodintconst(7))
+ index = ir.NewBinaryExpr(base.Pos, ir.OADD, index, ir.NewInt(7))
}
xe := ir.NewIndexExpr(base.Pos, ir.Names.Staticuint64s, index)
xe.SetBounded(true)
@@ -981,7 +982,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
case n.X.Op() == ir.ONAME && n.X.(*ir.Name).Class_ == ir.PEXTERN && n.X.(*ir.Name).Readonly():
// n.Left is a readonly global; use it directly.
value = n.X
- case !fromType.IsInterface() && n.Esc() == EscNone && fromType.Width <= 1024:
+ case !fromType.IsInterface() && n.Esc() == ir.EscNone && fromType.Width <= 1024:
// n.Left does not escape. Use a stack temporary initialized to n.Left.
value = temp(fromType)
init.Append(typecheck(ir.NewAssignStmt(base.Pos, value, n.X), ctxStmt))
@@ -1058,7 +1059,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// with a non-interface, especially in a switch on interface value
// with non-interface cases, is not visible to order.stmt, so we
// have to fall back on allocating a temp here.
- if !islvalue(v) {
+ if !ir.IsAssignable(v) {
v = copyexpr(v, v.Type(), init)
}
v = nodAddr(v)
@@ -1078,7 +1079,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if n.Op() == ir.OCONVNOP && n.Type() == n.X.Type() {
return n.X
}
- if n.Op() == ir.OCONVNOP && checkPtr(Curfn, 1) {
+ if n.Op() == ir.OCONVNOP && ir.ShouldCheckPtr(ir.CurFunc, 1) {
if n.Type().IsPtr() && n.X.Type().IsUnsafePtr() { // unsafe.Pointer to *T
return walkCheckPtrAlignment(n, init, nil)
}
@@ -1177,7 +1178,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) {
base.Warn("index bounds check elided")
}
- if smallintconst(n.Index) && !n.Bounded() {
+ if ir.IsSmallIntConst(n.Index) && !n.Bounded() {
base.Errorf("index out of bounds")
}
} else if ir.IsConst(n.X, constant.String) {
@@ -1185,13 +1186,13 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) {
base.Warn("index bounds check elided")
}
- if smallintconst(n.Index) && !n.Bounded() {
+ if ir.IsSmallIntConst(n.Index) && !n.Bounded() {
base.Errorf("index out of bounds")
}
}
if ir.IsConst(n.Index, constant.Int) {
- if v := n.Index.Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[types.TINT]) {
+ if v := n.Index.Val(); constant.Sign(v) < 0 || ir.ConstOverflow(v, types.Types[types.TINT]) {
base.Errorf("index out of bounds")
}
}
@@ -1252,7 +1253,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
n := n.(*ir.SliceExpr)
- checkSlice := checkPtr(Curfn, 1) && n.Op() == ir.OSLICE3ARR && n.X.Op() == ir.OCONVNOP && n.X.(*ir.ConvExpr).X.Type().IsUnsafePtr()
+ checkSlice := ir.ShouldCheckPtr(ir.CurFunc, 1) && n.Op() == ir.OSLICE3ARR && n.X.Op() == ir.OCONVNOP && n.X.(*ir.ConvExpr).X.Type().IsUnsafePtr()
if checkSlice {
conv := n.X.(*ir.ConvExpr)
conv.X = walkexpr(conv.X, init)
@@ -1262,7 +1263,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
low, high, max := n.SliceBounds()
low = walkexpr(low, init)
- if low != nil && isZero(low) {
+ if low != nil && ir.IsZero(low) {
// Reduce x[0:j] to x[:j] and x[0:j:k] to x[:j:k].
low = nil
}
@@ -1274,7 +1275,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
}
if n.Op().IsSlice3() {
- if max != nil && max.Op() == ir.OCAP && samesafeexpr(n.X, max.(*ir.UnaryExpr).X) {
+ if max != nil && max.Op() == ir.OCAP && ir.SameSafeExpr(n.X, max.(*ir.UnaryExpr).X) {
// Reduce x[i:j:cap(x)] to x[i:j].
if n.Op() == ir.OSLICE3 {
n.SetOp(ir.OSLICE)
@@ -1292,8 +1293,8 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if n.Type().Elem().NotInHeap() {
base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type().Elem())
}
- if n.Esc() == EscNone {
- if n.Type().Elem().Width >= maxImplicitStackVarSize {
+ if n.Esc() == ir.EscNone {
+ if n.Type().Elem().Width >= ir.MaxImplicitStackVarSize {
base.Fatalf("large ONEW with EscNone: %v", n)
}
r := temp(n.Type().Elem())
@@ -1346,7 +1347,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// var h *hmap
var h ir.Node
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
// Allocate hmap on stack.
// var hv hmap
@@ -1372,7 +1373,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// h.buckets = b
// }
- nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, hint, nodintconst(BUCKETSIZE)), nil, nil)
+ nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, hint, ir.NewInt(BUCKETSIZE)), nil, nil)
nif.Likely = true
// var bv bmap
@@ -1398,7 +1399,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// For hint <= BUCKETSIZE overLoadFactor(hint, 0) is false
// and no buckets will be allocated by makemap. Therefore,
// no buckets need to be allocated in this code path.
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
// Only need to initialize h.hash0 since
// hmap h has been allocated on the stack already.
// h.hash0 = fastrand()
@@ -1414,7 +1415,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
return mkcall1(fn, n.Type(), init)
}
- if n.Esc() != EscNone {
+ if n.Esc() != ir.EscNone {
h = nodnil()
}
// Map initialization with a variable or large hint is
@@ -1452,7 +1453,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if t.Elem().NotInHeap() {
base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
}
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
if why := heapAllocReason(n); why != "" {
base.Fatalf("%v has EscNone, but %v", n, why)
}
@@ -1470,8 +1471,8 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// if len < 0 { panicmakeslicelen() }
// panicmakeslicecap()
// }
- nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGT, conv(l, types.Types[types.TUINT64]), nodintconst(i)), nil, nil)
- niflen := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLT, l, nodintconst(0)), nil, nil)
+ nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGT, conv(l, types.Types[types.TUINT64]), ir.NewInt(i)), nil, nil)
+ niflen := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLT, l, ir.NewInt(0)), nil, nil)
niflen.Body = []ir.Node{mkcall("panicmakeslicelen", nil, init)}
nif.Body.Append(niflen, mkcall("panicmakeslicecap", nil, init))
init.Append(typecheck(nif, ctxStmt))
@@ -1514,7 +1515,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.OMAKESLICECOPY:
n := n.(*ir.MakeExpr)
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
base.Fatalf("OMAKESLICECOPY with EscNone: %v", n)
}
@@ -1534,12 +1535,12 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// We do not check for overflow of len(to)*elem.Width here
// since len(from) is an existing checked slice capacity
// with same elem.Width for the from slice.
- size := ir.NewBinaryExpr(base.Pos, ir.OMUL, conv(length, types.Types[types.TUINTPTR]), conv(nodintconst(t.Elem().Width), types.Types[types.TUINTPTR]))
+ size := ir.NewBinaryExpr(base.Pos, ir.OMUL, conv(length, types.Types[types.TUINTPTR]), conv(ir.NewInt(t.Elem().Width), types.Types[types.TUINTPTR]))
// instantiate mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
fn := syslook("mallocgc")
sh := ir.NewSliceHeaderExpr(base.Pos, nil, nil, nil, nil)
- sh.Ptr = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, nodnil(), nodbool(false))
+ sh.Ptr = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, nodnil(), ir.NewBool(false))
sh.Ptr.MarkNonNil()
sh.LenCap = []ir.Node{length, length}
sh.SetType(t)
@@ -1570,7 +1571,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.ORUNESTR:
n := n.(*ir.ConvExpr)
a := nodnil()
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
t := types.NewArray(types.Types[types.TUINT8], 4)
a = nodAddr(temp(t))
}
@@ -1580,7 +1581,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.OBYTES2STR, ir.ORUNES2STR:
n := n.(*ir.ConvExpr)
a := nodnil()
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
// Create temporary buffer for string on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
a = nodAddr(temp(t))
@@ -1616,7 +1617,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
// Allocate a [n]byte of the right size.
t := types.NewArray(types.Types[types.TUINT8], int64(len(sc)))
var a ir.Node
- if n.Esc() == EscNone && len(sc) <= int(maxImplicitStackVarSize) {
+ if n.Esc() == ir.EscNone && len(sc) <= int(ir.MaxImplicitStackVarSize) {
a = nodAddr(temp(t))
} else {
a = callnew(t)
@@ -1638,7 +1639,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
}
a := nodnil()
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
// Create temporary buffer for slice on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
a = nodAddr(temp(t))
@@ -1661,7 +1662,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.OSTR2RUNES:
n := n.(*ir.ConvExpr)
a := nodnil()
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
// Create temporary buffer for slice on stack.
t := types.NewArray(types.Types[types.TINT32], tmpstringbufsize)
a = nodAddr(temp(t))
@@ -1719,7 +1720,7 @@ func markUsedIfaceMethod(n *ir.CallExpr) {
dot := n.X.(*ir.SelectorExpr)
ityp := dot.X.Type()
tsym := typenamesym(ityp).Linksym()
- r := obj.Addrel(Curfn.LSym)
+ r := obj.Addrel(ir.CurFunc.LSym)
r.Sym = tsym
// dot.Xoffset is the method index * Widthptr (the offset of code pointer
// in itab).
@@ -1777,7 +1778,7 @@ func rtconvfn(src, dst *types.Type) (param, result types.Kind) {
// TODO(josharian): combine this with its caller and simplify
func reduceSlice(n *ir.SliceExpr) ir.Node {
low, high, max := n.SliceBounds()
- if high != nil && high.Op() == ir.OLEN && samesafeexpr(n.X, high.(*ir.UnaryExpr).X) {
+ if high != nil && high.Op() == ir.OLEN && ir.SameSafeExpr(n.X, high.(*ir.UnaryExpr).X) {
// Reduce x[i:len(x)] to x[i:].
high = nil
}
@@ -1824,7 +1825,7 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node {
break
}
// Do not generate 'x = x' during return. See issue 4014.
- if op == ir.ORETURN && samesafeexpr(nl[i], nr[i]) {
+ if op == ir.ORETURN && ir.SameSafeExpr(nl[i], nr[i]) {
continue
}
nn = append(nn, ascompatee1(nl[i], nr[i], init))
@@ -1835,7 +1836,7 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node {
var nln, nrn ir.Nodes
nln.Set(nl)
nrn.Set(nr)
- base.Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), ir.FuncName(Curfn))
+ base.Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), ir.FuncName(ir.CurFunc))
}
return reorder3(nn)
}
@@ -2000,11 +2001,11 @@ func walkprint(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
t := make([]ir.Node, 0, len(s)*2)
for i, n := range s {
if i != 0 {
- t = append(t, nodstr(" "))
+ t = append(t, ir.NewString(" "))
}
t = append(t, n)
}
- t = append(t, nodstr("\n"))
+ t = append(t, ir.NewString("\n"))
nn.Args.Set(t)
}
@@ -2018,7 +2019,7 @@ func walkprint(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
i++
}
if len(strs) > 0 {
- t = append(t, nodstr(strings.Join(strs, "")))
+ t = append(t, ir.NewString(strings.Join(strs, "")))
}
if i < len(s) {
t = append(t, s[i])
@@ -2140,31 +2141,6 @@ func callnew(t *types.Type) ir.Node {
return n
}
-// isReflectHeaderDataField reports whether l is an expression p.Data
-// where p has type reflect.SliceHeader or reflect.StringHeader.
-func isReflectHeaderDataField(l ir.Node) bool {
- if l.Type() != types.Types[types.TUINTPTR] {
- return false
- }
-
- var tsym *types.Sym
- switch l.Op() {
- case ir.ODOT:
- l := l.(*ir.SelectorExpr)
- tsym = l.X.Type().Sym()
- case ir.ODOTPTR:
- l := l.(*ir.SelectorExpr)
- tsym = l.X.Type().Elem().Sym()
- default:
- return false
- }
-
- if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
- return false
- }
- return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
-}
-
func convas(n *ir.AssignStmt, init *ir.Nodes) *ir.AssignStmt {
if n.Op() != ir.OAS {
base.Fatalf("convas: not OAS %v", n.Op())
@@ -2288,37 +2264,6 @@ func reorder3save(n ir.Node, all []*ir.AssignStmt, i int, early *[]ir.Node) ir.N
return q
}
-// what's the outer value that a write to n affects?
-// outer value means containing struct or array.
-func outervalue(n ir.Node) ir.Node {
- for {
- switch nn := n; nn.Op() {
- case ir.OXDOT:
- base.Fatalf("OXDOT in walk")
- case ir.ODOT:
- nn := nn.(*ir.SelectorExpr)
- n = nn.X
- continue
- case ir.OPAREN:
- nn := nn.(*ir.ParenExpr)
- n = nn.X
- continue
- case ir.OCONVNOP:
- nn := nn.(*ir.ConvExpr)
- n = nn.X
- continue
- case ir.OINDEX:
- nn := nn.(*ir.IndexExpr)
- if nn.X.Type() != nil && nn.X.Type().IsArray() {
- n = nn.X
- continue
- }
- }
-
- return n
- }
-}
-
// Is it possible that the computation of r might be
// affected by assignments in all?
func aliased(r ir.Node, all []*ir.AssignStmt) bool {
@@ -2344,7 +2289,7 @@ func aliased(r ir.Node, all []*ir.AssignStmt) bool {
continue
}
- lv := outervalue(as.X)
+ lv := ir.OuterValue(as.X)
if lv.Op() != ir.ONAME {
memwrite = true
continue
@@ -2526,7 +2471,7 @@ func paramstoheap(params *types.Type) []ir.Node {
// even allocations to move params/results to the heap.
// The generated code is added to Curfn's Enter list.
func zeroResults() {
- for _, f := range Curfn.Type().Results().Fields().Slice() {
+ for _, f := range ir.CurFunc.Type().Results().Fields().Slice() {
v := ir.AsNode(f.Nname)
if v != nil && v.Name().Heapaddr != nil {
// The local which points to the return value is the
@@ -2534,7 +2479,7 @@ func zeroResults() {
// by a Needzero annotation in plive.go:livenessepilogue.
continue
}
- if isParamHeapCopy(v) {
+ if ir.IsParamHeapCopy(v) {
// TODO(josharian/khr): Investigate whether we can switch to "continue" here,
// and document more in either case.
// In the review of CL 114797, Keith wrote (roughly):
@@ -2544,7 +2489,7 @@ func zeroResults() {
v = v.Name().Stackcopy
}
// Zero the stack location containing f.
- Curfn.Enter.Append(ir.NewAssignStmt(Curfn.Pos(), v, nil))
+ ir.CurFunc.Enter.Append(ir.NewAssignStmt(ir.CurFunc.Pos(), v, nil))
}
}
@@ -2570,13 +2515,13 @@ func returnsfromheap(params *types.Type) []ir.Node {
// Enter and Exit lists.
func heapmoves() {
lno := base.Pos
- base.Pos = Curfn.Pos()
- nn := paramstoheap(Curfn.Type().Recvs())
- nn = append(nn, paramstoheap(Curfn.Type().Params())...)
- nn = append(nn, paramstoheap(Curfn.Type().Results())...)
- Curfn.Enter.Append(nn...)
- base.Pos = Curfn.Endlineno
- Curfn.Exit.Append(returnsfromheap(Curfn.Type().Results())...)
+ base.Pos = ir.CurFunc.Pos()
+ nn := paramstoheap(ir.CurFunc.Type().Recvs())
+ nn = append(nn, paramstoheap(ir.CurFunc.Type().Params())...)
+ nn = append(nn, paramstoheap(ir.CurFunc.Type().Results())...)
+ ir.CurFunc.Enter.Append(nn...)
+ base.Pos = ir.CurFunc.Endlineno
+ ir.CurFunc.Exit.Append(returnsfromheap(ir.CurFunc.Type().Results())...)
base.Pos = lno
}
@@ -2743,7 +2688,7 @@ func addstr(n *ir.AddStringExpr, init *ir.Nodes) ir.Node {
}
buf := nodnil()
- if n.Esc() == EscNone {
+ if n.Esc() == ir.EscNone {
sz := int64(0)
for _, n1 := range n.List {
if n1.Op() == ir.OLITERAL {
@@ -2779,7 +2724,7 @@ func addstr(n *ir.AddStringExpr, init *ir.Nodes) ir.Node {
slice := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(t), args[1:])
slice.Prealloc = n.Prealloc
args = []ir.Node{buf, slice}
- slice.SetEsc(EscNone)
+ slice.SetEsc(ir.EscNone)
}
cat := syslook(fn)
@@ -2865,7 +2810,7 @@ func appendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
slice.SetType(s.Type())
slice.SetSliceBounds(ir.NewUnaryExpr(base.Pos, ir.OLEN, l1), nil, nil)
- Curfn.SetWBPos(n.Pos())
+ ir.CurFunc.SetWBPos(n.Pos())
// instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
fn := syslook("typedslicecopy")
@@ -2886,7 +2831,7 @@ func appendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
fn := syslook("slicecopy")
fn = substArgTypes(fn, ptr1.Type().Elem(), ptr2.Type().Elem())
- ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width))
+ ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, ir.NewInt(elemtype.Width))
} else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
ix := ir.NewIndexExpr(base.Pos, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1))
@@ -2896,7 +2841,7 @@ func appendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
sptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, l2)
nwid := cheapexpr(conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, l2), types.Types[types.TUINTPTR]), &nodes)
- nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, nodintconst(elemtype.Width))
+ nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(elemtype.Width))
// instantiate func memmove(to *any, frm *any, length uintptr)
fn := syslook("memmove")
@@ -2992,7 +2937,7 @@ func extendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
var nodes []ir.Node
// if l2 >= 0 (likely happens), do nothing
- nifneg := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGE, l2, nodintconst(0)), nil, nil)
+ nifneg := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGE, l2, ir.NewInt(0)), nil, nil)
nifneg.Likely = true
// else panicmakeslicelen()
@@ -3044,13 +2989,13 @@ func extendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
hp := convnop(nodAddr(ix), types.Types[types.TUNSAFEPTR])
// hn := l2 * sizeof(elem(s))
- hn := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, l2, nodintconst(elemtype.Width)), types.Types[types.TUINTPTR])
+ hn := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, l2, ir.NewInt(elemtype.Width)), types.Types[types.TUINTPTR])
clrname := "memclrNoHeapPointers"
hasPointers := elemtype.HasPointers()
if hasPointers {
clrname = "memclrHasPointers"
- Curfn.SetWBPos(n.Pos())
+ ir.CurFunc.SetWBPos(n.Pos())
}
var clr ir.Nodes
@@ -3094,7 +3039,7 @@ func extendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
// }
// s
func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node {
- if !samesafeexpr(dst, n.Args[0]) {
+ if !ir.SameSafeExpr(dst, n.Args[0]) {
n.Args[0] = safeexpr(n.Args[0], init)
n.Args[0] = walkexpr(n.Args[0], init)
}
@@ -3134,7 +3079,7 @@ func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node {
ns := temp(nsrc.Type())
l = append(l, ir.NewAssignStmt(base.Pos, ns, nsrc)) // s = src
- na := nodintconst(int64(argc)) // const argc
+ na := ir.NewInt(int64(argc)) // const argc
nif := ir.NewIfStmt(base.Pos, nil, nil, nil) // if cap(s) - len(s) < argc
nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OCAP, ns), ir.NewUnaryExpr(base.Pos, ir.OLEN, ns)), na)
@@ -3160,7 +3105,7 @@ func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node {
ix.SetBounded(true)
l = append(l, ir.NewAssignStmt(base.Pos, ix, n)) // s[n] = arg
if i+1 < len(ls) {
- l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, nodintconst(1)))) // n = n + 1
+ l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, ir.NewInt(1)))) // n = n + 1
}
}
@@ -3183,7 +3128,7 @@ func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node {
//
func copyany(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
if n.X.Type().Elem().HasPointers() {
- Curfn.SetWBPos(n.Pos())
+ ir.CurFunc.SetWBPos(n.Pos())
fn := writebarrierfn("typedslicecopy", n.X.Type().Elem(), n.Y.Type().Elem())
n.X = cheapexpr(n.X, init)
ptrL, lenL := backingArrayPtrLen(n.X)
@@ -3205,7 +3150,7 @@ func copyany(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
fn := syslook("slicecopy")
fn = substArgTypes(fn, ptrL.Type().Elem(), ptrR.Type().Elem())
- return mkcall1(fn, n.Type(), init, ptrL, lenL, ptrR, lenR, nodintconst(n.X.Type().Elem().Width))
+ return mkcall1(fn, n.Type(), init, ptrL, lenL, ptrR, lenR, ir.NewInt(n.X.Type().Elem().Width))
}
n.X = walkexpr(n.X, init)
@@ -3241,7 +3186,7 @@ func copyany(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
nwid := ir.Node(temp(types.Types[types.TUINTPTR]))
setwid := ir.NewAssignStmt(base.Pos, nwid, conv(nlen, types.Types[types.TUINTPTR]))
ne.Body.Append(setwid)
- nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, nodintconst(nl.Type().Elem().Width))
+ nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(nl.Type().Elem().Width))
call := mkcall1(fn, nil, init, nto, nfrm, nwid)
ne.Body.Append(call)
@@ -3264,12 +3209,12 @@ func eqfor(t *types.Type) (n ir.Node, needsize bool) {
case types.ASPECIAL:
sym := typesymprefix(".eq", t)
n := NewName(sym)
- setNodeNameFunc(n)
+ ir.MarkFunc(n)
n.SetType(functype(nil, []*ir.Field{
- anonfield(types.NewPtr(t)),
- anonfield(types.NewPtr(t)),
+ ir.NewField(base.Pos, nil, nil, types.NewPtr(t)),
+ ir.NewField(base.Pos, nil, nil, types.NewPtr(t)),
}, []*ir.Field{
- anonfield(types.Types[types.TBOOL]),
+ ir.NewField(base.Pos, nil, nil, types.Types[types.TBOOL]),
}))
return n, false
}
@@ -3415,7 +3360,7 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
// Chose not to inline. Call equality function directly.
if !inline {
// eq algs take pointers; cmpl and cmpr must be addressable
- if !islvalue(cmpl) || !islvalue(cmpr) {
+ if !ir.IsAssignable(cmpl) || !ir.IsAssignable(cmpr) {
base.Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
}
@@ -3424,7 +3369,7 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
call.Args.Append(nodAddr(cmpl))
call.Args.Append(nodAddr(cmpr))
if needsize {
- call.Args.Append(nodintconst(t.Width))
+ call.Args.Append(ir.NewInt(t.Width))
}
res := ir.Node(call)
if n.Op() != ir.OEQ {
@@ -3483,31 +3428,31 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
}
if step == 1 {
compare(
- ir.NewIndexExpr(base.Pos, cmpl, nodintconst(i)),
- ir.NewIndexExpr(base.Pos, cmpr, nodintconst(i)),
+ ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i)),
+ ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i)),
)
i++
remains -= t.Elem().Width
} else {
elemType := t.Elem().ToUnsigned()
- cmplw := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, nodintconst(i)))
+ cmplw := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i)))
cmplw = conv(cmplw, elemType) // convert to unsigned
cmplw = conv(cmplw, convType) // widen
- cmprw := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, nodintconst(i)))
+ cmprw := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i)))
cmprw = conv(cmprw, elemType)
cmprw = conv(cmprw, convType)
// For code like this: uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ...
// ssa will generate a single large load.
for offset := int64(1); offset < step; offset++ {
- lb := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, nodintconst(i+offset)))
+ lb := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i+offset)))
lb = conv(lb, elemType)
lb = conv(lb, convType)
- lb = ir.NewBinaryExpr(base.Pos, ir.OLSH, lb, nodintconst(8*t.Elem().Width*offset))
+ lb = ir.NewBinaryExpr(base.Pos, ir.OLSH, lb, ir.NewInt(8*t.Elem().Width*offset))
cmplw = ir.NewBinaryExpr(base.Pos, ir.OOR, cmplw, lb)
- rb := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, nodintconst(i+offset)))
+ rb := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i+offset)))
rb = conv(rb, elemType)
rb = conv(rb, convType)
- rb = ir.NewBinaryExpr(base.Pos, ir.OLSH, rb, nodintconst(8*t.Elem().Width*offset))
+ rb = ir.NewBinaryExpr(base.Pos, ir.OLSH, rb, ir.NewInt(8*t.Elem().Width*offset))
cmprw = ir.NewBinaryExpr(base.Pos, ir.OOR, cmprw, rb)
}
compare(cmplw, cmprw)
@@ -3517,7 +3462,7 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
}
}
if expr == nil {
- expr = nodbool(n.Op() == ir.OEQ)
+ expr = ir.NewBool(n.Op() == ir.OEQ)
// We still need to use cmpl and cmpr, in case they contain
// an expression which might panic. See issue 23837.
t := temp(cmpl.Type())
@@ -3604,12 +3549,12 @@ func walkcompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
if len(s) > 0 {
ncs = safeexpr(ncs, init)
}
- r := ir.Node(ir.NewBinaryExpr(base.Pos, cmp, ir.NewUnaryExpr(base.Pos, ir.OLEN, ncs), nodintconst(int64(len(s)))))
+ r := ir.Node(ir.NewBinaryExpr(base.Pos, cmp, ir.NewUnaryExpr(base.Pos, ir.OLEN, ncs), ir.NewInt(int64(len(s)))))
remains := len(s)
for i := 0; remains > 0; {
if remains == 1 || !canCombineLoads {
- cb := nodintconst(int64(s[i]))
- ncb := ir.NewIndexExpr(base.Pos, ncs, nodintconst(int64(i)))
+ cb := ir.NewInt(int64(s[i]))
+ ncb := ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i)))
r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, ncb, cb))
remains--
i++
@@ -3628,18 +3573,18 @@ func walkcompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
convType = types.Types[types.TUINT16]
step = 2
}
- ncsubstr := conv(ir.NewIndexExpr(base.Pos, ncs, nodintconst(int64(i))), convType)
+ ncsubstr := conv(ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i))), convType)
csubstr := int64(s[i])
// Calculate large constant from bytes as sequence of shifts and ors.
// Like this: uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ...
// ssa will combine this into a single large load.
for offset := 1; offset < step; offset++ {
- b := conv(ir.NewIndexExpr(base.Pos, ncs, nodintconst(int64(i+offset))), convType)
- b = ir.NewBinaryExpr(base.Pos, ir.OLSH, b, nodintconst(int64(8*offset)))
+ b := conv(ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i+offset))), convType)
+ b = ir.NewBinaryExpr(base.Pos, ir.OLSH, b, ir.NewInt(int64(8*offset)))
ncsubstr = ir.NewBinaryExpr(base.Pos, ir.OOR, ncsubstr, b)
csubstr |= int64(s[i+offset]) << uint8(8*offset)
}
- csubstrPart := nodintconst(csubstr)
+ csubstrPart := ir.NewInt(csubstr)
// Compare "step" bytes as once
r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, csubstrPart, ncsubstr))
remains -= step
@@ -3668,7 +3613,7 @@ func walkcompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
} else {
// sys_cmpstring(s1, s2) :: 0
r = mkcall("cmpstring", types.Types[types.TINT], init, conv(n.X, types.Types[types.TSTRING]), conv(n.Y, types.Types[types.TSTRING]))
- r = ir.NewBinaryExpr(base.Pos, n.Op(), r, nodintconst(0))
+ r = ir.NewBinaryExpr(base.Pos, n.Op(), r, ir.NewInt(0))
}
return finishcompare(n, r, init)
@@ -3692,7 +3637,7 @@ func bounded(n ir.Node, max int64) bool {
sign := n.Type().IsSigned()
bits := int32(8 * n.Type().Width)
- if smallintconst(n) {
+ if ir.IsSmallIntConst(n) {
v := ir.Int64Val(n)
return 0 <= v && v < max
}
@@ -3702,9 +3647,9 @@ func bounded(n ir.Node, max int64) bool {
n := n.(*ir.BinaryExpr)
v := int64(-1)
switch {
- case smallintconst(n.X):
+ case ir.IsSmallIntConst(n.X):
v = ir.Int64Val(n.X)
- case smallintconst(n.Y):
+ case ir.IsSmallIntConst(n.Y):
v = ir.Int64Val(n.Y)
if n.Op() == ir.OANDNOT {
v = ^v
@@ -3719,7 +3664,7 @@ func bounded(n ir.Node, max int64) bool {
case ir.OMOD:
n := n.(*ir.BinaryExpr)
- if !sign && smallintconst(n.Y) {
+ if !sign && ir.IsSmallIntConst(n.Y) {
v := ir.Int64Val(n.Y)
if 0 <= v && v <= max {
return true
@@ -3728,7 +3673,7 @@ func bounded(n ir.Node, max int64) bool {
case ir.ODIV:
n := n.(*ir.BinaryExpr)
- if !sign && smallintconst(n.Y) {
+ if !sign && ir.IsSmallIntConst(n.Y) {
v := ir.Int64Val(n.Y)
for bits > 0 && v >= 2 {
bits--
@@ -3738,7 +3683,7 @@ func bounded(n ir.Node, max int64) bool {
case ir.ORSH:
n := n.(*ir.BinaryExpr)
- if !sign && smallintconst(n.Y) {
+ if !sign && ir.IsSmallIntConst(n.Y) {
v := ir.Int64Val(n.Y)
if v > int64(bits) {
return true
@@ -3794,9 +3739,9 @@ func usemethod(n *ir.CallExpr) {
// (including global variables such as numImports - was issue #19028).
// Also need to check for reflect package itself (see Issue #38515).
if s := res0.Type.Sym(); s != nil && s.Name == "Method" && types.IsReflectPkg(s.Pkg) {
- Curfn.SetReflectMethod(true)
+ ir.CurFunc.SetReflectMethod(true)
// The LSym is initialized at this point. We need to set the attribute on the LSym.
- Curfn.LSym.Set(obj.AttrReflectMethod, true)
+ ir.CurFunc.LSym.Set(obj.AttrReflectMethod, true)
}
}
@@ -3845,10 +3790,10 @@ func usefield(n *ir.SelectorExpr) {
}
sym := tracksym(outer, field)
- if Curfn.FieldTrack == nil {
- Curfn.FieldTrack = make(map[*types.Sym]struct{})
+ if ir.CurFunc.FieldTrack == nil {
+ ir.CurFunc.FieldTrack = make(map[*types.Sym]struct{})
}
- Curfn.FieldTrack[sym] = struct{}{}
+ ir.CurFunc.FieldTrack[sym] = struct{}{}
}
// anySideEffects reports whether n contains any operations that could have observable side effects.
@@ -3987,7 +3932,7 @@ func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
arg = arg.(*ir.ConvExpr).X
n.Args[i] = arg
}
- funcArgs = append(funcArgs, symfield(s, arg.Type()))
+ funcArgs = append(funcArgs, ir.NewField(base.Pos, s, nil, arg.Type()))
}
t := ir.NewFuncType(base.Pos, nil, funcArgs, nil)
@@ -3995,7 +3940,7 @@ func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
sym := lookupN("wrap·", wrapCall_prgen)
fn := dclfunc(sym, t)
- args := paramNnames(t.Type())
+ args := ir.ParamNames(t.Type())
for i, origArg := range origArgs {
if origArg == nil {
continue
@@ -4076,7 +4021,7 @@ func walkCheckPtrAlignment(n *ir.ConvExpr, init *ir.Nodes, count ir.Node) ir.Nod
}
if count == nil {
- count = nodintconst(1)
+ count = ir.NewInt(1)
}
n.X = cheapexpr(n.X, init)
@@ -4107,7 +4052,7 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
return n
}
- if n.X.Op() == ir.ODOTPTR && isReflectHeaderDataField(n.X) {
+ if n.X.Op() == ir.ODOTPTR && ir.IsReflectHeaderDataField(n.X) {
return n
}
@@ -4141,7 +4086,7 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
cheap := cheapexpr(n, init)
slice := mkdotargslice(types.NewSlice(types.Types[types.TUNSAFEPTR]), originals)
- slice.SetEsc(EscNone)
+ slice.SetEsc(ir.EscNone)
init.Append(mkcall("checkptrArithmetic", nil, init, convnop(cheap, types.Types[types.TUNSAFEPTR]), slice))
// TODO(khr): Mark backing store of slice as dead. This will allow us to reuse
@@ -4150,13 +4095,6 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
return cheap
}
-// checkPtr reports whether pointer checking should be enabled for
-// function fn at a given level. See debugHelpFooter for defined
-// levels.
-func checkPtr(fn *ir.Func, level int) bool {
- return base.Debug.Checkptr >= level && fn.Pragma&ir.NoCheckPtr == 0
-}
-
// appendWalkStmt typechecks and walks stmt and then appends it to init.
func appendWalkStmt(init *ir.Nodes, stmt ir.Node) {
op := stmt.Op()
diff --git a/src/cmd/compile/internal/ir/cfg.go b/src/cmd/compile/internal/ir/cfg.go
new file mode 100644
index 0000000000..d986ac3a1e
--- /dev/null
+++ b/src/cmd/compile/internal/ir/cfg.go
@@ -0,0 +1,26 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+var (
+ // maximum size variable which we will allocate on the stack.
+ // This limit is for explicit variable declarations like "var x T" or "x := ...".
+ // Note: the flag smallframes can update this value.
+ MaxStackVarSize = int64(10 * 1024 * 1024)
+
+ // maximum size of implicit variables that we will allocate on the stack.
+ // p := new(T) allocating T on the stack
+ // p := &T{} allocating T on the stack
+ // s := make([]T, n) allocating [n]T on the stack
+ // s := []byte("...") allocating [n]byte on the stack
+ // Note: the flag smallframes can update this value.
+ MaxImplicitStackVarSize = int64(64 * 1024)
+
+ // MaxSmallArraySize is the maximum size of an array which is considered small.
+ // Small arrays will be initialized directly with a sequence of constant stores.
+ // Large arrays will be initialized by copying from a static temp.
+ // 256 bytes was chosen to minimize generated code + statictmp size.
+ MaxSmallArraySize = int64(256)
+)
diff --git a/src/cmd/compile/internal/ir/const.go b/src/cmd/compile/internal/ir/const.go
new file mode 100644
index 0000000000..bfa0136232
--- /dev/null
+++ b/src/cmd/compile/internal/ir/const.go
@@ -0,0 +1,99 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+ "go/constant"
+ "math"
+ "math/big"
+
+ "cmd/compile/internal/base"
+ "cmd/compile/internal/types"
+)
+
+func NewBool(b bool) Node {
+ return NewLiteral(constant.MakeBool(b))
+}
+
+func NewInt(v int64) Node {
+ return NewLiteral(constant.MakeInt64(v))
+}
+
+func NewString(s string) Node {
+ return NewLiteral(constant.MakeString(s))
+}
+
+const (
+ // Maximum size in bits for big.Ints before signalling
+ // overflow and also mantissa precision for big.Floats.
+ ConstPrec = 512
+)
+
+func BigFloat(v constant.Value) *big.Float {
+ f := new(big.Float)
+ f.SetPrec(ConstPrec)
+ switch u := constant.Val(v).(type) {
+ case int64:
+ f.SetInt64(u)
+ case *big.Int:
+ f.SetInt(u)
+ case *big.Float:
+ f.Set(u)
+ case *big.Rat:
+ f.SetRat(u)
+ default:
+ base.Fatalf("unexpected: %v", u)
+ }
+ return f
+}
+
+// ConstOverflow reports whether constant value v is too large
+// to represent with type t.
+func ConstOverflow(v constant.Value, t *types.Type) bool {
+ switch {
+ case t.IsInteger():
+ bits := uint(8 * t.Size())
+ if t.IsUnsigned() {
+ x, ok := constant.Uint64Val(v)
+ return !ok || x>>bits != 0
+ }
+ x, ok := constant.Int64Val(v)
+ if x < 0 {
+ x = ^x
+ }
+ return !ok || x>>(bits-1) != 0
+ case t.IsFloat():
+ switch t.Size() {
+ case 4:
+ f, _ := constant.Float32Val(v)
+ return math.IsInf(float64(f), 0)
+ case 8:
+ f, _ := constant.Float64Val(v)
+ return math.IsInf(f, 0)
+ }
+ case t.IsComplex():
+ ft := types.FloatForComplex(t)
+ return ConstOverflow(constant.Real(v), ft) || ConstOverflow(constant.Imag(v), ft)
+ }
+ base.Fatalf("doesoverflow: %v, %v", v, t)
+ panic("unreachable")
+}
+
+// IsConstNode reports whether n is a Go language constant (as opposed to a
+// compile-time constant).
+//
+// Expressions derived from nil, like string([]byte(nil)), while they
+// may be known at compile time, are not Go language constants.
+func IsConstNode(n Node) bool {
+ return n.Op() == OLITERAL
+}
+
+func IsSmallIntConst(n Node) bool {
+ if n.Op() == OLITERAL {
+ v, ok := constant.Int64Val(n.Val())
+ return ok && int64(int32(v)) == v
+ }
+ return false
+}
diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go
index 39a408fdc7..640cc03954 100644
--- a/src/cmd/compile/internal/ir/expr.go
+++ b/src/cmd/compile/internal/ir/expr.go
@@ -5,10 +5,13 @@
package ir
import (
+ "bytes"
"cmd/compile/internal/base"
"cmd/compile/internal/types"
"cmd/internal/src"
+ "fmt"
"go/constant"
+ "go/token"
)
func maybeDo(x Node, err error, do func(Node) error) error {
@@ -783,3 +786,371 @@ func (n *UnaryExpr) SetOp(op Op) {
n.op = op
}
}
+
+func IsZero(n Node) bool {
+ switch n.Op() {
+ case ONIL:
+ return true
+
+ case OLITERAL:
+ switch u := n.Val(); u.Kind() {
+ case constant.String:
+ return constant.StringVal(u) == ""
+ case constant.Bool:
+ return !constant.BoolVal(u)
+ default:
+ return constant.Sign(u) == 0
+ }
+
+ case OARRAYLIT:
+ n := n.(*CompLitExpr)
+ for _, n1 := range n.List {
+ if n1.Op() == OKEY {
+ n1 = n1.(*KeyExpr).Value
+ }
+ if !IsZero(n1) {
+ return false
+ }
+ }
+ return true
+
+ case OSTRUCTLIT:
+ n := n.(*CompLitExpr)
+ for _, n1 := range n.List {
+ n1 := n1.(*StructKeyExpr)
+ if !IsZero(n1.Value) {
+ return false
+ }
+ }
+ return true
+ }
+
+ return false
+}
+
+// lvalue etc
+func IsAssignable(n Node) bool {
+ switch n.Op() {
+ case OINDEX:
+ n := n.(*IndexExpr)
+ if n.X.Type() != nil && n.X.Type().IsArray() {
+ return IsAssignable(n.X)
+ }
+ if n.X.Type() != nil && n.X.Type().IsString() {
+ return false
+ }
+ fallthrough
+ case ODEREF, ODOTPTR, OCLOSUREREAD:
+ return true
+
+ case ODOT:
+ n := n.(*SelectorExpr)
+ return IsAssignable(n.X)
+
+ case ONAME:
+ n := n.(*Name)
+ if n.Class_ == PFUNC {
+ return false
+ }
+ return true
+
+ case ONAMEOFFSET:
+ return true
+ }
+
+ return false
+}
+
+func StaticValue(n Node) Node {
+ for {
+ if n.Op() == OCONVNOP {
+ n = n.(*ConvExpr).X
+ continue
+ }
+
+ n1 := staticValue1(n)
+ if n1 == nil {
+ return n
+ }
+ n = n1
+ }
+}
+
+// staticValue1 implements a simple SSA-like optimization. If n is a local variable
+// that is initialized and never reassigned, staticValue1 returns the initializer
+// expression. Otherwise, it returns nil.
+func staticValue1(nn Node) Node {
+ if nn.Op() != ONAME {
+ return nil
+ }
+ n := nn.(*Name)
+ if n.Class_ != PAUTO || n.Name().Addrtaken() {
+ return nil
+ }
+
+ defn := n.Name().Defn
+ if defn == nil {
+ return nil
+ }
+
+ var rhs Node
+FindRHS:
+ switch defn.Op() {
+ case OAS:
+ defn := defn.(*AssignStmt)
+ rhs = defn.Y
+ case OAS2:
+ defn := defn.(*AssignListStmt)
+ for i, lhs := range defn.Lhs {
+ if lhs == n {
+ rhs = defn.Rhs[i]
+ break FindRHS
+ }
+ }
+ base.Fatalf("%v missing from LHS of %v", n, defn)
+ default:
+ return nil
+ }
+ if rhs == nil {
+ base.Fatalf("RHS is nil: %v", defn)
+ }
+
+ if reassigned(n) {
+ return nil
+ }
+
+ return rhs
+}
+
+// reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean
+// indicating whether the name has any assignments other than its declaration.
+// The second return value is the first such assignment encountered in the walk, if any. It is mostly
+// useful for -m output documenting the reason for inhibited optimizations.
+// NB: global variables are always considered to be re-assigned.
+// TODO: handle initial declaration not including an assignment and followed by a single assignment?
+func reassigned(name *Name) bool {
+ if name.Op() != ONAME {
+ base.Fatalf("reassigned %v", name)
+ }
+ // no way to reliably check for no-reassignment of globals, assume it can be
+ if name.Curfn == nil {
+ return true
+ }
+ return Any(name.Curfn, func(n Node) bool {
+ switch n.Op() {
+ case OAS:
+ n := n.(*AssignStmt)
+ if n.X == name && n != name.Defn {
+ return true
+ }
+ case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
+ n := n.(*AssignListStmt)
+ for _, p := range n.Lhs {
+ if p == name && n != name.Defn {
+ return true
+ }
+ }
+ }
+ return false
+ })
+}
+
+// IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
+var IsIntrinsicCall = func(*CallExpr) bool { return false }
+
+// SameSafeExpr checks whether it is safe to reuse one of l and r
+// instead of computing both. SameSafeExpr assumes that l and r are
+// used in the same statement or expression. In order for it to be
+// safe to reuse l or r, they must:
+// * be the same expression
+// * not have side-effects (no function calls, no channel ops);
+// however, panics are ok
+// * not cause inappropriate aliasing; e.g. two string to []byte
+// conversions, must result in two distinct slices
+//
+// The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
+// as an lvalue (map assignment) and an rvalue (map access). This is
+// currently OK, since the only place SameSafeExpr gets used on an
+// lvalue expression is for OSLICE and OAPPEND optimizations, and it
+// is correct in those settings.
+func SameSafeExpr(l Node, r Node) bool {
+ if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
+ return false
+ }
+
+ switch l.Op() {
+ case ONAME, OCLOSUREREAD:
+ return l == r
+
+ case ODOT, ODOTPTR:
+ l := l.(*SelectorExpr)
+ r := r.(*SelectorExpr)
+ return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
+
+ case ODEREF:
+ l := l.(*StarExpr)
+ r := r.(*StarExpr)
+ return SameSafeExpr(l.X, r.X)
+
+ case ONOT, OBITNOT, OPLUS, ONEG:
+ l := l.(*UnaryExpr)
+ r := r.(*UnaryExpr)
+ return SameSafeExpr(l.X, r.X)
+
+ case OCONVNOP:
+ l := l.(*ConvExpr)
+ r := r.(*ConvExpr)
+ return SameSafeExpr(l.X, r.X)
+
+ case OCONV:
+ l := l.(*ConvExpr)
+ r := r.(*ConvExpr)
+ // Some conversions can't be reused, such as []byte(str).
+ // Allow only numeric-ish types. This is a bit conservative.
+ return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
+
+ case OINDEX, OINDEXMAP:
+ l := l.(*IndexExpr)
+ r := r.(*IndexExpr)
+ return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
+
+ case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
+ l := l.(*BinaryExpr)
+ r := r.(*BinaryExpr)
+ return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
+
+ case OLITERAL:
+ return constant.Compare(l.Val(), token.EQL, r.Val())
+
+ case ONIL:
+ return true
+ }
+
+ return false
+}
+
+// ShouldCheckPtr reports whether pointer checking should be enabled for
+// function fn at a given level. See debugHelpFooter for defined
+// levels.
+func ShouldCheckPtr(fn *Func, level int) bool {
+ return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
+}
+
+// IsReflectHeaderDataField reports whether l is an expression p.Data
+// where p has type reflect.SliceHeader or reflect.StringHeader.
+func IsReflectHeaderDataField(l Node) bool {
+ if l.Type() != types.Types[types.TUINTPTR] {
+ return false
+ }
+
+ var tsym *types.Sym
+ switch l.Op() {
+ case ODOT:
+ l := l.(*SelectorExpr)
+ tsym = l.X.Type().Sym()
+ case ODOTPTR:
+ l := l.(*SelectorExpr)
+ tsym = l.X.Type().Elem().Sym()
+ default:
+ return false
+ }
+
+ if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
+ return false
+ }
+ return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
+}
+
+func ParamNames(ft *types.Type) []Node {
+ args := make([]Node, ft.NumParams())
+ for i, f := range ft.Params().FieldSlice() {
+ args[i] = AsNode(f.Nname)
+ }
+ return args
+}
+
+// MethodSym returns the method symbol representing a method name
+// associated with a specific receiver type.
+//
+// Method symbols can be used to distinguish the same method appearing
+// in different method sets. For example, T.M and (*T).M have distinct
+// method symbols.
+//
+// The returned symbol will be marked as a function.
+func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
+ sym := MethodSymSuffix(recv, msym, "")
+ sym.SetFunc(true)
+ return sym
+}
+
+// MethodSymSuffix is like methodsym, but allows attaching a
+// distinguisher suffix. To avoid collisions, the suffix must not
+// start with a letter, number, or period.
+func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
+ if msym.IsBlank() {
+ base.Fatalf("blank method name")
+ }
+
+ rsym := recv.Sym()
+ if recv.IsPtr() {
+ if rsym != nil {
+ base.Fatalf("declared pointer receiver type: %v", recv)
+ }
+ rsym = recv.Elem().Sym()
+ }
+
+ // Find the package the receiver type appeared in. For
+ // anonymous receiver types (i.e., anonymous structs with
+ // embedded fields), use the "go" pseudo-package instead.
+ rpkg := Pkgs.Go
+ if rsym != nil {
+ rpkg = rsym.Pkg
+ }
+
+ var b bytes.Buffer
+ if recv.IsPtr() {
+ // The parentheses aren't really necessary, but
+ // they're pretty traditional at this point.
+ fmt.Fprintf(&b, "(%-S)", recv)
+ } else {
+ fmt.Fprintf(&b, "%-S", recv)
+ }
+
+ // A particular receiver type may have multiple non-exported
+ // methods with the same name. To disambiguate them, include a
+ // package qualifier for names that came from a different
+ // package than the receiver type.
+ if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
+ b.WriteString(".")
+ b.WriteString(msym.Pkg.Prefix)
+ }
+
+ b.WriteString(".")
+ b.WriteString(msym.Name)
+ b.WriteString(suffix)
+
+ return rpkg.LookupBytes(b.Bytes())
+}
+
+// MethodName returns the ONAME representing the method
+// referenced by expression n, which must be a method selector,
+// method expression, or method value.
+func MethodExprName(n Node) *Name {
+ name, _ := MethodExprFunc(n).Nname.(*Name)
+ return name
+}
+
+// MethodFunc is like MethodName, but returns the types.Field instead.
+func MethodExprFunc(n Node) *types.Field {
+ switch n.Op() {
+ case ODOTMETH:
+ return n.(*SelectorExpr).Selection
+ case OMETHEXPR:
+ return n.(*MethodExpr).Method
+ case OCALLPART:
+ n := n.(*CallPartExpr)
+ return n.Method
+ }
+ base.Fatalf("unexpected node: %v (%v)", n, n.Op())
+ panic("unreachable")
+}
diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go
index 57837e9e6b..a93516d716 100644
--- a/src/cmd/compile/internal/ir/func.go
+++ b/src/cmd/compile/internal/ir/func.go
@@ -261,3 +261,30 @@ func PkgFuncName(n Node) string {
}
return p + "." + s.Name
}
+
+var CurFunc *Func
+
+func FuncSymName(s *types.Sym) string {
+ return s.Name + "·f"
+}
+
+// NewFuncNameAt generates a new name node for a function or method.
+func NewFuncNameAt(pos src.XPos, s *types.Sym, fn *Func) *Name {
+ if fn.Nname != nil {
+ base.Fatalf("newFuncName - already have name")
+ }
+ n := NewNameAt(pos, s)
+ n.SetFunc(fn)
+ fn.Nname = n
+ return n
+}
+
+// MarkFunc marks a node as a function.
+func MarkFunc(n *Name) {
+ if n.Op() != ONAME || n.Class_ != Pxxx {
+ base.Fatalf("expected ONAME/Pxxx node, got %v", n)
+ }
+
+ n.Class_ = PFUNC
+ n.Sym().SetFunc(true)
+}
diff --git a/src/cmd/compile/internal/ir/name.go b/src/cmd/compile/internal/ir/name.go
index 770f8119e0..93535f4cee 100644
--- a/src/cmd/compile/internal/ir/name.go
+++ b/src/cmd/compile/internal/ir/name.go
@@ -413,3 +413,25 @@ func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName {
p.pos = pos
return p
}
+
+// IsParamStackCopy reports whether this is the on-stack copy of a
+// function parameter that moved to the heap.
+func IsParamStackCopy(n Node) bool {
+ if n.Op() != ONAME {
+ return false
+ }
+ name := n.(*Name)
+ return (name.Class_ == PPARAM || name.Class_ == PPARAMOUT) && name.Heapaddr != nil
+}
+
+// IsParamHeapCopy reports whether this is the on-heap copy of
+// a function parameter that moved to the heap.
+func IsParamHeapCopy(n Node) bool {
+ if n.Op() != ONAME {
+ return false
+ }
+ name := n.(*Name)
+ return name.Class_ == PAUTOHEAP && name.Name().Stackcopy != nil
+}
+
+var RegFP *Name
diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go
index 34b89752ad..b4a557f290 100644
--- a/src/cmd/compile/internal/ir/node.go
+++ b/src/cmd/compile/internal/ir/node.go
@@ -504,3 +504,99 @@ func IsBlank(n Node) bool {
func IsMethod(n Node) bool {
return n.Type().Recv() != nil
}
+
+func HasNamedResults(fn *Func) bool {
+ typ := fn.Type()
+ return typ.NumResults() > 0 && types.OrigSym(typ.Results().Field(0).Sym) != nil
+}
+
+// HasUniquePos reports whether n has a unique position that can be
+// used for reporting error messages.
+//
+// It's primarily used to distinguish references to named objects,
+// whose Pos will point back to their declaration position rather than
+// their usage position.
+func HasUniquePos(n Node) bool {
+ switch n.Op() {
+ case ONAME, OPACK:
+ return false
+ case OLITERAL, ONIL, OTYPE:
+ if n.Sym() != nil {
+ return false
+ }
+ }
+
+ if !n.Pos().IsKnown() {
+ if base.Flag.K != 0 {
+ base.Warn("setlineno: unknown position (line 0)")
+ }
+ return false
+ }
+
+ return true
+}
+
+func SetPos(n Node) src.XPos {
+ lno := base.Pos
+ if n != nil && HasUniquePos(n) {
+ base.Pos = n.Pos()
+ }
+ return lno
+}
+
+// The result of InitExpr MUST be assigned back to n, e.g.
+// n.Left = InitExpr(init, n.Left)
+func InitExpr(init []Node, n Node) Node {
+ if len(init) == 0 {
+ return n
+ }
+ if MayBeShared(n) {
+ // Introduce OCONVNOP to hold init list.
+ old := n
+ n = NewConvExpr(base.Pos, OCONVNOP, nil, old)
+ n.SetType(old.Type())
+ n.SetTypecheck(1)
+ }
+
+ n.PtrInit().Prepend(init...)
+ n.SetHasCall(true)
+ return n
+}
+
+// what's the outer value that a write to n affects?
+// outer value means containing struct or array.
+func OuterValue(n Node) Node {
+ for {
+ switch nn := n; nn.Op() {
+ case OXDOT:
+ base.Fatalf("OXDOT in walk")
+ case ODOT:
+ nn := nn.(*SelectorExpr)
+ n = nn.X
+ continue
+ case OPAREN:
+ nn := nn.(*ParenExpr)
+ n = nn.X
+ continue
+ case OCONVNOP:
+ nn := nn.(*ConvExpr)
+ n = nn.X
+ continue
+ case OINDEX:
+ nn := nn.(*IndexExpr)
+ if nn.X.Type() != nil && nn.X.Type().IsArray() {
+ n = nn.X
+ continue
+ }
+ }
+
+ return n
+ }
+}
+
+const (
+ EscUnknown = iota
+ EscNone // Does not escape to heap, result, or parameters.
+ EscHeap // Reachable from the heap
+ EscNever // By construction will not escape.
+)
diff --git a/src/cmd/compile/internal/gc/scc.go b/src/cmd/compile/internal/ir/scc.go
index a5a6480958..4f646e22b5 100644
--- a/src/cmd/compile/internal/gc/scc.go
+++ b/src/cmd/compile/internal/ir/scc.go
@@ -2,9 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package gc
-
-import "cmd/compile/internal/ir"
+package ir
// Strongly connected components.
//
@@ -32,13 +30,13 @@ import "cmd/compile/internal/ir"
// when analyzing a set of mutually recursive functions.
type bottomUpVisitor struct {
- analyze func([]*ir.Func, bool)
+ analyze func([]*Func, bool)
visitgen uint32
- nodeID map[*ir.Func]uint32
- stack []*ir.Func
+ nodeID map[*Func]uint32
+ stack []*Func
}
-// visitBottomUp invokes analyze on the ODCLFUNC nodes listed in list.
+// VisitFuncsBottomUp invokes analyze on the ODCLFUNC nodes listed in list.
// It calls analyze with successive groups of functions, working from
// the bottom of the call graph upward. Each time analyze is called with
// a list of functions, every function on that list only calls other functions
@@ -51,13 +49,13 @@ type bottomUpVisitor struct {
// If recursive is false, the list consists of only a single function and its closures.
// If recursive is true, the list may still contain only a single function,
// if that function is itself recursive.
-func visitBottomUp(list []ir.Node, analyze func(list []*ir.Func, recursive bool)) {
+func VisitFuncsBottomUp(list []Node, analyze func(list []*Func, recursive bool)) {
var v bottomUpVisitor
v.analyze = analyze
- v.nodeID = make(map[*ir.Func]uint32)
+ v.nodeID = make(map[*Func]uint32)
for _, n := range list {
- if n.Op() == ir.ODCLFUNC {
- n := n.(*ir.Func)
+ if n.Op() == ODCLFUNC {
+ n := n.(*Func)
if !n.IsHiddenClosure() {
v.visit(n)
}
@@ -65,7 +63,7 @@ func visitBottomUp(list []ir.Node, analyze func(list []*ir.Func, recursive bool)
}
}
-func (v *bottomUpVisitor) visit(n *ir.Func) uint32 {
+func (v *bottomUpVisitor) visit(n *Func) uint32 {
if id := v.nodeID[n]; id > 0 {
// already visited
return id
@@ -78,45 +76,45 @@ func (v *bottomUpVisitor) visit(n *ir.Func) uint32 {
min := v.visitgen
v.stack = append(v.stack, n)
- ir.Visit(n, func(n ir.Node) {
+ Visit(n, func(n Node) {
switch n.Op() {
- case ir.ONAME:
- n := n.(*ir.Name)
- if n.Class_ == ir.PFUNC {
+ case ONAME:
+ n := n.(*Name)
+ if n.Class_ == PFUNC {
if n != nil && n.Name().Defn != nil {
- if m := v.visit(n.Name().Defn.(*ir.Func)); m < min {
+ if m := v.visit(n.Name().Defn.(*Func)); m < min {
min = m
}
}
}
- case ir.OMETHEXPR:
- n := n.(*ir.MethodExpr)
- fn := methodExprName(n)
+ case OMETHEXPR:
+ n := n.(*MethodExpr)
+ fn := MethodExprName(n)
if fn != nil && fn.Defn != nil {
- if m := v.visit(fn.Defn.(*ir.Func)); m < min {
+ if m := v.visit(fn.Defn.(*Func)); m < min {
min = m
}
}
- case ir.ODOTMETH:
- n := n.(*ir.SelectorExpr)
- fn := methodExprName(n)
- if fn != nil && fn.Op() == ir.ONAME && fn.Class_ == ir.PFUNC && fn.Defn != nil {
- if m := v.visit(fn.Defn.(*ir.Func)); m < min {
+ case ODOTMETH:
+ n := n.(*SelectorExpr)
+ fn := MethodExprName(n)
+ if fn != nil && fn.Op() == ONAME && fn.Class_ == PFUNC && fn.Defn != nil {
+ if m := v.visit(fn.Defn.(*Func)); m < min {
min = m
}
}
- case ir.OCALLPART:
- n := n.(*ir.CallPartExpr)
- fn := ir.AsNode(callpartMethod(n).Nname)
- if fn != nil && fn.Op() == ir.ONAME {
- if fn := fn.(*ir.Name); fn.Class_ == ir.PFUNC && fn.Name().Defn != nil {
- if m := v.visit(fn.Name().Defn.(*ir.Func)); m < min {
+ case OCALLPART:
+ n := n.(*CallPartExpr)
+ fn := AsNode(n.Method.Nname)
+ if fn != nil && fn.Op() == ONAME {
+ if fn := fn.(*Name); fn.Class_ == PFUNC && fn.Name().Defn != nil {
+ if m := v.visit(fn.Name().Defn.(*Func)); m < min {
min = m
}
}
}
- case ir.OCLOSURE:
- n := n.(*ir.ClosureExpr)
+ case OCLOSURE:
+ n := n.(*ClosureExpr)
if m := v.visit(n.Func); m < min {
min = m
}